%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
com.nexes.wizard.Wizard |
|
|
1 | package com.nexes.wizard; |
|
2 | ||
3 | import java.awt.*; |
|
4 | import java.awt.event.*; |
|
5 | import java.beans.*; |
|
6 | import java.util.*; |
|
7 | import java.net.*; |
|
8 | ||
9 | import javax.swing.*; |
|
10 | import javax.swing.border.*; |
|
11 | ||
12 | /** |
|
13 | * This class implements a basic wizard dialog, where the programmer can |
|
14 | * insert one or more Components to act as panels. These panels can be navigated |
|
15 | * through arbitrarily using the 'Next' or 'Back' buttons, or the dialog itself |
|
16 | * can be closed using the 'Cancel' button. Note that even though the dialog |
|
17 | * uses a CardLayout manager, the order of the panels is not linear. Each panel |
|
18 | * determines at runtime what its next and previous panel will be. |
|
19 | */ |
|
20 | public class Wizard extends WindowAdapter implements PropertyChangeListener { |
|
21 | ||
22 | /** |
|
23 | * Indicates that the 'Finish' button was pressed to close the dialog. |
|
24 | */ |
|
25 | public static final int FINISH_RETURN_CODE = 0; |
|
26 | /** |
|
27 | * Indicates that the 'Cancel' button was pressed to close the dialog, or |
|
28 | * the user pressed the close box in the corner of the window. |
|
29 | */ |
|
30 | public static final int CANCEL_RETURN_CODE = 1; |
|
31 | /** |
|
32 | * Indicates that the dialog closed due to an internal error. |
|
33 | */ |
|
34 | public static final int ERROR_RETURN_CODE = 2; |
|
35 | ||
36 | /** |
|
37 | * The String-based action command for the 'Next' button. |
|
38 | */ |
|
39 | public static final String NEXT_BUTTON_ACTION_COMMAND = "NextButtonActionCommand"; |
|
40 | /** |
|
41 | * The String-based action command for the 'Back' button. |
|
42 | */ |
|
43 | public static final String BACK_BUTTON_ACTION_COMMAND = "BackButtonActionCommand"; |
|
44 | /** |
|
45 | * The String-based action command for the 'Cancel' button. |
|
46 | */ |
|
47 | public static final String CANCEL_BUTTON_ACTION_COMMAND = "CancelButtonActionCommand"; |
|
48 | ||
49 | ||
50 | // The i18n text used for the buttons. Loaded from a property resource file. |
|
51 | ||
52 | static String BACK_TEXT; |
|
53 | static String NEXT_TEXT; |
|
54 | static String FINISH_TEXT; |
|
55 | static String CANCEL_TEXT; |
|
56 | ||
57 | // The image icons used for the buttons. Filenames are loaded from a property resource file. |
|
58 | ||
59 | static Icon BACK_ICON; |
|
60 | static Icon NEXT_ICON; |
|
61 | static Icon FINISH_ICON; |
|
62 | static Icon CANCEL_ICON; |
|
63 | ||
64 | ||
65 | private WizardModel wizardModel; |
|
66 | private WizardController wizardController; |
|
67 | private JDialog wizardDialog; |
|
68 | ||
69 | private JPanel cardPanel; |
|
70 | private CardLayout cardLayout; |
|
71 | private JButton backButton; |
|
72 | private JButton nextButton; |
|
73 | private JButton cancelButton; |
|
74 | ||
75 | private int returnCode; |
|
76 | ||
77 | ||
78 | ||
79 | /** |
|
80 | * Default constructor. This method creates a new WizardModel object and passes it |
|
81 | * into the overloaded constructor. |
|
82 | */ |
|
83 | public Wizard() { |
|
84 | 0 | this((Frame)null); |
85 | 0 | } |
86 | ||
87 | /** |
|
88 | * This method accepts a java.awt.Dialog object as the javax.swing.JDialog's |
|
89 | * parent. |
|
90 | * @param owner The java.awt.Dialog object that is the owner of this dialog. |
|
91 | */ |
|
92 | 0 | public Wizard(Dialog owner) { |
93 | 0 | wizardModel = new WizardModel(); |
94 | 0 | wizardDialog = new JDialog(owner); |
95 | 0 | initComponents(); |
96 | 0 | } |
97 | ||
98 | /** |
|
99 | * This method accepts a java.awt.Frame object as the javax.swing.JDialog's |
|
100 | * parent. |
|
101 | * @param owner The java.awt.Frame object that is the owner of the javax.swing.JDialog. |
|
102 | */ |
|
103 | 0 | public Wizard(Frame owner) { |
104 | 0 | wizardModel = new WizardModel(); |
105 | 0 | wizardDialog = new JDialog(owner); |
106 | 0 | initComponents(); |
107 | 0 | } |
108 | ||
109 | /** |
|
110 | * Returns an instance of the JDialog that this class created. This is useful in |
|
111 | * the event that you want to change any of the JDialog parameters manually. |
|
112 | * @return The JDialog instance that this class created. |
|
113 | */ |
|
114 | public JDialog getDialog() { |
|
115 | 0 | return wizardDialog; |
116 | } |
|
117 | ||
118 | /** |
|
119 | * Returns the owner of the generated javax.swing.JDialog. |
|
120 | * @return The owner (java.awt.Frame or java.awt.Dialog) of the javax.swing.JDialog generated |
|
121 | * by this class. |
|
122 | */ |
|
123 | public Component getOwner() { |
|
124 | 0 | return wizardDialog.getOwner(); |
125 | } |
|
126 | ||
127 | /** |
|
128 | * Sets the title of the generated javax.swing.JDialog. |
|
129 | * @param s The title of the dialog. |
|
130 | */ |
|
131 | public void setTitle(String s) { |
|
132 | 0 | wizardDialog.setTitle(s); |
133 | 0 | } |
134 | ||
135 | /** |
|
136 | * Returns the current title of the generated dialog. |
|
137 | * @return The String-based title of the generated dialog. |
|
138 | */ |
|
139 | public String getTitle() { |
|
140 | 0 | return wizardDialog.getTitle(); |
141 | } |
|
142 | ||
143 | /** |
|
144 | * Sets the modality of the generated javax.swing.JDialog. |
|
145 | * @param b the modality of the dialog |
|
146 | */ |
|
147 | public void setModal(boolean b) { |
|
148 | 0 | wizardDialog.setModal(b); |
149 | 0 | } |
150 | ||
151 | /** |
|
152 | * Returns the modality of the dialog. |
|
153 | * @return A boolean indicating whether or not the generated javax.swing.JDialog is modal. |
|
154 | */ |
|
155 | public boolean isModal() { |
|
156 | 0 | return wizardDialog.isModal(); |
157 | } |
|
158 | ||
159 | /** |
|
160 | * Convienence method that displays a modal wizard dialog and blocks until the dialog |
|
161 | * has completed. |
|
162 | * @return Indicates how the dialog was closed. Compare this value against the RETURN_CODE |
|
163 | * constants at the beginning of the class. |
|
164 | */ |
|
165 | public int showModalDialog() { |
|
166 | ||
167 | 0 | wizardDialog.setModal(true); |
168 | 0 | wizardDialog.pack(); |
169 | 0 | wizardDialog.setVisible(true); |
170 | ||
171 | 0 | return class="keyword">returnCode; |
172 | } |
|
173 | ||
174 | /** |
|
175 | * Returns the current model of the wizard dialog. |
|
176 | * @return A WizardModel instance, which serves as the model for the wizard dialog. |
|
177 | */ |
|
178 | public WizardModel getModel() { |
|
179 | 0 | return wizardModel; |
180 | } |
|
181 | ||
182 | /** |
|
183 | * Add a Component as a panel for the wizard dialog by registering its |
|
184 | * WizardPanelDescriptor object. Each panel is identified by a unique Object-based |
|
185 | * identifier (often a String), which can be used by the setCurrentPanel() |
|
186 | * method to display the panel at runtime. |
|
187 | * @param id An Object-based identifier used to identify the WizardPanelDescriptor object. |
|
188 | * @param panel The WizardPanelDescriptor object which contains helpful information about the panel. |
|
189 | */ |
|
190 | public void registerWizardPanel(Object id, WizardPanelDescriptor panel) { |
|
191 | ||
192 | // Add the incoming panel to our JPanel display that is managed by |
|
193 | // the CardLayout layout manager. |
|
194 | ||
195 | 0 | cardPanel.add(panel.getPanelComponent(), id); |
196 | ||
197 | // Set a callback to the current wizard. |
|
198 | ||
199 | 0 | panel.setWizard(this); |
200 | ||
201 | // Place a reference to it in the model. |
|
202 | ||
203 | 0 | wizardModel.registerPanel(id, panel); |
204 | ||
205 | 0 | } |
206 | ||
207 | /** |
|
208 | * Displays the panel identified by the object passed in. This is the same Object-based |
|
209 | * identified used when registering the panel. |
|
210 | * @param id The Object-based identifier of the panel to be displayed. |
|
211 | */ |
|
212 | public void setCurrentPanel(Object id) { |
|
213 | ||
214 | // Get the hashtable reference to the panel that should |
|
215 | // be displayed. If the identifier passed in is null, then close |
|
216 | // the dialog. |
|
217 | ||
218 | 0 | if (id == null) |
219 | 0 | close(ERROR_RETURN_CODE); |
220 | ||
221 | 0 | WizardPanelDescriptor oldPanelDescriptor = wizardModel.getCurrentPanelDescriptor(); |
222 | 0 | if (oldPanelDescriptor != null) |
223 | 0 | oldPanelDescriptor.aboutToHidePanel(); |
224 | ||
225 | 0 | wizardModel.setCurrentPanel(id); |
226 | 0 | wizardModel.getCurrentPanelDescriptor().aboutToDisplayPanel(); |
227 | ||
228 | // Show the panel in the dialog. |
|
229 | ||
230 | 0 | cardLayout.show(cardPanel, id.toString()); |
231 | 0 | wizardModel.getCurrentPanelDescriptor().displayingPanel(); |
232 | ||
233 | ||
234 | 0 | } |
235 | ||
236 | /** |
|
237 | * Method used to listen for property change events from the model and update the |
|
238 | * dialog's graphical components as necessary. |
|
239 | * @param evt PropertyChangeEvent passed from the model to signal that one of its properties has changed value. |
|
240 | */ |
|
241 | public void propertyChange(PropertyChangeEvent evt) { |
|
242 | ||
243 | 0 | if (evt.getPropertyName().equals(WizardModel.CURRENT_PANEL_DESCRIPTOR_PROPERTY)) { |
244 | 0 | wizardController.resetButtonsToPanelRules(); |
245 | 0 | } else if (evt.getPropertyName().equals(WizardModel.NEXT_FINISH_BUTTON_TEXT_PROPERTY)) { |
246 | 0 | nextButton.setText(evt.getNewValue().toString()); |
247 | 0 | } else if (evt.getPropertyName().equals(WizardModel.BACK_BUTTON_TEXT_PROPERTY)) { |
248 | 0 | backButton.setText(evt.getNewValue().toString()); |
249 | 0 | } else if (evt.getPropertyName().equals(WizardModel.CANCEL_BUTTON_TEXT_PROPERTY)) { |
250 | 0 | cancelButton.setText(evt.getNewValue().toString()); |
251 | 0 | } else if (evt.getPropertyName().equals(WizardModel.NEXT_FINISH_BUTTON_ENABLED_PROPERTY)) { |
252 | 0 | nextButton.setEnabled(((Boolean)evt.getNewValue()).booleanValue()); |
253 | 0 | } else if (evt.getPropertyName().equals(WizardModel.BACK_BUTTON_ENABLED_PROPERTY)) { |
254 | 0 | backButton.setEnabled(((Boolean)evt.getNewValue()).booleanValue()); |
255 | 0 | } else if (evt.getPropertyName().equals(WizardModel.CANCEL_BUTTON_ENABLED_PROPERTY)) { |
256 | 0 | cancelButton.setEnabled(((Boolean)evt.getNewValue()).booleanValue()); |
257 | 0 | } else if (evt.getPropertyName().equals(WizardModel.NEXT_FINISH_BUTTON_ICON_PROPERTY)) { |
258 | 0 | nextButton.setIcon((Icon)evt.getNewValue()); |
259 | 0 | } else if (evt.getPropertyName().equals(WizardModel.BACK_BUTTON_ICON_PROPERTY)) { |
260 | 0 | backButton.setIcon((Icon)evt.getNewValue()); |
261 | 0 | } else if (evt.getPropertyName().equals(WizardModel.CANCEL_BUTTON_ICON_PROPERTY)) { |
262 | 0 | cancelButton.setIcon((Icon)evt.getNewValue()); |
263 | } |
|
264 | ||
265 | 0 | } |
266 | ||
267 | /** |
|
268 | * Retrieves the last return code set by the dialog. |
|
269 | * @return An integer that identifies how the dialog was closed. See the *_RETURN_CODE |
|
270 | * constants of this class for possible values. |
|
271 | */ |
|
272 | public int getReturnCode() { |
|
273 | 0 | return class="keyword">returnCode; |
274 | } |
|
275 | ||
276 | /** |
|
277 | * Mirrors the WizardModel method of the same name. |
|
278 | * @return A boolean indicating if the button is enabled. |
|
279 | */ |
|
280 | public boolean getBackButtonEnabled() { |
|
281 | 0 | return wizardModel.getBackButtonEnabled().booleanValue(); |
282 | } |
|
283 | ||
284 | /** |
|
285 | * Mirrors the WizardModel method of the same name. |
|
286 | * @param boolean newValue The new enabled status of the button. |
|
287 | */ |
|
288 | public void setBackButtonEnabled(boolean newValue) { |
|
289 | 0 | wizardModel.setBackButtonEnabled(new Boolean(class="keyword">newValue)); |
290 | 0 | } |
291 | ||
292 | /** |
|
293 | * Mirrors the WizardModel method of the same name. |
|
294 | * @return A boolean indicating if the button is enabled. |
|
295 | */ |
|
296 | public boolean getNextFinishButtonEnabled() { |
|
297 | 0 | return wizardModel.getNextFinishButtonEnabled().booleanValue(); |
298 | } |
|
299 | ||
300 | /** |
|
301 | * Mirrors the WizardModel method of the same name. |
|
302 | * @param boolean newValue The new enabled status of the button. |
|
303 | */ |
|
304 | public void setNextFinishButtonEnabled(boolean newValue) { |
|
305 | 0 | wizardModel.setNextFinishButtonEnabled(new Boolean(class="keyword">newValue)); |
306 | 0 | } |
307 | ||
308 | /** |
|
309 | * Mirrors the WizardModel method of the same name. |
|
310 | * @return A boolean indicating if the button is enabled. |
|
311 | */ |
|
312 | public boolean getCancelButtonEnabled() { |
|
313 | 0 | return wizardModel.getCancelButtonEnabled().booleanValue(); |
314 | } |
|
315 | ||
316 | /** |
|
317 | * Mirrors the WizardModel method of the same name. |
|
318 | * @param boolean newValue The new enabled status of the button. |
|
319 | */ |
|
320 | public void setCancelButtonEnabled(boolean newValue) { |
|
321 | 0 | wizardModel.setCancelButtonEnabled(new Boolean(class="keyword">newValue)); |
322 | 0 | } |
323 | ||
324 | /** |
|
325 | * Closes the dialog and sets the return code to the integer parameter. |
|
326 | * @param code The return code. |
|
327 | */ |
|
328 | void close(int code) { |
|
329 | 0 | returnCode = code; |
330 | 0 | wizardDialog.dispose(); |
331 | 0 | } |
332 | ||
333 | /** |
|
334 | * This method initializes the components for the wizard dialog: it creates a JDialog |
|
335 | * as a CardLayout panel surrounded by a small amount of space on each side, as well |
|
336 | * as three buttons at the bottom. |
|
337 | */ |
|
338 | ||
339 | private void initComponents() { |
|
340 | ||
341 | 0 | wizardModel.addPropertyChangeListener(this); |
342 | 0 | wizardController = new WizardController(this); |
343 | ||
344 | 0 | wizardDialog.getContentPane().setLayout(new BorderLayout()); |
345 | 0 | wizardDialog.addWindowListener(this); |
346 | ||
347 | // Create the outer wizard panel, which is responsible for three buttons: |
|
348 | // Next, Back, and Cancel. It is also responsible a JPanel above them that |
|
349 | // uses a CardLayout layout manager to display multiple panels in the |
|
350 | // same spot. |
|
351 | ||
352 | 0 | JPanel buttonPanel = new JPanel(); |
353 | 0 | JSeparator separator = new JSeparator(); |
354 | 0 | Box buttonBox = new Box(BoxLayout.X_AXIS); |
355 | ||
356 | 0 | cardPanel = new JPanel(); |
357 | 0 | cardPanel.setBorder(new EmptyBorder(class="keyword">new Insets(5, 10, 5, 10))); |
358 | ||
359 | 0 | cardLayout = new CardLayout(); |
360 | 0 | cardPanel.setLayout(cardLayout); |
361 | ||
362 | 0 | backButton = new JButton(class="keyword">new ImageIcon("com/nexes/wizard/backIcon.gif")); |
363 | 0 | nextButton = new JButton(); |
364 | 0 | cancelButton = new JButton(); |
365 | ||
366 | 0 | backButton.setActionCommand(BACK_BUTTON_ACTION_COMMAND); |
367 | 0 | nextButton.setActionCommand(NEXT_BUTTON_ACTION_COMMAND); |
368 | 0 | cancelButton.setActionCommand(CANCEL_BUTTON_ACTION_COMMAND); |
369 | ||
370 | 0 | backButton.addActionListener(wizardController); |
371 | 0 | nextButton.addActionListener(wizardController); |
372 | 0 | cancelButton.addActionListener(wizardController); |
373 | ||
374 | // Create the buttons with a separator above them, then place them |
|
375 | // on the east side of the panel with a small amount of space between |
|
376 | // the back and the next button, and a larger amount of space between |
|
377 | // the next button and the cancel button. |
|
378 | ||
379 | 0 | buttonPanel.setLayout(new BorderLayout()); |
380 | 0 | buttonPanel.add(separator, BorderLayout.NORTH); |
381 | ||
382 | 0 | buttonBox.setBorder(new EmptyBorder(class="keyword">new Insets(5, 10, 5, 10))); |
383 | 0 | buttonBox.add(backButton); |
384 | 0 | buttonBox.add(Box.createHorizontalStrut(10)); |
385 | 0 | buttonBox.add(nextButton); |
386 | 0 | buttonBox.add(Box.createHorizontalStrut(30)); |
387 | 0 | buttonBox.add(cancelButton); |
388 | ||
389 | 0 | buttonPanel.add(buttonBox, java.awt.BorderLayout.EAST); |
390 | ||
391 | 0 | wizardDialog.getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH); |
392 | 0 | wizardDialog.getContentPane().add(cardPanel, java.awt.BorderLayout.CENTER); |
393 | ||
394 | 0 | } |
395 | ||
396 | private static Object getImage(String name) { |
|
397 | ||
398 | 0 | URL url = null; |
399 | ||
400 | try { |
|
401 | 0 | Class c = Class.forName("com.nexes.wizard.Wizard"); |
402 | 0 | url = c.getResource(name); |
403 | 0 | } catch (ClassNotFoundException cnfe) { |
404 | 0 | System.err.println("Unable to find Wizard class"); |
405 | 0 | } |
406 | 0 | return url; |
407 | ||
408 | } |
|
409 | ||
410 | /** |
|
411 | * If the user presses the close box on the dialog's window, treat it |
|
412 | * as a cancel. |
|
413 | * @param WindowEvent The event passed in from AWT. |
|
414 | */ |
|
415 | ||
416 | public void windowClosing(WindowEvent e) { |
|
417 | 0 | returnCode = CANCEL_RETURN_CODE; |
418 | 0 | } |
419 | ||
420 | ||
421 | ||
422 | static { |
|
423 | ||
424 | try { |
|
425 | ||
426 | 0 | PropertyResourceBundle resources = (PropertyResourceBundle) |
427 | ResourceBundle.getBundle("com.nexes.wizard.wizard"); |
|
428 | ||
429 | 0 | BACK_TEXT = (String)(resources.getObject("backButtonText")); |
430 | 0 | NEXT_TEXT = (String)(resources.getObject("nextButtonText")); |
431 | 0 | CANCEL_TEXT = (String)(resources.getObject("cancelButtonText")); |
432 | 0 | FINISH_TEXT = (String)(resources.getObject("finishButtonText")); |
433 | ||
434 | 0 | BACK_ICON = new ImageIcon((URL)getImage((String)(resources.getObject("backButtonIcon")))); |
435 | 0 | NEXT_ICON = new ImageIcon((URL)getImage((String)(resources.getObject("nextButtonIcon")))); |
436 | 0 | CANCEL_ICON = new ImageIcon((URL)getImage((String)(resources.getObject("cancelButtonIcon")))); |
437 | 0 | FINISH_ICON = new ImageIcon((URL)getImage((String)(resources.getObject("finishButtonIcon")))); |
438 | ||
439 | 0 | } catch (MissingResourceException mre) { |
440 | 0 | System.out.println(mre); |
441 | 0 | System.exit(1); |
442 | 0 | } |
443 | 0 | } |
444 | ||
445 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |