当用户拖动鼠标时,收听JFrame resize事件?

Cli*_*ton 30 java mouse user-interface swing

当用户单击JFrame的一角以调整大小并拖动鼠标时,JFrame将根据用户拖动时鼠标的当前位置重新绘制.你怎么能听这些事件?

以下是我目前尝试的内容:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }

    // These methods do not appear to be called at all when a JFrame
    // is being resized.
    @Override
    public void setSize(int width, int height) {
        System.out.println("setSize");
    }

    @Override
    public void setBounds(Rectangle r) {
        System.out.println("setBounds A");
    }

    @Override
    public void setBounds(int x, int y, int width, int height) {
        System.out.println("setBounds B");
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在用鼠标左右拖动时确定和约束用户调整窗口大小的方式(基于窗口的当前宽高比)?

Ale*_*lex 40

您可以添加组件侦听器并实现componentResized函数,如下所示:

JFrame component = new JFrame("My Frame");

component.addComponentListener(new ComponentAdapter() 
{  
        public void componentResized(ComponentEvent evt) {
            Component c = (Component)evt.getSource();
            //........
        }
});
Run Code Online (Sandbox Code Playgroud)

编辑:显然,对于JFrame,componentResized事件被挂钩到mouseReleased事件.这就是释放鼠标按钮时调用该方法的原因.

实现您想要的一种方法是添加一个覆盖JFrame整个区域的JPanel.然后将componentListener添加到JPanel(即使在鼠标仍在拖动时也会调用componentResized for JPanel).调整框架大小后,面板也会调整大小.

我知道,这不是最优雅的解决方案,但它确实有效!


Tom*_*ine 7

您可能需要覆盖类似的东西validate(不要忘记调用超级).当然,如果您使用窗口系统配置拖动轮廓,那么仍然可能无法正常工作.

  • 哎呀,找到了.super.validate(),当然. (3认同)

vau*_*oid 7

另一种解决方法(与Alex非常相似,但更直接)是从JFrame根窗格中收听事件:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.getRootPane().addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

根据其他实现细节,可能会更改根窗格.如果这是一种可能性,那么你可以覆盖setRootPane()并处理它.由于setRootPane()受到保护并且仅从构造函数调用,因此您不太可能需要这样做.

  • @AnnonomusPenguin,不,这是一个构造函数声明,构造函数不指定返回类型,如`void`. (2认同)