|
@@ -24,7 +24,7 @@ package com.dmdirc.ui.swing.dialogs.wizard;
|
24
|
24
|
|
25
|
25
|
import static com.dmdirc.ui.swing.UIUtilities.SMALL_BORDER;
|
26
|
26
|
import com.dmdirc.ui.swing.components.StandardDialog;
|
27
|
|
-
|
|
27
|
+import com.dmdirc.util.ListenerList;
|
28
|
28
|
import java.awt.BorderLayout;
|
29
|
29
|
import java.awt.Color;
|
30
|
30
|
import java.awt.Component;
|
|
@@ -38,9 +38,7 @@ import java.awt.Rectangle;
|
38
|
38
|
import java.awt.event.ActionEvent;
|
39
|
39
|
import java.awt.event.ActionListener;
|
40
|
40
|
import java.io.Serializable;
|
41
|
|
-import java.util.ArrayList;
|
42
|
41
|
import java.util.List;
|
43
|
|
-
|
44
|
42
|
import javax.swing.BorderFactory;
|
45
|
43
|
import javax.swing.Box;
|
46
|
44
|
import javax.swing.BoxLayout;
|
|
@@ -55,24 +53,23 @@ import javax.swing.JSeparator;
|
55
|
53
|
*/
|
56
|
54
|
public final class WizardDialog extends StandardDialog implements ActionListener,
|
57
|
55
|
Serializable {
|
58
|
|
-
|
|
56
|
+
|
59
|
57
|
/**
|
60
|
58
|
* A version number for this class. It should be changed whenever the class
|
61
|
59
|
* structure is changed (or anything else that would prevent serialized
|
62
|
60
|
* objects being unserialized with the new class).
|
63
|
61
|
*/
|
64
|
|
- private static final long serialVersionUID = 1;
|
65
|
|
-
|
|
62
|
+ private static final long serialVersionUID = 2;
|
66
|
63
|
/** Step panel list. */
|
67
|
|
- private final List<Step> steps;
|
|
64
|
+ private final StepLayout steps;
|
68
|
65
|
/** Wizard title. */
|
69
|
66
|
private final String title;
|
70
|
67
|
/** Wizard. */
|
71
|
68
|
private final transient Wizard wizard;
|
72
|
|
-
|
73
|
69
|
/** Parent component. */
|
74
|
70
|
private final Component parent;
|
75
|
|
-
|
|
71
|
+ /** Step panel. */
|
|
72
|
+ private JPanel stepsPanel;
|
76
|
73
|
/** Button panel. */
|
77
|
74
|
private JPanel buttonsPanel;
|
78
|
75
|
/** Title panel. */
|
|
@@ -85,7 +82,9 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
85
|
82
|
private JButton next;
|
86
|
83
|
/** Progress label. */
|
87
|
84
|
private JLabel progressLabel;
|
88
|
|
-
|
|
85
|
+ /** Step Listeners. */
|
|
86
|
+ private ListenerList stepListeners;
|
|
87
|
+
|
89
|
88
|
/**
|
90
|
89
|
* Creates a new instance of WizardFrame that requires a mainframe.
|
91
|
90
|
*
|
|
@@ -95,125 +94,139 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
95
|
94
|
* @param modal Whether the wizard should be modal
|
96
|
95
|
* @param parent Parent component
|
97
|
96
|
*/
|
98
|
|
- public WizardDialog(final String title, final List<Step> steps,
|
99
|
|
- final Wizard wizard, final boolean modal, final Component parent) {
|
|
97
|
+ public WizardDialog(final String title,
|
|
98
|
+ final List<Step> steps,
|
|
99
|
+ final Wizard wizard, final boolean modal,
|
|
100
|
+ final Component parent) {
|
100
|
101
|
super(null, modal);
|
101
|
|
-
|
|
102
|
+
|
|
103
|
+ stepListeners = new ListenerList();
|
|
104
|
+
|
102
|
105
|
this.title = title;
|
103
|
|
- this.steps = new ArrayList<Step>(steps);
|
|
106
|
+ this.steps = new StepLayout();
|
104
|
107
|
this.wizard = wizard;
|
105
|
108
|
this.parent = parent;
|
106
|
|
-
|
|
109
|
+
|
107
|
110
|
initComponents();
|
108
|
111
|
layoutComponents();
|
|
112
|
+
|
|
113
|
+ for (Step step : steps) {
|
|
114
|
+ addStep(step);
|
|
115
|
+ }
|
109
|
116
|
}
|
110
|
|
-
|
|
117
|
+
|
111
|
118
|
/** Initialises the components. */
|
112
|
119
|
private void initComponents() {
|
113
|
120
|
final JLabel titleLabel = new JLabel(title);
|
114
|
|
-
|
|
121
|
+
|
115
|
122
|
titlePanel = new JPanel();
|
116
|
123
|
titlePanel.setLayout(new BorderLayout());
|
117
|
124
|
titlePanel.setBackground(Color.WHITE);
|
118
|
|
-
|
119
|
|
- titleLabel.setFont(titleLabel.getFont().deriveFont(
|
120
|
|
- (float) (titleLabel.getFont().getSize() * 1.5)));
|
|
125
|
+ stepsPanel = new JPanel(steps);
|
|
126
|
+
|
|
127
|
+ titleLabel.setFont(titleLabel.getFont().
|
|
128
|
+ deriveFont((float) (titleLabel.getFont().getSize() * 1.5)));
|
121
|
129
|
titleLabel.setBorder(BorderFactory.createEmptyBorder(SMALL_BORDER,
|
122
|
130
|
SMALL_BORDER, SMALL_BORDER, SMALL_BORDER));
|
123
|
|
-
|
|
131
|
+
|
124
|
132
|
titlePanel.add(titleLabel, BorderLayout.CENTER);
|
125
|
133
|
titlePanel.add(new JSeparator(), BorderLayout.PAGE_END);
|
126
|
|
-
|
|
134
|
+
|
127
|
135
|
initButtonsPanel();
|
128
|
136
|
}
|
129
|
|
-
|
|
137
|
+
|
130
|
138
|
/** Lays out the components. */
|
131
|
139
|
private void layoutComponents() {
|
132
|
|
- this.setLayout(new BorderLayout());
|
133
|
|
-
|
134
|
|
-
|
135
|
|
- this.add(titlePanel, BorderLayout.PAGE_START);
|
136
|
|
- this.add(buttonsPanel, BorderLayout.PAGE_END);
|
|
140
|
+ setLayout(new BorderLayout());
|
|
141
|
+
|
|
142
|
+ add(titlePanel, BorderLayout.PAGE_START);
|
|
143
|
+ add(stepsPanel, BorderLayout.CENTER);
|
|
144
|
+ add(buttonsPanel, BorderLayout.PAGE_END);
|
137
|
145
|
}
|
138
|
|
-
|
|
146
|
+
|
139
|
147
|
/** Initialises the button panel. */
|
140
|
148
|
private void initButtonsPanel() {
|
141
|
149
|
final JPanel buttonPanel = new JPanel();
|
142
|
150
|
buttonsPanel = new JPanel();
|
143
|
151
|
progressLabel = new JLabel();
|
144
|
|
-
|
|
152
|
+
|
145
|
153
|
orderButtons(new JButton(), new JButton());
|
146
|
154
|
next = new JButton();
|
147
|
155
|
setOkButton(next);
|
148
|
|
-
|
|
156
|
+
|
149
|
157
|
prev = new JButton("<< Previous");
|
150
|
158
|
next.setText("Next >>");
|
151
|
|
-
|
|
159
|
+
|
152
|
160
|
prev.setPreferredSize(new Dimension(110, 30));
|
153
|
161
|
next.setPreferredSize(new Dimension(110, 30));
|
154
|
|
-
|
|
162
|
+
|
155
|
163
|
prev.setMargin(new Insets(prev.getMargin().top, 0,
|
156
|
164
|
prev.getMargin().bottom, 0));
|
157
|
165
|
next.setMargin(new Insets(next.getMargin().top, 0,
|
158
|
166
|
next.getMargin().bottom, 0));
|
159
|
|
-
|
|
167
|
+
|
160
|
168
|
getCancelButton().addActionListener(this);
|
161
|
169
|
prev.addActionListener(this);
|
162
|
170
|
next.addActionListener(this);
|
163
|
|
-
|
|
171
|
+
|
164
|
172
|
buttonPanel.setBorder(BorderFactory.createEmptyBorder(SMALL_BORDER,
|
165
|
173
|
SMALL_BORDER, SMALL_BORDER, SMALL_BORDER));
|
166
|
|
-
|
167
|
|
- buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
|
174
|
+
|
|
175
|
+ buttonPanel.setLayout(new BoxLayout(buttonPanel,
|
|
176
|
+ BoxLayout.LINE_AXIS));
|
168
|
177
|
buttonPanel.add(progressLabel);
|
169
|
178
|
buttonPanel.add(Box.createHorizontalStrut(SMALL_BORDER));
|
170
|
179
|
buttonPanel.add(Box.createHorizontalGlue());
|
171
|
180
|
buttonPanel.add(prev);
|
172
|
181
|
buttonPanel.add(Box.createHorizontalStrut(SMALL_BORDER));
|
173
|
182
|
buttonPanel.add(next);
|
174
|
|
-
|
|
183
|
+
|
175
|
184
|
buttonsPanel.setLayout(new BorderLayout());
|
176
|
|
-
|
|
185
|
+
|
177
|
186
|
buttonsPanel.add(new JSeparator(), BorderLayout.PAGE_START);
|
178
|
187
|
buttonsPanel.add(buttonPanel, BorderLayout.CENTER);
|
179
|
188
|
}
|
180
|
|
-
|
|
189
|
+
|
181
|
190
|
/** Displays the wizard. */
|
182
|
191
|
public void display() {
|
183
|
192
|
if (!steps.isEmpty()) {
|
184
|
|
-
|
185
|
|
- add(steps.get(0), BorderLayout.CENTER);
|
|
193
|
+ steps.first(stepsPanel);
|
186
|
194
|
currentStep = 0;
|
187
|
|
-
|
|
195
|
+
|
188
|
196
|
prev.setEnabled(false);
|
189
|
197
|
if (steps.size() == 1) {
|
190
|
198
|
next.setText("Finish");
|
191
|
199
|
}
|
192
|
|
-
|
|
200
|
+
|
193
|
201
|
updateProgressLabel();
|
194
|
|
-
|
|
202
|
+
|
195
|
203
|
setTitle(title);
|
196
|
204
|
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
197
|
205
|
pack();
|
198
|
|
- if (parent == null) {
|
|
206
|
+ if (parent != null) {
|
199
|
207
|
setLocationRelativeTo(parent);
|
200
|
208
|
} else {
|
201
|
209
|
// Position wizard center-screen on the correct monitor of a
|
202
|
210
|
// multi-monitor system. (See MainFrame constructor for more info)
|
203
|
|
- final PointerInfo myPointerInfo = MouseInfo.getPointerInfo();
|
|
211
|
+ final PointerInfo myPointerInfo =
|
|
212
|
+ MouseInfo.getPointerInfo();
|
204
|
213
|
final GraphicsDevice myDevice = myPointerInfo.getDevice();
|
205
|
|
- final GraphicsConfiguration myGraphicsConfig = myDevice.getDefaultConfiguration();
|
|
214
|
+ final GraphicsConfiguration myGraphicsConfig =
|
|
215
|
+ myDevice.getDefaultConfiguration();
|
206
|
216
|
final Rectangle gcBounds = myGraphicsConfig.getBounds();
|
207
|
|
- final int xPos = gcBounds.x + ((gcBounds.width - getWidth()) / 2);
|
208
|
|
- final int yPos = gcBounds.y + ((gcBounds.height - getHeight()) / 2);
|
|
217
|
+ final int xPos =
|
|
218
|
+ gcBounds.x + ((gcBounds.width - getWidth()) / 2);
|
|
219
|
+ final int yPos =
|
|
220
|
+ gcBounds.y + ((gcBounds.height - getHeight()) / 2);
|
209
|
221
|
setLocation(xPos, yPos);
|
210
|
222
|
}
|
211
|
223
|
setResizable(false);
|
212
|
224
|
setVisible(true);
|
213
|
225
|
}
|
214
|
226
|
}
|
215
|
|
-
|
|
227
|
+
|
216
|
228
|
/** {@inheritDoc} */
|
|
229
|
+ @Override
|
217
|
230
|
public void actionPerformed(final ActionEvent e) {
|
218
|
231
|
if (e.getSource() == next) {
|
219
|
232
|
nextStep();
|
|
@@ -223,16 +236,16 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
223
|
236
|
wizard.wizardCancelled();
|
224
|
237
|
}
|
225
|
238
|
}
|
226
|
|
-
|
|
239
|
+
|
227
|
240
|
/**
|
228
|
241
|
* Adds a step to the wizard.
|
229
|
242
|
*
|
230
|
243
|
* @param step Step to add
|
231
|
244
|
*/
|
232
|
245
|
public void addStep(final Step step) {
|
233
|
|
- steps.add(step);
|
|
246
|
+ stepsPanel.add(step, step.toString());
|
234
|
247
|
}
|
235
|
|
-
|
|
248
|
+
|
236
|
249
|
/**
|
237
|
250
|
* Enables or disables the "next step" button.
|
238
|
251
|
*
|
|
@@ -241,7 +254,7 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
241
|
254
|
public void enableNextStep(final boolean newValue) {
|
242
|
255
|
next.setEnabled(newValue);
|
243
|
256
|
}
|
244
|
|
-
|
|
257
|
+
|
245
|
258
|
/**
|
246
|
259
|
* Enables or disables the "previous step" button.
|
247
|
260
|
*
|
|
@@ -250,13 +263,14 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
250
|
263
|
public void enablePreviousStep(final boolean newValue) {
|
251
|
264
|
prev.setEnabled(newValue);
|
252
|
265
|
}
|
253
|
|
-
|
|
266
|
+
|
254
|
267
|
/** Moves to the next step. */
|
255
|
268
|
private void nextStep() {
|
256
|
|
- steps.get(currentStep).setVisible(false);
|
257
|
269
|
if ("Next >>".equals(next.getText())) {
|
258
|
|
- remove(steps.get(currentStep));
|
259
|
|
- add(steps.get(++currentStep), BorderLayout.CENTER);
|
|
270
|
+ fireStepAboutToBeDisplayed(steps.getStep(currentStep + 1));
|
|
271
|
+ steps.next(stepsPanel);
|
|
272
|
+ fireStepHidden(steps.getStep(currentStep));
|
|
273
|
+ currentStep++;
|
260
|
274
|
prev.setEnabled(true);
|
261
|
275
|
if (currentStep == steps.size() - 1) {
|
262
|
276
|
next.setText("Finish");
|
|
@@ -264,30 +278,25 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
264
|
278
|
updateProgressLabel();
|
265
|
279
|
wizard.stepChanged(currentStep - 1, currentStep);
|
266
|
280
|
} else if ("Finish".equals(next.getText())) {
|
267
|
|
- this.dispose();
|
|
281
|
+ dispose();
|
268
|
282
|
wizard.wizardFinished();
|
269
|
283
|
}
|
270
|
|
- final Step newstep = steps.get(currentStep);
|
271
|
|
- if (newstep instanceof SpecialStep) {
|
272
|
|
- ((SpecialStep) newstep).showStep();
|
273
|
|
- }
|
274
|
|
- newstep.setVisible(true);
|
275
|
284
|
}
|
276
|
|
-
|
|
285
|
+
|
277
|
286
|
/** Moves to the previous step. */
|
278
|
287
|
private void prevStep() {
|
279
|
|
- steps.get(currentStep).setVisible(false);
|
280
|
|
- remove(steps.get(currentStep));
|
281
|
|
- add(steps.get(--currentStep), BorderLayout.CENTER);
|
|
288
|
+ fireStepAboutToBeDisplayed(steps.getStep(currentStep - 1));
|
|
289
|
+ steps.previous(stepsPanel);
|
|
290
|
+ fireStepHidden(steps.getStep(currentStep));
|
|
291
|
+ currentStep--;
|
282
|
292
|
if (currentStep == 0) {
|
283
|
293
|
prev.setEnabled(false);
|
284
|
294
|
}
|
285
|
295
|
next.setText("Next >>");
|
286
|
|
- steps.get(currentStep).setVisible(true);
|
287
|
296
|
updateProgressLabel();
|
288
|
297
|
wizard.stepChanged(currentStep + 1, currentStep);
|
289
|
298
|
}
|
290
|
|
-
|
|
299
|
+
|
291
|
300
|
/**
|
292
|
301
|
* Returns the step at the specified index.
|
293
|
302
|
*
|
|
@@ -296,9 +305,9 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
296
|
305
|
* @return Specified step.
|
297
|
306
|
*/
|
298
|
307
|
public Step getStep(final int stepNumber) {
|
299
|
|
- return steps.get(stepNumber);
|
|
308
|
+ return steps.getStep(stepNumber);
|
300
|
309
|
}
|
301
|
|
-
|
|
310
|
+
|
302
|
311
|
/**
|
303
|
312
|
* Returns the current step.
|
304
|
313
|
*
|
|
@@ -307,9 +316,53 @@ public final class WizardDialog extends StandardDialog implements ActionListener
|
307
|
316
|
public int getCurrentStep() {
|
308
|
317
|
return currentStep;
|
309
|
318
|
}
|
310
|
|
-
|
|
319
|
+
|
311
|
320
|
/** Updates the progress label. */
|
312
|
321
|
private void updateProgressLabel() {
|
313
|
322
|
progressLabel.setText("Step " + (currentStep + 1) + " of " + steps.size());
|
314
|
|
- }
|
315
|
|
-}
|
|
323
|
+ }
|
|
324
|
+
|
|
325
|
+ /**
|
|
326
|
+ * Adds a step listener to the list.
|
|
327
|
+ *
|
|
328
|
+ * @param listener
|
|
329
|
+ */
|
|
330
|
+ public void addStepListener(final StepListener listener) {
|
|
331
|
+ stepListeners.add(StepListener.class, listener);
|
|
332
|
+ }
|
|
333
|
+
|
|
334
|
+ /**
|
|
335
|
+ * Removes a step listener from the list.
|
|
336
|
+ *
|
|
337
|
+ * @param listener
|
|
338
|
+ */
|
|
339
|
+ public void removeStepListener(final StepListener listener) {
|
|
340
|
+ stepListeners.remove(StepListener.class, listener);
|
|
341
|
+ }
|
|
342
|
+
|
|
343
|
+ /**
|
|
344
|
+ * Fires step about to be displayed events.
|
|
345
|
+ *
|
|
346
|
+ * @param step Step to be displayed
|
|
347
|
+ */
|
|
348
|
+ private void fireStepAboutToBeDisplayed(final Step step) {
|
|
349
|
+ List<StepListener> listeners =
|
|
350
|
+ stepListeners.get(StepListener.class);
|
|
351
|
+ for (StepListener listener : listeners) {
|
|
352
|
+ listener.stepAboutToDisplay(step);
|
|
353
|
+ }
|
|
354
|
+ }
|
|
355
|
+
|
|
356
|
+ /**
|
|
357
|
+ * Fires step hidden events.
|
|
358
|
+ *
|
|
359
|
+ * @param step step thats been hidden
|
|
360
|
+ */
|
|
361
|
+ private void fireStepHidden(final Step step) {
|
|
362
|
+ List<StepListener> listeners =
|
|
363
|
+ stepListeners.get(StepListener.class);
|
|
364
|
+ for (StepListener listener : listeners) {
|
|
365
|
+ listener.stepHidden(step);
|
|
366
|
+ }
|
|
367
|
+ }
|
|
368
|
+}
|