如何关闭JDialog并通知Window事件监听器?

时间:2009-08-27 20:20:14

标签: java swing jdialog

有没有办法通过代码关闭JDialog,以便仍然会通知Window事件监听器?我试过将可见设置为false并处理,但似乎都没有。

5 个答案:

答案 0 :(得分:48)

关闭一个窗口(带有dispose())并将其隐藏(带有setVisible(false))是不同的操作,并产生不同的事件 - 从操作系统关闭它是另一个产生的不同操作一个不同的事件。

所有三个都会产生windowDeactivated告诉你窗口失去焦点,但dispose()将产生windowClosed,而从操作系统关闭将首先产生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,首先是隐藏,然后是失效,但是当你用setVisible()隐藏它时它仍然有效,所以你赢了没有失效。

答案 1 :(得分:3)

我似乎没有你的问题。当我使用下面的代码时,windowDeactivated()setVisible( false )会调用dispose(),而对于dispose()也会调用windowClosed()

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

答案 2 :(得分:1)

将windowClosing事件发送到Window。查看Closing an Application条目中的ExitAction示例。

答案 3 :(得分:0)

未经测试的建议:

您是否尝试过getWindowListeners()然后迭代以向每个WindowListeners触发windowClosed()?

编辑:上述建议是错误的。为后代保留它。

我害怕在我的简单例子中调用dialog.dispose()对我来说很好。

答案 4 :(得分:0)

我想从代码中触发windowClosing事件(就像用户单击X一样),因为我在JDialog中有一个额外的关闭按钮,并且想要使用{实现的相同的WindowListener {1}})在单击X并单击按钮时运行。正在运行WindowAdapter只会触发dispose(),而不是windowClosed,并且我希望在窗口关闭之前显示消息,以进行确认。我也没有设法通过JDialog的方法windowClosing触发windowClosing,因为它受到保护。

以下是我如何使用它:

processWindowEvent

希望能有所帮助。