【发布时间】:2020-05-27 20:33:21
【问题描述】:
我意识到,正式的方法是监听添加到 JFrame 主机的窗口关闭事件,然后简单地调用 JPanel 上的清理方法。不过,我很好奇。我最近才需要在我的程序中已经使用的面板中关闭(关闭、离开、离开)挂钩。而且,出于好奇,我不想重新访问该面板放置在通用旧 JFrame 中的地方(不需要特殊处理的地方),并且它只是显示为对话框,等待输入,然后后被解雇。我不想让这个假设的其他编码器(我)去向那些已经使用我的面板的框架添加窗口侦听器,要求他们现在调用一个新的关闭方法。是我在 Panel 中的代码需要添加的功能,那么为什么让那些 Framers 都去更改他们的代码以添加窗口侦听器呢? JPanel 不能自己找出来吗?
所以,我为 JPanel 做了一个 hack,以检测它何时被关闭,而 JFrame 不需要窗口侦听器。 JPanel,对我来说,现在更加自我意识......它有自己的窗口关闭检测策略,独立于使用我的 JPanel 需要编写侦听器和调用关闭挂钩的编码器。我只是想尝试一下,而不必返回并更改现有代码。
也意识到,我的 hack 仅适用于 DISPOSE_ON_CLOSE,但是……这就是我在对话中使用的方法。
有人可以告诉我应该怎么做吗?有我可以挖掘的财产事件吗?这必须是我刚刚在这里所做的一次可以开火的进攻。这一定是非常错误的。然而,我有我自己的 JPanel 关闭钩子,它可以工作。有人请引导我到别处(没有明显选择父 JFrame 使用它自己的窗口关闭事件,我想看看 JPanel 是否可以自己意识到这一点。)
我的 hack 有效……告诉我它有什么问题。它一定是错的,即使它对我有用。对吧?
下面的 sn-p 是一个正在运行的模型。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class JPanelClosing extends JPanel {
static JFrame frame; // This frame is only here for the mmockup ... what
// follows after would be part of your own custom JPanel.
private boolean formClosing = false;
private boolean filterEvent = true;
public JPanelClosing() {
initComponents();
}
private void initComponents() {
addPropertyChangeListener(new java.beans.PropertyChangeListener() {
@Override
public void propertyChange(java.beans.PropertyChangeEvent evt) {
formPropertyChange(evt);
}
});
}
private void formPropertyChange(java.beans.PropertyChangeEvent evt) {
// This is a hack I came up with. The JPanel fires two events when
// used in a waiting input dialog of an unkown JFrame that hosts it.
// When the JFrame DefaultCloseOperation is set to DISPOSE_ON_CLOSE:
// PropertyChangeEvent fires twice when it opens, and twice when it closes.
// So, I filter out the two events to pick one, like using !valueIsAdjusting.
// Then, I filter whether it's state one, opening, or state two, closing.
// This is all kept track of using two field variables; filterEvent, and formClosing
// With DISPOSE_ON_CLOSE, (on my machine) I get:
// Form opened.
// Form Closed.
// (EXIT_ON_CLOSE and HIDE_ON_CLOSE will only produce 'Form opened')
if (!filterEvent) {
if ( formClosing ) {
System.out.println("Form Closed.");
System.exit(0);
} else {
formClosing = true;
System.out.println("Form opened.");
}
filterEvent = true;
} else { // end if value not adjusting
filterEvent = false;
}
}
public static void main (String args[] ) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame = new JFrame();
final JPanel panel = new JPanelClosing();
frame.setContentPane(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
【问题讨论】:
-
使用 AncestorEvent 怎么样?
-
谢谢,我会检查的。它说它可以检测到: ANCESTOR_REMOVED 祖先组件已从可见对象的层次结构中删除(隐藏)并且不再显示。也许这会奏效。如果我发现这更正式,我会使用它并回帖。