简体   繁体   English

windowClosed多次触发。 这是错误还是功能?

[英]windowClosed fires more than once. Is this a bug or a feature?

Take the following code: 采取以下代码:

import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class WeirdDialogShitTest implements Runnable {
    private JFrame frame;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new WeirdDialogShitTest());
    }

    @Override
    public void run() {
        frame = new JFrame("Test");
        frame.add(new JButton(new AbstractAction("Show Dialog") {
            @Override
            public void actionPerformed(ActionEvent event) {
                showDialog();
            }
        }));
        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }

    private void showDialog() {
        JDialog dialog = new JDialog(frame, "Dialog", Dialog.ModalityType.DOCUMENT_MODAL);
        dialog.add(new JLabel("Content here"));
        dialog.pack();
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        dialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent event) {
                JOptionPane.showMessageDialog(frame, "windowClosed fired");
            }
        });
        dialog.setVisible(true);
    }
}

I expect windowClosed to be called once - when the dialog closes. 我希望windowClosed被调用一次-对话框关闭时。

What actually happens is that it is called twice - once when the dialog closes, and once when the containing frame closes. 实际发生的情况是它被两次调用-一次在对话框关闭时调用,一次在包含框架关闭时调用。

When I traced it to see what was going on, here's what I found: 当我跟踪它以查看发生了什么时,这是我发现的内容:

  • When dispose() is called on the parent, it disposes all children too. 在父对象上调用dispose() ,它也会同时处置所有子代。 Fair enough. 很公平。
  • All child dialogs remain in the list of children despite no longer existing. 尽管不再存在,所有子对话框仍保留在子列表中。 This seems dodgy to me. 这对我来说似乎很狡猾。 (Are they ever removed?) (他们曾经被移除吗?)
  • dispose() unconditionally fires windowClosed whether the window is already disposed or not. dispose()无条件激发windowClosed不管窗口是否已经被处置。 This seems dodgy to me also. 这对我来说似乎也很狡猾。

The end result is getting windowClosed once for the dialog itself and once for each ancestor. 最终结果是,对话框本身和每个祖先窗口windowClosed :/ :/

But maybe this is the intended behaviour? 但这也许是预期的行为吗?

Should use frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 应该使用frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); on main frame. 在主机上。 This will solve your problem. 这样可以解决您的问题。 Try: 尝试:

public class WeirdDialogShitTest implements Runnable {
    private JFrame frame;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new WeirdDialogShitTest());
    }

    @Override
    public void run() {
        frame = new JFrame("Test");
        frame.add(new JButton(new AbstractAction("Show Dialog") {
            @Override
            public void actionPerformed(ActionEvent event) {
                showDialog();
            }
        }));
        frame.pack();

        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //Use EXIT_ON_CLOSE here.
    }

    private void showDialog() {
        JDialog dialog = new JDialog(frame, "Dialog", Dialog.ModalityType.DOCUMENT_MODAL);
        dialog.add(new JLabel("Content here"));
        dialog.pack();
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        dialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent event) {
                JOptionPane.showMessageDialog(frame, "windowClosed fired");

            }
        });
        dialog.setVisible(true);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Enum *似乎*被多次初始化,构造函数被多次调用。 如果我是对的,那为什么? - Enum *seems* to be initialized more than once, the constructor is called more than once. If I’m right, then why? 这段代码的问题在于输出。 生产者生产不止一次。 为什么以及如何解决? - The problem of this code is in the output. Producer produce more than once. Why and how can I solve it? Java:服务器不会多次通过tcp套接字接收消息。 - Java: Server not receiveing messages over tcp socket more than once. 手动触发的Azure Webjob多次触发。 返回409(冲突)错误 - Manually Triggered Azure Webjob is getting triggered more than once. Returning 409 (conflict) error Java - 多次从ArrayList中删除时出错。 (IllegalStateException异常) - Java - Error when removing from an ArrayList more than once. (IllegalStateException) 多次调用扫描仪时抛出异常。 “线程主异常” java.util.NoSuchElementException:找不到行“ - Exception thrown while calling scanner more than once. “Exception in thread main” java.util.NoSuchElementException: No line found" 调度线程仅一次。 - Schedule Thread only once. 警告不止一次出现 - warning appears more than once 多次迭代一个Collection - Iterating a Collection more than once BroadcastReceiver 不止一次收到 - BroadcastReceiver received more than once
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM