web-dev-qa-db-ja.com

ユーザーがマウスをドラッグするときにJFrameサイズ変更イベントをリッスンしますか?

ユーザーが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");
    }
}

ユーザーがマウスの周りをドラッグしているときに、ユーザーがウィンドウの現在の縦横比に基づいてウィンドウのサイズを変更する方法を決定および制約するにはどうすればよいですか?

30
Clinton

おそらくvalidateのようなものをオーバーライドする必要があります(スーパーを呼び出すことを忘れないでください)。もちろん、ウィンドウシステムを使用してアウトラインをドラッグするように構成している場合は、まだ機能しない可能性があります。

コンポーネントリスナーを追加し、次のようなcomponentResized関数を実装できます。

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

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

編集:どうやら、JFrameの場合、componentResizedイベントはmouseReleasedイベントにフックされます。そのため、マウスボタンを放したときにメソッドが呼び出されます。

目的を達成する1つの方法は、JFrameの全領域をカバーするJPanelを追加することです。次に、componentListenerをJPanelに追加します(JPanelのcomponentResizedは、マウスがまだドラッグしている間にも呼び出されます)。フレームのサイズが変更されると、パネルのサイズも変更されます。

これは最もエレガントなソリューションではありませんが、機能します!

40
Alex

別の回避策(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");
            }
        });
    }
}
_

他の実装の詳細によっては、ルートペインが変更される可能性があります。それが可能であれば、setRootPane()をオーバーライドして対処することができます。ただし、setRootPane()は保護されており、コンストラクターからのみ呼び出されるため、これを行う必要はほとんどありません。

6
vaughandroid