使用鼠标适配器调整 jpopupmenu 的大小
Resize jpopupmenu using Mouse Adapter
我正在使用 Swing bits 库向我的 jtable 列 headers 添加过滤器。该库按预期工作,但右击列上出现的 jpopupmenu 没有 re-size。 (re-sizing 只允许从右下角使用鼠标拖动)屏幕截图如下所示。
我找到了 swing bits 库源代码来尝试解决这个问题,这就是我的发现。
jpopupmenu 调整大小由 MouseMotionListner 和 MouseListener 处理。基本上一个 MouseDragged 方法被连续调用,它应该更新 jpopupmenu 大小,直到鼠标被释放。代码如下所示。
public void mouseDragged(MouseEvent e) {
//System.out.println("test_0");
if ( !isResizing ){
//System.out.println("test_3");
return;}
Point p = toScreen(e);
int dx = p.x - mouseStart.x;
int dy = p.y - mouseStart.y;
Dimension minDim = menu.getMinimumSize();
Dimension newDim = new Dimension(startSize.width + dx, startSize.height + dy);
if ( newDim.width >= minDim.width && newDim.height >= minDim.height) {
menu.setPopupSize(newDim);
//System.out.println("test_1");
}
//System.out.println("test_2");
}
通过一些调试,我意识到问题出在 menu.setPopUpSize(newDim) 方法调用上。
如果没有这段代码,当我尝试 re-size jpopupmenu 时,mouseDragged() 方法会被连续调用。 (因为它应该)使用注释打印语句解决了这个问题。
在包含 menu.setPopUpSize(newDim) 的情况下,mouseDragged() 方法仅被调用一次。由于某些原因,在调用setPopUpSize 方法后,鼠标拖动事件没有再次注册。请注意,该方法不 return。在那个单一的调用中,setPopUpSize() 稍微 re-sizes 具有更新的 newDim 值的弹出菜单。
理想情况下,应该重复调用 mouseDragged() 方法,直到用户释放鼠标拖动操作,re-sizing 弹出菜单不断。
我想出的一个解决方法是公开声明 newDim 值并在 mouseReleased() 方法中调用 setPopUpSize(newDim) 方法。这将从鼠标拖动中获取最终坐标并将其用于 re-size 弹出菜单。但这并没有为用户显示边缘的拖动,非常不方便。
非常感谢任何帮助。
不使用 setPopUpSize(newDim) 方法执行:
test_0
test_1
test_2
test_0
test_1
test_2 ...
重复此模式,直到松开鼠标拖动。
使用 setPopUpSize(newDim) 方法执行:
test_0
test_1
test_2
mouseDragged() 方法只被调用一次。
此行为的发生取决于 JPopupMenu 使用的布局,有一种方法可以设置父级 window 的大小并对其进行验证,以便再次重新计算布局,如下所示:
public class ResizePopup {
private final static JPopupMenu menu = new JPopupMenu();
public static void main(final String[] args) {
final JButton small = new JButton("Small");
small.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resize(100, 100);
}
});
final JButton big = new JButton("Big");
big.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resize(400, 400);
}
});
menu.add(small);
menu.add(big);
menu.show(null, 50, 50);
}
private static void resize(final int width, final int height) {
final Window window = (Window) menu.getTopLevelAncestor();
window.pack();
window.setSize(width, height);
window.validate();
}
}
嗯!原来问题出在 java 版本上。我是 运行 java 1.8.0_25 (x64) ,更新到最新的 (1.8.0_66) 并且问题消失了。图书馆工作正常。可以在此处找到有关此问题的更多信息。
我正在使用 Swing bits 库向我的 jtable 列 headers 添加过滤器。该库按预期工作,但右击列上出现的 jpopupmenu 没有 re-size。 (re-sizing 只允许从右下角使用鼠标拖动)屏幕截图如下所示。
我找到了 swing bits 库源代码来尝试解决这个问题,这就是我的发现。
jpopupmenu 调整大小由 MouseMotionListner 和 MouseListener 处理。基本上一个 MouseDragged 方法被连续调用,它应该更新 jpopupmenu 大小,直到鼠标被释放。代码如下所示。
public void mouseDragged(MouseEvent e) {
//System.out.println("test_0");
if ( !isResizing ){
//System.out.println("test_3");
return;}
Point p = toScreen(e);
int dx = p.x - mouseStart.x;
int dy = p.y - mouseStart.y;
Dimension minDim = menu.getMinimumSize();
Dimension newDim = new Dimension(startSize.width + dx, startSize.height + dy);
if ( newDim.width >= minDim.width && newDim.height >= minDim.height) {
menu.setPopupSize(newDim);
//System.out.println("test_1");
}
//System.out.println("test_2");
}
通过一些调试,我意识到问题出在 menu.setPopUpSize(newDim) 方法调用上。
如果没有这段代码,当我尝试 re-size jpopupmenu 时,mouseDragged() 方法会被连续调用。 (因为它应该)使用注释打印语句解决了这个问题。
在包含 menu.setPopUpSize(newDim) 的情况下,mouseDragged() 方法仅被调用一次。由于某些原因,在调用setPopUpSize 方法后,鼠标拖动事件没有再次注册。请注意,该方法不 return。在那个单一的调用中,setPopUpSize() 稍微 re-sizes 具有更新的 newDim 值的弹出菜单。 理想情况下,应该重复调用 mouseDragged() 方法,直到用户释放鼠标拖动操作,re-sizing 弹出菜单不断。
我想出的一个解决方法是公开声明 newDim 值并在 mouseReleased() 方法中调用 setPopUpSize(newDim) 方法。这将从鼠标拖动中获取最终坐标并将其用于 re-size 弹出菜单。但这并没有为用户显示边缘的拖动,非常不方便。
非常感谢任何帮助。
不使用 setPopUpSize(newDim) 方法执行:
test_0
test_1
test_2
test_0
test_1
test_2 ...
重复此模式,直到松开鼠标拖动。
使用 setPopUpSize(newDim) 方法执行:
test_0
test_1
test_2
mouseDragged() 方法只被调用一次。
此行为的发生取决于 JPopupMenu 使用的布局,有一种方法可以设置父级 window 的大小并对其进行验证,以便再次重新计算布局,如下所示:
public class ResizePopup {
private final static JPopupMenu menu = new JPopupMenu();
public static void main(final String[] args) {
final JButton small = new JButton("Small");
small.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resize(100, 100);
}
});
final JButton big = new JButton("Big");
big.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resize(400, 400);
}
});
menu.add(small);
menu.add(big);
menu.show(null, 50, 50);
}
private static void resize(final int width, final int height) {
final Window window = (Window) menu.getTopLevelAncestor();
window.pack();
window.setSize(width, height);
window.validate();
}
}
嗯!原来问题出在 java 版本上。我是 运行 java 1.8.0_25 (x64) ,更新到最新的 (1.8.0_66) 并且问题消失了。图书馆工作正常。可以在此处找到有关此问题的更多信息。