001: /*
002: * @(#)StandardDialog.java
003: *
004: * Copyright 2002 - 2003 JIDE Software. All rights reserved.
005: */
006: package com.jidesoft.dialog;
007:
008: import com.jidesoft.swing.DelegateAction;
009: import com.jidesoft.swing.JideSwingUtilities;
010:
011: import javax.swing.*;
012: import java.awt.*;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.KeyEvent;
015: import java.awt.event.WindowAdapter;
016: import java.awt.event.WindowEvent;
017: import java.beans.PropertyChangeEvent;
018: import java.beans.PropertyChangeListener;
019:
020: /**
021: * StandardDialog is a dialog template. However several things are added to it
022: * to make it easier to use.
023: * <UL>
024: * <LI> Laziness. The content will not be filled until pack() or show() are called.
025: * <LI> Default action and cancel action. User can set the default
026: * action and cancel action of this dialog. By default, the ENTER key
027: * will trigger the default action and the ESC key will trigger the cancel action and set the dialog result to RESULT_CANCELLED.
028: * <LI> Divide the whole ContentPane of the dialog into three parts
029: * - content panel, button panel and banner panel. By default,
030: * they are added to the CENTER, SOUTH and NORTH of a BorderLayout respectively.
031: * There isn't anything special about this. However if all your dialogs use
032: * this pattern, it will automatically make the user interface more consistent.
033: * </UL>
034: * <p/>
035: * This class is abstract. Subclasses need to implement createBannerPanel(),
036: * createButtonPanel() and createContentPanel()
037: */
038: abstract public class StandardDialog extends JDialog implements
039: ButtonNames {
040: private boolean _lazyConstructorCalled = false;
041:
042: protected StandardDialogPane _standardDialogPane;
043:
044: /**
045: * Dialog result.
046: */
047: public final static int RESULT_CANCELLED = -1;
048:
049: /**
050: * Dialog result.
051: */
052: public final static int RESULT_AFFIRMED = 0;
053:
054: // indicate user press OK or Cancel.
055: private int _dialogResult = RESULT_CANCELLED;
056: public StandardDialogPropertyChangeListener _propertyChangeListener;
057:
058: public StandardDialog() throws HeadlessException {
059: this (null);
060: }
061:
062: public StandardDialog(Frame owner) throws HeadlessException {
063: this (owner, true);
064: }
065:
066: public StandardDialog(Frame owner, boolean modal)
067: throws HeadlessException {
068: this (owner, "", modal);
069: }
070:
071: public StandardDialog(Frame owner, String title)
072: throws HeadlessException {
073: this (owner, title, true);
074: }
075:
076: public StandardDialog(Frame owner, String title, boolean modal)
077: throws HeadlessException {
078: super (owner, title, modal);
079: _standardDialogPane = createStandardDialogPane();
080: _propertyChangeListener = new StandardDialogPropertyChangeListener();
081: _standardDialogPane
082: .addPropertyChangeListener(_propertyChangeListener);
083: }
084:
085: public StandardDialog(Dialog owner, boolean modal)
086: throws HeadlessException {
087: this (owner, "", modal);
088: }
089:
090: public StandardDialog(Dialog owner, String title)
091: throws HeadlessException {
092: this (owner, title, true);
093: }
094:
095: public StandardDialog(Dialog owner, String title, boolean modal)
096: throws HeadlessException {
097: super (owner, title, modal);
098: _standardDialogPane = createStandardDialogPane();
099: _propertyChangeListener = new StandardDialogPropertyChangeListener();
100: _standardDialogPane
101: .addPropertyChangeListener(_propertyChangeListener);
102: }
103:
104: public StandardDialog(Dialog owner, String title, boolean modal,
105: GraphicsConfiguration gc) throws HeadlessException {
106: super (owner, title, modal, gc);
107: _standardDialogPane = createStandardDialogPane();
108: _propertyChangeListener = new StandardDialogPropertyChangeListener();
109: _standardDialogPane
110: .addPropertyChangeListener(_propertyChangeListener);
111: }
112:
113: /**
114: * Gets the result.
115: *
116: * @return the result.
117: */
118: public int getDialogResult() {
119: return _dialogResult;
120: }
121:
122: /**
123: * Sets the dialog result.
124: *
125: * @param dialogResult the new dialog result.
126: */
127: public void setDialogResult(int dialogResult) {
128: _dialogResult = dialogResult;
129: }
130:
131: /**
132: * Get default cancel action. Default cancel action will be triggered when ESC is pressed.
133: *
134: * @return the default cancel action
135: */
136: public Action getDefaultCancelAction() {
137: return _standardDialogPane.getDefaultCancelAction();
138: }
139:
140: /**
141: * Set default cancel action. Default cancel action will be triggered when ESC is pressed.
142: *
143: * @param defaultCancelAction the default cancel action
144: */
145: public void setDefaultCancelAction(Action defaultCancelAction) {
146: _standardDialogPane.setDefaultCancelAction(defaultCancelAction);
147: }
148:
149: /**
150: * Gets the default action. Default action will be trigger when ENTEY key is pressed.
151: *
152: * @return the default action.
153: */
154: public Action getDefaultAction() {
155: return _standardDialogPane.getDefaultAction();
156: }
157:
158: /**
159: * Sets the default action. Default action will be trigger when ENTEY key is pressed.
160: *
161: * @param defaultAction the default action.
162: */
163: public void setDefaultAction(Action defaultAction) {
164: _standardDialogPane.setDefaultAction(defaultAction);
165: }
166:
167: @Override
168: public void pack() {
169: try {
170: initialize();
171: } catch (Exception e) {
172: JideSwingUtilities.throwException(e);
173: }
174: super .pack();
175: }
176:
177: /**
178: * @deprecated As of JDK version 1.5, replaced by
179: * {@link Component#setVisible(boolean) Component.setVisible(boolean)}.
180: */
181: @Override
182: public void show() {
183: try {
184: initialize();
185: } catch (Exception e) {
186: JideSwingUtilities.throwException(e);
187: }
188: super .show();
189: }
190:
191: /**
192: * Force the initComponent() method implemented in the child class
193: * to be called. If this method is called more than once on
194: * a given object, all calls but the first do nothing.
195: */
196: public synchronized final void initialize() {
197: if ((!_lazyConstructorCalled) && (getParent() != null)) {
198: initComponents();
199: _lazyConstructorCalled = true;
200: validate();
201: }
202: }
203:
204: /**
205: * Call three createXxxPanel methods and layout them using BorderLayout.
206: * By default, banner panel, content panel and button panel are added to NORTH,
207: * CENTER and SOUTH of BorderLayout respectively.
208: * <p/>
209: * You can override this method if you want to layout them in another way.
210: */
211: protected void initComponents() {
212: getContentPane().setLayout(new BorderLayout());
213: _standardDialogPane.initComponents();
214: getContentPane().add(_standardDialogPane);
215:
216: if (getInitFocusedComponent() != null) {
217: addWindowListener(new WindowAdapter() {
218: @Override
219: public void windowActivated(WindowEvent e) {
220: getInitFocusedComponent().requestFocus();
221: }
222: });
223: }
224: }
225:
226: /**
227: * Gets the initial focused component when dialog is shown.
228: *
229: * @return the initial focused component
230: */
231: public Component getInitFocusedComponent() {
232: return _standardDialogPane.getInitFocusedComponent();
233: }
234:
235: /**
236: * Sets the initial focused component when dialog is shown.
237: *
238: * @param initFocusedComponent the initial focused component.
239: */
240: public void setInitFocusedComponent(Component initFocusedComponent) {
241: _standardDialogPane
242: .setInitFocusedComponent(initFocusedComponent);
243: }
244:
245: /**
246: * Gets the banner panel created by createBannerPanel.
247: *
248: * @return the banner panel.
249: */
250: public JComponent getBannerPanel() {
251: return _standardDialogPane.getBannerPanel();
252: }
253:
254: /**
255: * Gets the banner panel created by createContentPanel.
256: *
257: * @return the content panel.
258: */
259: public JComponent getContentPanel() {
260: return _standardDialogPane.getContentPanel();
261: }
262:
263: /**
264: * Gets the banner panel created by createButtonPanel.
265: *
266: * @return the button panel.
267: */
268: public ButtonPanel getButtonPanel() {
269: return _standardDialogPane.getButtonPanel();
270: }
271:
272: public StandardDialogPane getStandardDialogPane() {
273: return _standardDialogPane;
274: }
275:
276: /**
277: * Subclasses should implement this method to create the banner panel.
278: * By default banner panel will appear on top of the dialog unless you
279: * override initComponent() method. Banner panel is really used to balance
280: * the layout of dialog to make the dialog looking good. However it can be used
281: * to show some help text. It is highly recommended to use our {@link BannerPanel}
282: * <p/>
283: * If subclass doesn't want to have a banner panel, just return null.
284: *
285: * @return the banner panel.
286: */
287: abstract public JComponent createBannerPanel();
288:
289: /**
290: * Subclasses should implement this method to create the content panel.
291: * This is the main panel of the dialog which will be added to the center
292: * of the dialog. Subclass should never return null.
293: *
294: * @return the content panel.
295: */
296: abstract public JComponent createContentPanel();
297:
298: /**
299: * Subclasses should implement this method to create the button panel.
300: * 90% of dialogs have buttons. It is highly recommended to use our {@link ButtonPanel}.
301: *
302: * @return the button panel.
303: * @see ButtonPanel
304: */
305: abstract public ButtonPanel createButtonPanel();
306:
307: protected StandardDialogPane createStandardDialogPane() {
308: return new DefaultStandardDialogPane();
309: }
310:
311: class StandardDialogPropertyChangeListener implements
312: PropertyChangeListener {
313: public void propertyChange(PropertyChangeEvent evt) {
314: if (StandardDialogPane.PROPERTY_CANCEL_ACTION.equals(evt
315: .getPropertyName())) {
316: DelegateAction delegateAction = new DelegateAction(
317: getDefaultCancelAction()) {
318: @Override
319: public boolean delegateActionPerformed(ActionEvent e) {
320: MenuElement[] selectedPath = MenuSelectionManager
321: .defaultManager().getSelectedPath();
322: if (selectedPath != null
323: && selectedPath.length > 0) {
324: MenuSelectionManager.defaultManager()
325: .clearSelectedPath();
326: return true;
327: }
328: return false;
329: }
330: };
331: DelegateAction.replaceAction(getRootPane(),
332: JComponent.WHEN_IN_FOCUSED_WINDOW, KeyStroke
333: .getKeyStroke(KeyEvent.VK_ESCAPE, 0),
334: delegateAction, false);
335: } else if (StandardDialogPane.PROPERTY_DEFAULT_ACTION
336: .equals(evt.getPropertyName())) {
337: getRootPane().unregisterKeyboardAction(
338: KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
339: getRootPane().registerKeyboardAction(
340: getDefaultAction(),
341: KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
342: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
343:
344: }
345: }
346: }
347:
348: protected class DefaultStandardDialogPane extends
349: StandardDialogPane {
350: @Override
351: public JComponent createBannerPanel() {
352: return StandardDialog.this .createBannerPanel();
353: }
354:
355: @Override
356: public JComponent createContentPanel() {
357: return StandardDialog.this .createContentPanel();
358: }
359:
360: @Override
361: public ButtonPanel createButtonPanel() {
362: return StandardDialog.this.createButtonPanel();
363: }
364: }
365: }
|