データベースからデータを取得して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の親を持つように変更したところ、すべてが希望どおりに機能するようになりました。
JDialogを開始する行を参照してください。
dialog = new MyDialog(this);
ダイアログが置かれている親フレームと同じフレームを設定しています。ご覧のとおり、ダイアログはそれ自体では表示できません。親フレームの上に配置する必要があります。
したがって、コードでは、次のように記述します。
setVisible(false); // works when changed to dispose();
dialog.setVisible(true);
最初の行で、フレームを非表示にするように指示し、次にダイアログを表示するように指示します。これにより、ダイアログが親フレームに表示されるようになります。親フレームは同じであるため、表示されたままのように見えます。 2行目を削除すると、フレームが消えると確信しています。しかし、フレームに破棄するように指示すると、可視性を失うだけでなく、メモリから自分自身を削除するように指示したため、フレームは完全に消えます。
次に、ダイアログを表示するように指示すると、ダイアログは(破棄された)JFrameを探し、再初期化して開きます。
問題を解決する方法は、JDialog用に別の新しいJFrameを作成することです。次に、disposeを使用せず、setVisibleコマンドを使用します。
-アサフ
私は自分のスタイルで正しいコードを与えるだけです。それは確かに単一の、あるいは証明された最良の解決策ではありません。
メインフレームの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();
}
}