34

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

4

5 に答える 5

49

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

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

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());
      }
  });

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

于 2009-08-31T08:48:59.583 に答える
3

私はあなたの問題を抱えていないようです。以下のコードを使用すると、windowDeactivate()が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);
    }
}
于 2009-08-27T21:17:13.873 に答える
1

windowClosingイベントをWindowにディスパッチします。アプリケーションの終了エントリのExitActionの例を確認してください。

于 2009-08-27T20:37:13.283 に答える
0

テストされていない提案:

getWindowListeners()を試し、繰り返して各WindowListenersに対してwindowClosed()を起動しましたか?

編集:上記の提案は間違っています。後世のためにそれを保持します。

簡単な例では、dialog.dispose()を呼び出すと問題なく動作します。

于 2009-08-27T20:28:23.270 に答える
0

windowClosingJDialogに余分な閉じるボタンがあり、Xがクリックされたときに同じWindowListener(を使用して実装したWindowAdapter)を実行したいので、コードからイベントを発生させたいと思いました(ユーザーがXをクリックしたかのように)。ボタンがクリックされたとき。実行すると、が発生するのではなく、発生するdispose()だけです。確認のために、ウィンドウを閉じる前にメッセージを表示したいと思います。また、JDialogは保護されているため、JDialogの方法で発砲することはできませんでした。windowClosedwindowClosingwindowClosingprocessWindowEvent

これが私がそれをどのように機能させたかです:

WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));

それが誰かを助けることを願っています。

于 2013-06-01T18:32:01.863 に答える