Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用鼠标适配器调整JPOppMenu的大小_Java_Swing_Listener_Mouse_Mousemotionlistener - Fatal编程技术网

Java 使用鼠标适配器调整JPOppMenu的大小

Java 使用鼠标适配器调整JPOppMenu的大小,java,swing,listener,mouse,mousemotionlistener,Java,Swing,Listener,Mouse,Mousemotionlistener,我正在使用库向我的jtable列标题添加过滤器。该库按预期工作,但右键单击列上显示的jpopupmenu不会重新调整大小。(仅允许使用鼠标拖动从右下角重新调整大小)屏幕截图如下所示 public void mouseDragged(MouseEvent e) { //System.out.println("test_0"); if ( !isResizing ){ //System.out.println("test_3"); return;}

我正在使用库向我的jtable列标题添加过滤器。该库按预期工作,但右键单击列上显示的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");
}

我获得了swing bits库源代码,试图解决这个问题,这就是我发现的

JPOppMenu的大小调整由MouseMotionListner和MouseStener处理。基本上,会连续调用MouseDragged方法,在释放鼠标之前,该方法将更新jpopmpmenu大小。代码如下所示

    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.setpopussize(newDim)方法调用

如果没有这段代码,当我尝试重新调整JPOppMenu的大小时,mouseDragged()方法会不断被调用。(正如它应该做的那样)使用注释的print语句解决了这个问题

在包含menu.setPopusSize(newDim)的情况下,mouseDragged()方法只调用一次。由于某些原因,在调用setPopUpSize方法后,不会再次注册鼠标拖动事件。请注意,该方法不会返回。在这个调用中,setPopUpSize()使用更新的newDim值稍微重新调整popupmenu的大小。 理想情况下,应该重复调用mouseDragged()方法,直到用户释放鼠标拖动动作,从而不断调整弹出菜单的大小

我想到的一个解决方法是公开声明newDim值,并在mousererelease()方法中调用setPopusSize(newDim)方法。这将从鼠标拖动中获取最终坐标,并使用该坐标重新调整弹出菜单的大小。但这并没有为用户显示边缘的拖动,这非常不方便

任何帮助都将不胜感激

不使用setPopusSize(newDim)方法执行:

重复此模式,直到释放鼠标拖动

使用setPopusSize(newDim)方法执行:


mouseDragged()方法只调用一次。

此行为可能发生,具体取决于JPOppMenu使用的布局,有一种方法可以设置父窗口的大小并对其进行验证,以便重新计算布局,如下所示:

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版本上。我运行的是Java1.8.0_25(x64),将其更新为最新版本(1.8.0_66),问题已经消失。这座图书馆运转良好。有关此问题的更多信息,请参见此处


setPopupSize
,这是一种设置组件的
preferredSize
的方法,如果大小改变,它将继续隐藏并重新显示弹出窗口您可以详细说明“它将继续隐藏并重新显示弹出窗口”?调用
setPopupSize
,调用
showPopup
,这将关闭当前弹出窗口(如果可见),并根据弹出窗口的新
preferredSize
重新创建窗口。窗口的实际创建方式取决于许多系统临界值。这可能意味着这样做时,先前注册的
MouseListener
s“可能”被取消注册,并且此重新创建的弹出菜单不会响应上一个菜单的
mouseDragged
侦听器。因此,
mouseDragged
方法在每次单击和拖动时只调用一次?是吗?好的,
MouseListener
s保持不变,但是,因为窗口是可见的,鼠标事件不再发送到它,而是发送到它下面的窗口,整个事件在火焰中爆炸。这是SwingBits的作者必须解决的一个bug。我已经检查了这些值,新的维度在限制范围内。添加的菜单。重新绘制()不起作用。问题是,只有一次调用mouseDragged()方法,该方法将弹出菜单的大小重新调整了一小部分。理想情况下,菜单应该像正常的可重新调整大小的窗口一样,通过鼠标拖动继续重新调整大小。这不起作用。我也得到了类似的答案。
菜单返回的顶级窗口。GetToLevel
是jtable的窗口,调整popupmenu的大小会更改整个表的大小。您不能设置最大列宽吗?
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();
    }
}