Is there a way to close a JDialog through code such that the Window event listeners will still be notified? I've tried just setting visible to false and disposing, but neither seem to do it.
有没有办法通过代码关闭JDialog,以便仍然会通知Window事件监听器?我试过将可见设置为false并处理,但似乎都没有。
5 个解决方案
#1
47
Closing a window (with dispose()
) and hiding it (with setVisible(false)
) are different operations, and produce different events -- and closing it from the operating system is yet another different operation that produces yet a different event.
关闭窗口(使用dispose())并隐藏它(使用setVisible(false))是不同的操作,并产生不同的事件 - 从操作系统关闭它是另一个产生不同事件的不同操作。
All three will produce windowDeactivated
to tell you the window's lost focus, but dispose()
will then produce windowClosed
, while closing from the OS will first produce windowClosing
. If you want to handle both of these the same way, you can set the window to be disposed when closed:
所有三个都会产生windowDeactivated以告诉你窗口失去焦点,但dispose()将生成windowClosed,而从OS关闭将首先产生windowClosing。如果要以相同的方式处理这两种方法,可以将窗口设置为在关闭时处理:
window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
In general, setVisible(false)
implies that you might want to use the window again, so it doesn't post any window events (apart from windowDeactivated
). If you want to detect the hiding of a window, you need to use a ComponentListener
;
通常,setVisible(false)意味着您可能希望再次使用该窗口,因此它不会发布任何窗口事件(除了windowDeactivated)。如果要检测窗口的隐藏,则需要使用ComponentListener;
window.addComponentListener(new ComponentAdapter() {
@Override
public void componentHidden(ComponentEvent e) {
System.out.println("componentHidden()");
}
})
Note though that this will pretty much only work for explicit setVisible()
calls. If you need to detect hiding more generally, you can use a HierarchyListener
, but it's probably more trouble than it's worth.
请注意,这几乎只适用于显式setVisible()调用。如果你需要更普遍地检测隐藏,你可以使用HierarchyListener,但它可能比它的价值更麻烦。
window.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
System.out.println("valid: " + window.isValid());
System.out.println("showing: " + window.isShowing());
}
});
Note that when you dispose a window you'll get a couple of HierarchyEvent
s, first for hiding and then for invalidation, but when you hide it with setVisible()
it's still valid, so you won't get the invalidation.
请注意,当你处理一个窗口时,你会得到几个HierarchyEvents,首先是隐藏然后是失效,但是当你用setVisible()隐藏它时它仍然有效,所以你不会得到失效。
#2
3
I don't seem to have your problem. When I use the code below windowDeactivated() is called for either setVisible( false ) or dispose() and windowClosed() is also called for dispose().
我似乎没有你的问题。当我使用下面的代码时,对于setVisible(false)或dispose()调用windowDeactivated(),并且还调用windowClosed()for dispose()。
ClosingDialog.java:
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
1
Dispatch a windowClosing event to the Window. Check out the ExitAction example from the Closing an Application entry.
将windowClosing事件发送到Window。查看Closing an Application条目中的ExitAction示例。
#4
0
Untested suggestion:
未经测试的建议:
Have you tried getWindowListeners() and then iterating around to fire windowClosed() to each of the WindowListeners?
您是否尝试过getWindowListeners()然后迭代以向每个WindowListeners触发windowClosed()?
EDIT: the above suggestion is wrong. Keeping it for posterity.
编辑:上述建议是错误的。为后代保留它。
I'm afraid calling dialog.dispose() works fine for me in my simple example.
在我的简单例子中,我害怕调用dialog.dispose()对我来说很好。
#5
0
I wanted to fire a windowClosing
event from the code (just as if the user clicked the X), because I have an extra close button in the JDialog and want the same WindowListener (that I implemented using a WindowAdapter
) to be run when the X is clicked and when the button is clicked. Running dispose()
only fires windowClosed
, not windowClosing
, and I want a message to appear before the window is closed, for confirmation. I also didn't manage to fire windowClosing
via JDialog's method processWindowEvent
since it is protected.
我想从代码中触发一个windowClosing事件(就像用户单击X一样),因为我在JDialog中有一个额外的关闭按钮,并希望在X时运行相同的WindowListener(我使用WindowAdapter实现)单击并单击按钮时单击。运行dispose()只触发windowClosed,而不是windowClosing,我希望在窗口关闭之前显示一条消息,以便进行确认。我也没有设法通过JDialog的方法processWindowEvent来激活windowClosing,因为它受到保护。
Here is how I got it working though:
以下是我如何使用它:
WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));
Hope that helps someone.
希望能帮助别人。
#1
47
Closing a window (with dispose()
) and hiding it (with setVisible(false)
) are different operations, and produce different events -- and closing it from the operating system is yet another different operation that produces yet a different event.
关闭窗口(使用dispose())并隐藏它(使用setVisible(false))是不同的操作,并产生不同的事件 - 从操作系统关闭它是另一个产生不同事件的不同操作。
All three will produce windowDeactivated
to tell you the window's lost focus, but dispose()
will then produce windowClosed
, while closing from the OS will first produce windowClosing
. If you want to handle both of these the same way, you can set the window to be disposed when closed:
所有三个都会产生windowDeactivated以告诉你窗口失去焦点,但dispose()将生成windowClosed,而从OS关闭将首先产生windowClosing。如果要以相同的方式处理这两种方法,可以将窗口设置为在关闭时处理:
window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
In general, setVisible(false)
implies that you might want to use the window again, so it doesn't post any window events (apart from windowDeactivated
). If you want to detect the hiding of a window, you need to use a ComponentListener
;
通常,setVisible(false)意味着您可能希望再次使用该窗口,因此它不会发布任何窗口事件(除了windowDeactivated)。如果要检测窗口的隐藏,则需要使用ComponentListener;
window.addComponentListener(new ComponentAdapter() {
@Override
public void componentHidden(ComponentEvent e) {
System.out.println("componentHidden()");
}
})
Note though that this will pretty much only work for explicit setVisible()
calls. If you need to detect hiding more generally, you can use a HierarchyListener
, but it's probably more trouble than it's worth.
请注意,这几乎只适用于显式setVisible()调用。如果你需要更普遍地检测隐藏,你可以使用HierarchyListener,但它可能比它的价值更麻烦。
window.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
System.out.println("valid: " + window.isValid());
System.out.println("showing: " + window.isShowing());
}
});
Note that when you dispose a window you'll get a couple of HierarchyEvent
s, first for hiding and then for invalidation, but when you hide it with setVisible()
it's still valid, so you won't get the invalidation.
请注意,当你处理一个窗口时,你会得到几个HierarchyEvents,首先是隐藏然后是失效,但是当你用setVisible()隐藏它时它仍然有效,所以你不会得到失效。
#2
3
I don't seem to have your problem. When I use the code below windowDeactivated() is called for either setVisible( false ) or dispose() and windowClosed() is also called for dispose().
我似乎没有你的问题。当我使用下面的代码时,对于setVisible(false)或dispose()调用windowDeactivated(),并且还调用windowClosed()for dispose()。
ClosingDialog.java:
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
1
Dispatch a windowClosing event to the Window. Check out the ExitAction example from the Closing an Application entry.
将windowClosing事件发送到Window。查看Closing an Application条目中的ExitAction示例。
#4
0
Untested suggestion:
未经测试的建议:
Have you tried getWindowListeners() and then iterating around to fire windowClosed() to each of the WindowListeners?
您是否尝试过getWindowListeners()然后迭代以向每个WindowListeners触发windowClosed()?
EDIT: the above suggestion is wrong. Keeping it for posterity.
编辑:上述建议是错误的。为后代保留它。
I'm afraid calling dialog.dispose() works fine for me in my simple example.
在我的简单例子中,我害怕调用dialog.dispose()对我来说很好。
#5
0
I wanted to fire a windowClosing
event from the code (just as if the user clicked the X), because I have an extra close button in the JDialog and want the same WindowListener (that I implemented using a WindowAdapter
) to be run when the X is clicked and when the button is clicked. Running dispose()
only fires windowClosed
, not windowClosing
, and I want a message to appear before the window is closed, for confirmation. I also didn't manage to fire windowClosing
via JDialog's method processWindowEvent
since it is protected.
我想从代码中触发一个windowClosing事件(就像用户单击X一样),因为我在JDialog中有一个额外的关闭按钮,并希望在X时运行相同的WindowListener(我使用WindowAdapter实现)单击并单击按钮时单击。运行dispose()只触发windowClosed,而不是windowClosing,我希望在窗口关闭之前显示一条消息,以便进行确认。我也没有设法通过JDialog的方法processWindowEvent来激活windowClosing,因为它受到保护。
Here is how I got it working though:
以下是我如何使用它:
WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));
Hope that helps someone.
希望能帮助别人。