Java 来自父类的非终止窗口侦听器
有人能解释为什么在关闭子窗口时下列程序没有终止吗 我创建了一个简单的应用程序,其中包含一个父类Java 来自父类的非终止窗口侦听器,java,swing,jframe,dispose,windowlistener,Java,Swing,Jframe,Dispose,Windowlistener,有人能解释为什么在关闭子窗口时下列程序没有终止吗 我创建了一个简单的应用程序,其中包含一个父类JFrame,它用JDialog实例化了一个子类。当我将父引用传递到子类中,以便可以使用父类创建JDialog(即:newjdialog(parent);)时,从父类添加到它的窗口侦听器会导致程序在子窗口关闭后永不终止。窗口确实关闭了(就可见性而言),但程序本身仍在运行。父对象的默认关闭操作设置为JFrame。在关闭时退出。子项的默认关闭操作设置为JDialog.DISPOSE\u ON\u close
JFrame
,它用JDialog
实例化了一个子类。当我将父引用传递到子类中,以便可以使用父类创建JDialog
(即:newjdialog(parent);
)时,从父类添加到它的窗口侦听器会导致程序在子窗口关闭后永不终止。窗口确实关闭了(就可见性而言),但程序本身仍在运行。父对象的默认关闭操作设置为JFrame。在关闭时退出。子项的默认关闭操作设置为JDialog.DISPOSE\u ON\u close
如果我没有向子类传递父引用,因此在没有父窗口的情况下实例化JDialog
,则当关闭子窗口时,该示例将终止。例如,如果使用以下命令,程序将终止:ChildWindow prompt=newchildwindow(null)代码>
父类:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ParentWindow {
private JFrame frame;
private JPanel contentPane = new JPanel(new BorderLayout(0, 0));
private JButton btnNewButton = new JButton("Open Child Window!");
public ParentWindow() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ChildWindow prompt = new ChildWindow(frame); // or use null for no parent
prompt.getDialog().addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e){
// .. get some information from the child before disposing
System.out.println("Window closed."); // does not terminate when passing frame as parent
frame.dispose();
}
});
}
});
contentPane.add(btnNewButton);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new ParentWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
儿童班:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ChildWindow {
private JDialog dialog;
private JButton okButton = new JButton("Close");
public ChildWindow(Window parent) {
dialog = new JDialog(parent);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(okButton, BorderLayout.CENTER);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.pack();
dialog.setVisible(true);
}
public JDialog getDialog() {
return dialog;
}
}
输出:
Window closed.
Window closed.
Window closed.
... (does not terminate)
使用Windows7和Java8进行测试,没有问题,当我尝试Java7或Java6时,它只是继续打印出关闭的窗口。
因此,我使用对frame.isVisible的测试更新了windowClosed
方法
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ChildWindow prompt = new ChildWindow(frame); // or use null for no parent
prompt.getDialog().addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
// .. get some information from the child before disposing
System.out.println("Window closed."); // does not terminate when passing frame as parent
if (frame.isVisible()) {
frame.dispose();
}
}
});
}
});
让它工作…现在看看我是否能找到原因
我“认为”发生的事情是
ok按钮
被触发,调用对话框。dispose
dialog.dispose
正在设置第一个windowClosed
事件
WindowListener
已收到windowClosed
事件的通知,该事件正在处理帧
框架试图关闭其子窗口,这导致对话框再次通知WindowListener他们正在关闭,以此类推…转到3并重复
这是一个bug,在Java 8中似乎已修复…因为关闭事件被推送到事件队列中,所以不会得到StackOverflowException
在这种情况下,另一个选项是从触发windowClosed
事件的窗口中删除WindowListener
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ChildWindow prompt = new ChildWindow(frame); // or use null for no parent
prompt.getDialog().addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
e.getWindow().removeWindowListener(this);
frame.dispose();
}
});
}
});
对我来说很好…@MadProgrammer你试过关闭子窗口吗?是的,打开了3,关闭了第一个…等了一两秒钟,JVM终止了…@MadProgrammer当我运行它时,当父窗口关闭时,程序肯定会终止,但如果我关闭任何子窗口,它就会卡住,不会终止(使用子窗口的关闭按钮或JButton
close按钮).What OS,What Java version?在这里也可以使用,除了在我的环境中使用JDK1.7u60时,它会打印两次。使用JDK1.8u5时,它会按预期工作,并且只打印一次。有趣的发现,谢谢。由于它是一个创建的无模式对话框,有没有更好的方法(从其他类外部)获取信息当对话框关闭时,问题是最后一个转折点(JVM)@CanadianDavid将是