web-dev-qa-db-ja.com

JDialogを閉じて、ウィンドウイベントリスナーに通知するにはどうすればよいですか?

Windowイベントリスナーが引き続き通知されるように、コードを通じてJDialogを閉じる方法はありますか? visibleをfalseに設定して破棄しようとしましたが、どちらも実行しないようです。

33
Jeff Storey

ウィンドウを閉じる(dispose())と非表示(setVisible(false))は異なる操作であり、異なるイベントを生成します。そして、オペレーティングシステムからウィンドウを閉じることは、まだ別のイベント。

3つすべてがwindowDeactivatedを生成してウィンドウのフォーカスが失われたことを通知しますが、dispose()windowClosedを生成し、OSから閉じるとfirstwindowClosingを生成します。これらの両方を同じ方法で処理する場合は、閉じたときにウィンドウが破棄されるように設定できます。

_window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
_

一般に、setVisible(false)は、ウィンドウを再度使用することを意味するため、ウィンドウイベントは(windowDeactivatedを除いて)ポストされません。ウィンドウの非表示を検出する場合は、ComponentListenerを使用する必要があります。

_window.addComponentListener(new ComponentAdapter() {
  @Override
  public void componentHidden(ComponentEvent e) {
    System.out.println("componentHidden()");
  }
})
_

ただし、これは明示的なsetVisible()呼び出しでのみ機能することに注意してください。より一般的に非表示を検出する必要がある場合は、HierarchyListenerを使用できますが、おそらくそれは価値があるよりも厄介です。

_  window.addHierarchyListener(new HierarchyListener() {
    @Override
      public void hierarchyChanged(HierarchyEvent e) {
        System.out.println("valid: " + window.isValid());
        System.out.println("showing: " + window.isShowing());
      }
  });
_

ウィンドウを破棄すると、最初に非表示にしてから無効化するために、いくつかのHierarchyEventsを取得しますが、setVisible()で非表示にしても有効であることに注意してください。無効化を取得します。

48
David Moles

私はあなたの問題を抱えていないようです。以下のコードを使用すると、- windowDeactivated()setVisible(false) または dispose() および windowClosed()のいずれかに対して呼び出されます は、dispose()に対しても呼び出されます。

ClosingDialog.Java:

public class ClosingDialog extends JDialog {
    public ClosingDialog(Frame owner, String title, boolean modal) {
        super(owner, title, modal);
        JPanel contentPanel = (JPanel) this.getContentPane();

        JButton setVisButton = new JButton("setVisible( false )");
        setVisButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.setVisible(false);
            }
        });

        JButton disposeButton = new JButton("dispose()");
        disposeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.dispose();
            }
        });

        contentPanel.setLayout(new FlowLayout());

        contentPanel.add(setVisButton);
        contentPanel.add(disposeButton);

        this.addWindowListener(new WindowListener() {
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("windowClosed");
            }

            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }

            public void windowDeactivated(WindowEvent e) {
                System.out.println("windowDeactivated");
            }

            public void windowDeiconified(WindowEvent e) {
                System.out.println("windowDeiconified");
            }

            public void windowIconified(WindowEvent e) {
                System.out.println("windowIconified");
            }

            public void windowOpened(WindowEvent e) {
                System.out.println("windowOpened");
            }
        });

        this.setSize(300, 300);
    }
}
3
Joseph Gordon

WindowClosingイベントをWindowにディスパッチします。 Closing an Application エントリのExitActionの例を確認してください。

1
camickr

未検証の提案:

GetWindowListeners()を試してから、各WindowListenersに対してwindowClosed()を起動するために繰り返し実行しましたか?

編集:上記の提案は間違っています。後世のために保管してください。

単純な例では、dialog.dispose()を呼び出すとうまくいくのではないかと心配しています。

0
Grundlefleck