我目前正在开发一个具有始终存在的主JFrame
的工作应用程序。我目前有一个孩子JDialog
出现在按钮上。此框架具有JMenu
,其中包含“退出显示”的项目。当我按下显示选项的注销时,我的任务是确保这个孩子JDialog
消失。当注销发生时,主显示器通过以下方式设置为不可见:
mainFrame.setVisible(false);
子JDialog具有默认的关闭操作:
DISPONSE_ON_CLOSE
当用户重新登录时,首先要做的是:
mainFrame.setVisible(true);
发生这种情况时,子对话框会显示备份。看看JDialog
Javadoc,这似乎是预期的行为。但是,我还没有办法打破父母/孩子的关系或彻底摧毁孩子JDialog
。似乎JDialog
将一直保留到GC,这可能不会及时发生。
这是一个模拟我所看到的行为的示例程序:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public class WindowTest {
public static void createAndShowGUI() {
JFrame aFrame = new JFrame("LAUNCHER");
final JFrame aParent = new JFrame("PARENT");
final JDialog aChild = new JDialog(aParent);
aParent.setSize(200,200);
final JToggleButton showParentButton = new JToggleButton("HIDE");
showParentButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showParentButton.setText(!showParentButton.isSelected() ? "SHOW": "HIDE");
aParent.setVisible(!showParentButton.isSelected());
}
});
aChild.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
aChild.setSize(200,200);
aParent.addComponentListener(new ComponentAdapter() {
public void componentHidden(ComponentEvent e) {
aChild.dispose();
aChild.setVisible(false);
}
});
aFrame.setContentPane(showParentButton);
aFrame.pack();
aFrame.setVisible(true);
aParent.setVisible(true);
aChild.setVisible(true);
}
public static void main(String [] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
createAndShowGUI();
}
});
}
}
当父母被隐藏时,孩子会被处理掉。显示父级时,孩子会显示备份。真正奇怪的是,当我按下孩子的X时:当父母被隐藏然后再次显示时,孩子不显示备份。
我看到的唯一区别是单击X也会触发WindowClosing事件。我尝试在上面的componentHidden方法中发送even:
//Added into the constructor
//add to the imports: import java.awt.event.WindowEvent;
aParent.addComponentListener(new ComponentAdapter() {
public void componentHidden(ComponentEvent e) {
aChild.dispose();
aChild.setVisible(false);
WindowEvent closingEvent =
new WindowEvent(aChild, WindowEvent.WINDOW_CLOSING);
aChild.dispatchEvent(closingEvent);
}
});
这并没有解决问题。
目前看起来我唯一的选择是将孩子的类型更改为JFrame
。我只是想知道是否有一种处理孩子的正确方法JDialog
。
我目前在Redhat Enterprise Linux Server 6.4版上运行Java版本:1.7.0_76 64位。
答案 0 :(得分:4)
我不知道命名约定会影响编译。
没有。为保持一致性,可读性和可维护性而进行了约定。编写代码的人并不总是维护代码的人。因此,如果您希望其他人阅读您的代码,特别是在寻求帮助时,请遵循标准。
您可以从Java Programming Style Guidelines
开始我按照公司的标准从另一个屏幕手动复制代码。
这完全是浪费时间。您的代码没有任何专有权。再问一个问题时,代码应该是SSCCE的形式,这样才能证明问题。这允许您删除所有不必要的代码。
直接找出进口货物。
完全正确,所以你应该这样做。你希望我们帮助你,为什么我们要花时间搞清楚?尽可能让人们想要帮助你。
添加导入没有帮助。您发布的代码仍然无法编译,所以我不知道它是否准确反映了您试图描述的问题。
再次发布代码的重点是我们可以复制/粘贴/编译/测试。在你发布适当的SSCCE之前,我不会提供答案。
编辑:
从我的测试中,如果在父项不可见时父项的可见性改变了子窗口的可见性,那么当父项可见时,子项的可见性也会被父项更改。因此,当可见性发生变化时,父母看起来像是保留了子窗口的状态。
所以解决方法是让子窗口在父窗口之前不可见:
showParentButton.setText(!showParentButton.isSelected() ? "SHOW": "HIDE");
aChild.setVisible(false); // add this
aParent.setVisible(!showParentButton.isSelected());
如果您没有对子窗口的引用,那么我猜您可以使用Windows.getOwnedWindows()
方法访问所有子窗口。
另一个编辑:
作为一个黑客,我创建了一个自定义对话框,一旦处理就无法再显示:
final JDialog aChild = new JDialog(aParent)
{
private boolean disposed = false;
@Override
public void dispose()
{
super.dispose();
disposed = true;
}
@Override
public void show()
{
if (disposed)
return;
super.show();
}
};