web-dev-qa-db-ja.com

Java Swing dispose()vs。setVisible(false)

データベースからデータを取得してJTableに表示するスタンドアロンのJavaアプリケーションがあります。アプリケーションが起動すると、ユーザーはJDialogでユーザー名/パスワードの入力を求められます。正しい資格情報を取得したら入力すると、データを含むメインJFrameが表示されます。メイン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();
            }
        });
    }
}
_

MainFrame.Java:

_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);
    }
}
_

MyDialog.Java:

_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)で機能するのかということです。コードを整理するためのより良い方法はありますか?私はSwingを初めて使用するので、これが基本的な質問である場合はお詫び申し上げます。ありがとうございました。


2011-10-19 10:26 PDT編集

みなさん、ありがとうございました。 JDialogをnullの親を持つように変更したところ、すべてが希望どおりに機能するようになりました。

8
user1002119

JDialogを開始する行を参照してください。

dialog = new MyDialog(this);

ダイアログが置かれている親フレームと同じフレームを設定しています。ご覧のとおり、ダイアログはそれ自体では表示できません。親フレームの上に配置する必要があります。

したがって、コードでは、次のように記述します。

setVisible(false); // works when changed to dispose();
dialog.setVisible(true);

最初の行で、フレームを非表示にするように指示し、次にダイアログを表示するように指示します。これにより、ダイアログが親フレームに表示されるようになります。親フレームは同じであるため、表示されたままのように見えます。 2行目を削除すると、フレームが消えると確信しています。しかし、フレームに破棄するように指示すると、可視性を失うだけでなく、メモリから自分自身を削除するように指示したため、フレームは完全に消えます。

次に、ダイアログを表示するように指示すると、ダイアログは(破棄された)JFrameを探し、再初期化して開きます。

問題を解決する方法は、JDialog用に別の新しいJFrameを作成することです。次に、disposeを使用せず、setVisibleコマンドを使用します。

-アサフ

7
Asaf

私は自分のスタイルで正しいコードを与えるだけです。それは確かに単一の、あるいは証明された最良の解決策ではありません。

メインフレームのsetVisible(false)は、論理的にはメインフレームEXIT_ON_CLOSEに対してクローズ操作を呼び出す必要があります。ダイアログがメインフレームの子である場合、アプリケーションは終了します。

そこで、モーダルダイアログを2番目のトップウィンドウにしました。このウィンドウには、(JFrame)nullが親として含まれています。したがって、2つの上部ウィンドウを持つアプリケーションがあります。そして、モーダルダイアログは毎回破棄されます。閉じるアイコンを機能させたくないので、モーダルダイアログをDO_NOTHING_ON_CLOSEにしました。したがって、actionPerformedのdispose()。 (いつでも親がある場合は、親をフィールドにコピーする代わりにgetOwner()を使用できます。)

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainFrame mainFrame = new MainFrame();
                mainFrame.actionPerformed(null);
            }
        });
    }
}


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

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

    @Override
    public void actionPerformed(ActionEvent e) {
        MyDialog dialog = new MyDialog(MainFrame.this);
        dialog.setVisible(true);
        setVisible(false);
    }
}


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

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

    @Override
    public void actionPerformed(ActionEvent e) {
        parentFrame.setVisible(true);
        dispose();
    }
}
0
Joop Eggen