Usually in a Swing application if I want to display JDialogs
to the user, I create them once and then reuse them.
JFrame
has references to these JDialogs
.
Sometimes though I need to display a JDialog
from parts of code outside the JFrame class
.
Usually I make开发者_JAVA技巧 the JDialog
member variables (of JFrame
) public and either they are static or pass a reference of the JFrame
arround to be able to access the JDialog
.
It works but it seems messy to me.
I was wondering is there a standard design approach for something like this? My own philosophy is to make almost all fields private, including the dialog and only expose that which needs exposing, no more and no less. For instance if I have a JDialog called from another class and I get information from that dialog, I expose only the information via public getter methods, not the dialog itself.
Edit 1
Sorry for some gross over-kill and much longer than expected code, but this is kind of what I meant in an MVC sort of way and created in a great hurry:
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);
}
}
}
}
The key here is that the MainPanel has no knowledge about the DialogPanel and visa-versa since it's all connected by the MainControl through the marvels of MVC.
Either pass the JFrame instance to the helper classes which create new JDialog instances, or, if your application has a single frame, make this frame accessible from anywhere:
public class MyApp {
private static JFrame mainFrame;
public static JFrame getMainFrame() {
return MyApp.mainFrame;
}
public static void main(String[] args) {
// ...
MyApp.mainFrame = new JFrame();
// ...
}
}
I usually avoid reusing dialog instances: this makes the code more difficult to write (you need to take care of the previous state of the dialog), and it consumes memory to keep invisible dialog instances around.
精彩评论