KDialog's constructors map to JDialog'spackage kahuna.ui; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; public class KDialog extends JDialog { protected KDialog(Frame owner, boolean modal) { super(owner, modal); } protected KDialog(Dialog owner, boolean modal) { super(owner, modal); } protected KDialog(Frame owner, String title, boolean modal) { super(owner, title, modal); } protected KDialog(Dialog owner, String title, boolean modal) { super(owner, title, modal); }Always pass in a valid owner to avoid orphan dialogs. Orphan dialogs disappear when you click on another window but they don't go away, they just slip underneath, and you have to close other windows to find them. |
ExampleDialog extends, adds widgets and modelpackage kahuna.ui; import java.awt.*; import javax.swing.*; public class ExampleDialog extends KDialog { private static final boolean MODAL = true; private static final String TITLE = "Exemplary Dialog"; // the object whose data we're messing with private SomeClass dataOwner; // widgets private JLabel nameLabel; private JTextField nameText; private JLabel phoneLabel; private JTextField phoneText; private JCheckBox sexCheck; // constructor as template method public ExampleDialog(Frame owner, SomeClass dataOwner) { super(owner, TITLE, MODAL); this.dataOwner = dataOwner; createComponents(); initializeComponents(); layoutComponents(); addWiring(); setLocationRelativeTo(owner); } |
KDialog's builder methods include stdTextField() . . .
public static JTextField stdTextField(int columns) {
final JTextField tf = new JTextField(columns) {
public Dimension getMaximumSize() {
Dimension max = super.getMaximumSize();
Dimension prf = getPreferredSize();
return new Dimension(max.width, prf.height);
}
};
tf.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent event) {
if (!event.isTemporary()) {
tf.selectAll();
}
}
});
return tf;
}
. . . stdPasswordField() . . .
public static JPasswordField stdPasswordField(int cols) {
final JPasswordField tf = new JPasswordField(cols) {
public Dimension getMaximumSize() {
Dimension max = super.getMaximumSize();
Dimension prf = getPreferredSize();
return new Dimension(max.width, prf.height);
}
};
tf.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent event) {
if (!event.isTemporary()) {
tf.selectAll();
}
}
});
return tf;
}
|
ExampleDialog creates and initializes its components
private void createComponents() {
nameLabel = new JLabel("Name:");
nameText = stdTextField(15);
phoneLabel = new JLabel("Phone:");
phoneText = stdTextField15);
sexCheck = new JCheckBox("Sex");
}
private void initializeComponents() {
// add mnemonics
nameLabel.setDisplayedMnemonic('N');
nameLabel.setLabelFor(nameText);
phoneLabel.setDisplayedMnemonic('P');
phoneLabel.setLabelFor(phoneText);
sexCheck.setMnemonic('S');
// init data widgets
nameText.setText(dataOwner.getName());
sexCheck.setSelected(dataOwner.isSexed());
}
private void addWiring() {}
|
. . . stdCancelButton() . . .
protected JButton stdCancelButton() {
JButton button = new JButton("Cancel");
button.setMnemonic('C');
button.setDefaultCapable(false);
Action cancelAction = new AbstractAction("Cancel") {
public void actionPerformed(ActionEvent event) {
Here's the action:
setVisible(false);
}
};
button.addActionListener(cancelAction);
mapKeyToAction(KeyEvent.VK_ESCAPE, cancelAction);
return button;
}
. . . stdOKButton()
protected JButton stdOKButton() {
JButton button = new JButton("OK");
button.setMnemonic('O');
getRootPane().setDefaultButton(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Here's the action:
if (dataIsValid()) {
setModelFromView();
setVisible(false);
}
}
});
return button;
}
Subclasses should override dataIsValid() . . .
protected boolean dataIsValid() {
return true;
}
. . . and setModelFromView()
protected void setModelFromView() {}
|
ExampleDialog overrides dataIsValid() . . .(Note the chaining of validation methods.)
protected boolean dataIsValid() {
return nameIsOK() && phoneIsOK();
}
private boolean nameIsOK() {
if (nameText.getText().length() > 0) {
return true;
}
stdErrBox("You must enter a name.");
nameText.requestFocus();
return false;
}
private boolean phoneIsOK() {
if (phoneText.getText().length() > 0) {
return true;
}
stdErrBox("You must enter a phone number.");
phoneText.requestFocus();
return false;
}
. . . and setModelFromView()(This only gets called if the user clicks the OK button.)
protected void setModelFromView() {
dataOwner.setName(nameText.getText());
dataOwner.setPhone(phoneText.getText());
dataOwner.setSexed(sexCheck.isSelected());
}
|
KDialog supplies standard message boxes . . .. . . a standard "information" type box
protected void stdInfoBox(String message) {
stdInfoBox(this, message);
}
. . . a standard "warning" type box
protected void stdWarningBox(String message) {
stdWarningBox(this, message);
}
. . . and a standard "error" type box
protected void stdErrBox(String message) {
stdErrBox(this, message);
}
KDialog also offers static versions of these methods:
public static void stdErrBox(Component pa, String msg) {
stdMsgBox(pa, msg, JOptionPane.ERROR_MESSAGE);
}
|
The standard message boxes.
stdInfoBox("Our new version doesn't crash as much.");
![]()
stdWarningBox("That tie doesn't go with that shirt.");
![]()
stdErrBox("Sorry. All your data has been lost.");
![]()
|
KDialog's convenience methods: stdLayout() . . .protected void stdLayout(Component widgetBox, JButton[] buttons) { // create button box Box buttonBox = Box.createHorizontalBox(); buttonBox.add(Box.createHorizontalGlue()); for (int i = 0; i < buttons.length; i++) { if (i > 0) { buttonBox.add(Box.createHorizontalStrut(5)); } buttonBox.add(buttons[i]); } matchComponentSize(buttons); // create main box Box mainBox = Box.createVerticalBox(); mainBox.add(widgetBox); mainBox.add(createVerticalStrut(17)); mainBox.add(buttonBox); // assemble std dialog Container cont = getContentPane(); cont.add(createVerticalStrut(13), BorderLayout.NORTH); cont.add(createVerticalStrut(10), BorderLayout.SOUTH); cont.add(createHorizontalStrut(11), BorderLayout.WEST); cont.add(createHorizontalStrut(10), BorderLayout.EAST); cont.add(mainBox); pack(); } |
ExampleDialog only lays out its own widgets// all routines from here on concern only visual layout private void layoutComponents() { Container widgetBox = createMainBox(); JButton[] buttons = { stdOKButton(), stdCancelButton() }; stdLayout(widgetBox, buttons); } |
. . . matchComponentSize(JComponent[]) . . .public static void matchComponentSize(JComponent[] comps) { Dimension size = new Dimension(0, 0); for (int i = 0; i < comps.length; i++) { if (comps[i].isVisible()) { Dimension bSize = comps[i].getPreferredSize(); size.width = (size.width < bSize.width) ? bSize.width : size.width; size.height = (size.height < bSize.height) ? bSize.height : size.height; } } for (int i = 0; i < comps.length; i++) { comps[i].setPreferredSize(size); comps[i].setMinimumSize(size); comps[i].setMaximumSize(size); } } . . . shrinkWrap(AbstractButton[]) . . .public static void shrinkWrap(AbstractButton[] buttons) { Insets shrinkWrap = new Insets(0, 0, 0, 0); for (int i = 0; i < buttons.length; i++) { buttons[i].setMargin(shrinkWrap); } } . . . createHorizontalStrut(int width) . . .public static Component createHorizontalStrut(int width) { return Box.createRigidArea(new Dimension(width, 0)); } . . . and createVerticalStrut(int height)public static Component createVerticalStrut(int height) { return Box.createRigidArea(new Dimension(0, height)); } |
Boxes within boxes within boxes . . .private Box createMainBox() { Box box = Box.createVerticalBox(); matchComponentSize(new JComponent[]{ nameLabel, phoneLabel }); box.add(createNameTextBox()); box.add(createVerticalStrut(5)); box.add(createPhoneTextBox()); box.add(createVerticalStrut(5)); box.add(createIsSexedBox()); return box; } private Box createNameTextBox() { Box box = Box.createHorizontalBox(); box.add(nameLabel); box.add(Box.createHorizontalGlue()); box.add(createHorizontalStrut(11)); box.add(nameText); return box; } private Box createPhoneTextBox() { Box box = Box.createHorizontalBox(); box.add(phoneLabel); box.add(Box.createHorizontalGlue()); box.add(createHorizontalStrut(11)); box.add(phoneText); return box; } private Box createIsSexedBox() { Box box = Box.createHorizontalBox(); shrinkWrap(new AbstractButton[]{ sexCheck }); box.add(sexCheck); box.add(Box.createHorizontalGlue()); return box; } |