通常在Swing应用程序中,如果我想向用户显示JDialogs
,我会创建一次它们,然后重用它们
通常主JFrame
具有对这些JDialogs
的引用
尽管有时我需要从JFrame class
之外的部分代码中显示JDialog
通常,我会公开(JFrame
的(JDialog
成员变量,它们要么是静态的,要么传递JFrame
的引用,以便能够访问JDialog
它有效,但在我看来很乱。
我想知道这样的东西有标准的设计方法吗?
我自己的理念是让几乎所有字段都是私有的,包括对话框,只公开需要公开的字段,不多也不少。例如,如果我有一个从另一个类调用的JDialog,并且我从该对话框中获取信息,那么我只通过公共getter方法公开信息,而不是对话框本身。
编辑1
很抱歉出现了一些严重的过度杀伤和比预期的长得多的代码,但这正是我在MVC中的意思,并且创建得很匆忙:
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import javax.swing.*;
public class DialogEg {
private static void createAndShowUI() {
JFrame frame = new JFrame("Dialog Eg");
MainPanel mainPanel = new MainPanel();
MainControl mainControl = new MainControl(frame);
mainControl.setMainPanel(mainPanel);
mainPanel.setControl(mainControl);
frame.getContentPane().add(mainPanel.getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MainPanel {
private JPanel mainPanel = new JPanel();
private JButton showDlgBtn = new JButton("Show Dialog");
private JTextField field = new JTextField(10);
private MainControl mainControl;
public MainPanel() {
mainPanel.add(showDlgBtn);
mainPanel.add(field);
field.setEditable(false);
showDlgBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (mainControl != null) {
mainControl.showDialog();
}
}
});
}
public void setControl(MainControl mainControl) {
this.mainControl = mainControl;
}
public void setFieldText(String text) {
field.setText(text);
}
public JPanel getMainPanel() {
return mainPanel;
}
}
class DialogPanel {
private static final String[] COMBO_DATA = {"", "one", "two", "three", "four"};
private JPanel dialogPanel = new JPanel();
private JComboBox combo = new JComboBox(COMBO_DATA);
public DialogPanel() {
dialogPanel.add(combo);
combo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.getWindowAncestor(dialogPanel);
window.dispose();
}
});
}
public JPanel getDialogPanel() {
return dialogPanel;
}
public String getSelectedText() {
return combo.getSelectedItem() == null ? "" : combo.getSelectedItem().toString();
}
}
class MainControl {
private DialogPanel dlgPanel = new DialogPanel();
private MainPanel mainPanel;
private JFrame frame;
public MainControl(JFrame frame) {
this.frame = frame;
}
public void setMainPanel(MainPanel mainPanel) {
this.mainPanel = mainPanel;
}
public void showDialog() {
if (mainPanel != null) {
JDialog dialog = new JDialog(frame, "Dialog", ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dlgPanel.getDialogPanel());
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
String text = dlgPanel.getSelectedText();
if (text != null) {
mainPanel.setFieldText(text);
}
}
}
}
这里的关键是MainPanel对DialogPanel一无所知,反之亦然,因为它都是通过MVC的奇迹由MainControl连接的。
将JFrame实例传递给创建新JDialog实例的辅助类,或者,如果您的应用程序只有一个框架,则使该框架可以从任何地方访问:
public class MyApp {
private static JFrame mainFrame;
public static JFrame getMainFrame() {
return MyApp.mainFrame;
}
public static void main(String[] args) {
// ...
MyApp.mainFrame = new JFrame();
// ...
}
}
我通常避免重复使用对话框实例:这会使代码更难编写(您需要注意对话框的先前状态(,并且会消耗内存来保留不可见的对话框实例。