Java Swing dispose()与setVisible(false)

Java Swing dispose()与setVisible(false),java,swing,visibility,dispose,Java,Swing,Visibility,Dispose,我有一个独立的Java应用程序,它从数据库中获取数据并将其显示在JTable中。当应用程序启动时,会在JDialog中提示用户输入用户名/密码。输入正确的凭据后,将显示包含数据的主框架。在主JFrame上,我有一个注销按钮,单击该按钮时,应关闭主JFrame并重新显示登录JDialog。除了我发现当单击注销按钮时,主JFrame不会消失之外,其他一切都在正常工作。下面是我的代码的一个小示例: Main.java: import javax.swing.SwingUtilities; publi

我有一个独立的Java应用程序,它从数据库中获取数据并将其显示在JTable中。当应用程序启动时,会在JDialog中提示用户输入用户名/密码。输入正确的凭据后,将显示包含数据的主框架。在主JFrame上,我有一个注销按钮,单击该按钮时,应关闭主JFrame并重新显示登录JDialog。除了我发现当单击注销按钮时,主JFrame不会消失之外,其他一切都在正常工作。下面是我的代码的一个小示例:

Main.java:

import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();
            }
        });
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MainFrame extends JFrame implements ActionListener {
    private JButton button;
    private MyDialog dialog;

    public MainFrame() {
        super("this is the JFrame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        dialog = new MyDialog(this);
        button = new JButton("click me to hide this JFrame and display JDialog");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false); // works when changed to dispose();
        dialog.setVisible(true);
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;


public class MyDialog extends JDialog implements ActionListener {
    private JFrame parentFrame;
    private JButton button;

    public MyDialog(JFrame parentFrame) {
        super(parentFrame, "this is the JDialog", true);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.parentFrame = parentFrame;
        button = new JButton("click me to hide JDialog and show JFrame");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false);
        parentFrame.setVisible(true);
    }
}
MainFrame.java:

import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();
            }
        });
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MainFrame extends JFrame implements ActionListener {
    private JButton button;
    private MyDialog dialog;

    public MainFrame() {
        super("this is the JFrame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        dialog = new MyDialog(this);
        button = new JButton("click me to hide this JFrame and display JDialog");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false); // works when changed to dispose();
        dialog.setVisible(true);
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;


public class MyDialog extends JDialog implements ActionListener {
    private JFrame parentFrame;
    private JButton button;

    public MyDialog(JFrame parentFrame) {
        super(parentFrame, "this is the JDialog", true);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.parentFrame = parentFrame;
        button = new JButton("click me to hide JDialog and show JFrame");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false);
        parentFrame.setVisible(true);
    }
}
MyDialog.java:

import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();
            }
        });
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MainFrame extends JFrame implements ActionListener {
    private JButton button;
    private MyDialog dialog;

    public MainFrame() {
        super("this is the JFrame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        dialog = new MyDialog(this);
        button = new JButton("click me to hide this JFrame and display JDialog");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false); // works when changed to dispose();
        dialog.setVisible(true);
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;


public class MyDialog extends JDialog implements ActionListener {
    private JFrame parentFrame;
    private JButton button;

    public MyDialog(JFrame parentFrame) {
        super(parentFrame, "this is the JDialog", true);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.parentFrame = parentFrame;
        button = new JButton("click me to hide JDialog and show JFrame");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false);
        parentFrame.setVisible(true);
    }
}
MainFrame.java中,如果我将显示
setVisible(false)
的行更改为
dispose()
,那么当我单击按钮时,JFrame就会消失。我的问题是,为什么这对
dispose()
有效,而对
setVisible(false)
无效?有没有更好的方法来组织代码?我是个新手,所以如果这是一个基本问题,我很抱歉。多谢各位


编辑时间:2011-10-19 10:26 PDT


谢谢大家的帮助。我将JDialog更改为具有空父级,现在一切都按我的要求运行。

请参阅启动JDialog的行:

dialog = new MyDialog(this);
您正在设置与对话框所在的父框架相同的框架。你看,对话框不能单独出现,它必须位于父框架的顶部

因此,在您的代码中,当您编写:

setVisible(false); // works when changed to dispose();
dialog.setVisible(true);
在第一行中,告诉帧消失,然后告诉对话框显示,这实际上告诉对话框显示在其父帧上。由于父帧是相同的,因此看起来它对您仍然可见。如果你删除第二行,我肯定帧会消失。但是,当您告诉框架进行处理时,它将完全消失,因为您告诉它不仅要失去可见性,还要将自身从内存中删除

然后,当您告诉对话框显示时,它会查找其JFrame(已释放),重新初始化它并打开

解决问题的方法是为JDialog创建一个单独的新JFrame。然后不要使用dispose,只使用setVisible命令


-Asaf

我将以自己的风格给出正确的代码。它当然不是单一的,甚至不是经验证的最佳解决方案

主框架上的setVisible(false)应该调用关闭操作,从逻辑上讲,对于主框架退出,关闭。如果对话框是主框架的子级,则应用程序退出

因此,我将模态对话框设置为第二个顶部窗口,它的父窗口为(JFrame)null。因此,您有一个具有两个顶部窗口的应用程序。并且每次都会处理模态对话框。 我使模式对话框在关闭时不执行任何操作,因为您不希望关闭图标正常工作。 因此,actionPerformed中的dispose()已执行。 (如果您在任何时候都有父项,则可以使用getOwner()而不是将父项复制到字段。)


只要不使框架重新打开其父框架就足够了。因此,在
MyDialog()
go:
super中进行super调用(null,“这是JDialog”,false)。如果主框架被隐藏,它将不会收到有意义的输入,因此没有理由使对话框成为模态。@如果您是正确的,这也是一个选项。我忘了有一个用于模态的布尔值。另外,我相当肯定boolean模式已经被弃用,ModalityType方法现在是首选。不是真的弃用,至少不是正式弃用。它指定了哪个布尔值对应于哪个模态类型,所以这可能只是一个您喜欢哪个样式的问题。@Inedia很有趣,因为如果您尝试在eclipse中使用setModal(布尔模态),它会被标记为不推荐使用。在OS X附带的Java版本中,文档中没有这样标记(既不使用
@Deprecated
,也不使用相应的javadoc标记),而且在使用IntelliJ的javac构建时,我没有收到编译器警告,因此我认为Eclipse对此有自己的看法。文档提到
setModal()
是“过时的”,所以这可能是动机所在。(他们没有这样说构造函数。)我不认为setVisible调用close操作。它只是隐藏了框架/对话框……为了更快地获得更好的帮助,请发布一个。