View Javadoc
1   package com.github.sbugat.rundeckmonitor.wizard;
2   
3   import java.awt.BorderLayout;
4   import java.awt.CardLayout;
5   import java.awt.Insets;
6   import java.awt.event.ActionEvent;
7   import java.awt.event.ActionListener;
8   import java.util.HashMap;
9   import java.util.Map;
10  
11  import javax.swing.Box;
12  import javax.swing.BoxLayout;
13  import javax.swing.JButton;
14  import javax.swing.JFrame;
15  import javax.swing.JPanel;
16  import javax.swing.JSeparator;
17  import javax.swing.border.EmptyBorder;
18  
19  import com.github.sbugat.rundeckmonitor.configuration.RundeckMonitorConfiguration;
20  import com.github.sbugat.rundeckmonitor.tools.SystemTools;
21  
22  /**
23   * Class of the configuration Wizard.
24   * 
25   * @author Sylvain Bugat
26   * 
27   */
28  public final class RundeckMonitorConfigurationWizard {
29  
30  	/** Configuration wizard frame title. */
31  	private static final String WIZARD_FRAME_TITLE = "RundeckMonitor configuration wizard"; //$NON-NLS-1$
32  
33  	/** Back button label. */
34  	private static final String BACK_BUTTON_LABEL = "Back"; //$NON-NLS-1$
35  	/** Cancel button label. */
36  	private static final String CANCEL_BUTTON_LABEL = "Cancel"; //$NON-NLS-1$
37  	/** Finish button label. */
38  	private static final String FINISH_BUTTON_LABEL = "Finish"; //$NON-NLS-1$
39  	/** Next button label. */
40  	private static final String NEXT_BUTTON_LABEL = "Next"; //$NON-NLS-1$
41  
42  	/** Wizard steps maps. */
43  	private final Map<ConfigurationWizardStep, WizardPanelDescriptor> map = new HashMap<>();
44  	/** Current wizard step. */
45  	private ConfigurationWizardStep currentStep;
46  
47  	/** Configuration wizard main frame. */
48  	private final JFrame wizardFrame;
49  
50  	/** Wizard main panel. */
51  	private JPanel cardPanel;
52  	/** Wizard main card layout for steps. */
53  	private CardLayout cardLayout;
54  
55  	/** Back/previous step button of the wizard. */
56  	private JButton backButton;
57  	/** Next step button of the wizard. */
58  	private JButton nextButton;
59  
60  	/**
61  	 * Initialize a new configuration wizard.
62  	 * 
63  	 * @param rundeckMonitorConfiguration RunDeck monitor configuration
64  	 * @param exitOnClose indicate if the program must exit if the wizard is closed
65  	 */
66  	public RundeckMonitorConfigurationWizard(final RundeckMonitorConfiguration rundeckMonitorConfiguration, final boolean exitOnClose) {
67  
68  		wizardFrame = new JFrame();
69  		wizardFrame.setTitle(WIZARD_FRAME_TITLE);
70  
71  		if (exitOnClose) {
72  			wizardFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
73  		}
74  		else {
75  			wizardFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
76  		}
77  
78  		// Initialize displayed components
79  		initComponents(exitOnClose);
80  
81  		// Initialize steps and set the first step
82  		final WizardPanelDescriptor wpd1 = new RundeckConfigurationWizardPanelDescriptor(null, ConfigurationWizardStep.PROJECT_STEP, rundeckMonitorConfiguration);
83  		final WizardPanelDescriptor wpd2 = new ProjectConfigurationWizardPanelDescriptor(ConfigurationWizardStep.RUNDECK_STEP, ConfigurationWizardStep.MONITOR_STEP, rundeckMonitorConfiguration);
84  		final WizardPanelDescriptor wpd3 = new MonitorConfigurationWizardPanelDescriptor(ConfigurationWizardStep.PROJECT_STEP, null, rundeckMonitorConfiguration);
85  
86  		registerWizardPanel(wpd1);
87  		registerWizardPanel(wpd2);
88  		registerWizardPanel(wpd3);
89  		setCurrentPanel(ConfigurationWizardStep.RUNDECK_STEP, false);
90  
91  		// Resize the frame
92  		wizardFrame.pack();
93  		wizardFrame.setResizable(false);
94  		// Center the frame on the screen
95  		wizardFrame.setLocationRelativeTo(null);
96  
97  		// Display the frame
98  		wizardFrame.setVisible(true);
99  	}
100 
101 	/**
102 	 * Initialize the main card panel and listeners.
103 	 * 
104 	 * @param exitOnClose indicate if Cancel/close the wizard will exit
105 	 */
106 	private void initComponents(final boolean exitOnClose) {
107 
108 		final JPanel buttonPanel = new JPanel();
109 		final Box buttonBox = new Box(BoxLayout.X_AXIS);
110 
111 		cardPanel = new JPanel();
112 		cardPanel.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));
113 
114 		cardLayout = new CardLayout();
115 		cardPanel.setLayout(cardLayout);
116 		backButton = new JButton(BACK_BUTTON_LABEL);
117 		nextButton = new JButton(NEXT_BUTTON_LABEL);
118 		final JButton cancelButton = new JButton(CANCEL_BUTTON_LABEL);
119 
120 		final ActionListener backListener = new ActionListener() {
121 
122 			@Override
123 			@SuppressWarnings("synthetic-access")
124 			public void actionPerformed(final ActionEvent e) {
125 				final ConfigurationWizardStep dest = map.get(currentStep).getBack();
126 				setCurrentPanel(dest, false);
127 			}
128 		};
129 		final ActionListener nextListener = new ActionListener() {
130 
131 			@Override
132 			@SuppressWarnings("synthetic-access")
133 			public void actionPerformed(final ActionEvent e) {
134 				final ConfigurationWizardStep dest = map.get(currentStep).getNext();
135 
136 				if (null == dest) {
137 
138 					final WizardPanelDescriptor oldPanelDescriptor = map.get(currentStep);
139 
140 					// Write configuration
141 					oldPanelDescriptor.validate();
142 
143 					wizardFrame.setVisible(false);
144 					wizardFrame.dispose();
145 				}
146 				else {
147 					setCurrentPanel(dest, true);
148 				}
149 			}
150 		};
151 		final ActionListener cancelListener = new ActionListener() {
152 
153 			@Override
154 			@SuppressWarnings("synthetic-access")
155 			public void actionPerformed(final ActionEvent e) {
156 
157 				if (exitOnClose) {
158 					SystemTools.exit(SystemTools.EXIT_CODE_OK);
159 				}
160 				else {
161 					wizardFrame.setVisible(false);
162 					wizardFrame.dispose();
163 				}
164 			}
165 		};
166 
167 		backButton.addActionListener(backListener);
168 		nextButton.addActionListener(nextListener);
169 		cancelButton.addActionListener(cancelListener);
170 
171 		buttonPanel.setLayout(new BorderLayout());
172 		buttonPanel.add(new JSeparator(), BorderLayout.NORTH);
173 
174 		buttonBox.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));
175 		buttonBox.add(backButton);
176 		buttonBox.add(Box.createHorizontalStrut(10));
177 		buttonBox.add(nextButton);
178 		buttonBox.add(Box.createHorizontalStrut(30));
179 		buttonBox.add(cancelButton);
180 		buttonPanel.add(buttonBox, BorderLayout.EAST);
181 		wizardFrame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
182 		wizardFrame.getContentPane().add(cardPanel, BorderLayout.CENTER);
183 	}
184 
185 	/**
186 	 * Add a new wizard panel to the wizard.
187 	 * 
188 	 * @param panel panel to add
189 	 */
190 	public void registerWizardPanel(final WizardPanelDescriptor panel) {
191 		cardPanel.add(panel.getPanelComponent(), panel.getPanelDescriptorIdentifier().toString());
192 		map.put(panel.getPanelDescriptorIdentifier(), panel);
193 	}
194 
195 	/**
196 	 * Change the current panel to a new one with validation of the current if needed.
197 	 * 
198 	 * @param id identifier or the targeted Wizard step
199 	 * @param next indicate if it's a next step
200 	 */
201 	public void setCurrentPanel(final ConfigurationWizardStep id, final boolean next) {
202 
203 		// If going to the next panel, validate it and don't advance if validation failed
204 		if (next && currentStep != null && !map.get(currentStep).validate()) {
205 			return;
206 		}
207 
208 		currentStep = id;
209 
210 		map.get(id).aboutToDisplayPanel();
211 
212 		if (null == map.get(id).getNext()) {
213 			nextButton.setText(FINISH_BUTTON_LABEL);
214 		}
215 		else {
216 			nextButton.setText(NEXT_BUTTON_LABEL);
217 		}
218 
219 		backButton.setVisible(null != map.get(id).getBack());
220 
221 		cardLayout.show(cardPanel, id.toString());
222 	}
223 }