Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

WizardPanel.java 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * Copyright (c) 2006-2017 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  5. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  7. * permit persons to whom the Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
  10. * Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
  14. * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  15. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. */
  17. package com.dmdirc.addons.ui_swing.wizard;
  18. import com.dmdirc.addons.ui_swing.UIUtilities;
  19. import com.dmdirc.addons.ui_swing.components.EtchedLineBorder;
  20. import com.dmdirc.addons.ui_swing.components.EtchedLineBorder.BorderSide;
  21. import com.dmdirc.addons.ui_swing.components.TitlePanel;
  22. import com.dmdirc.addons.ui_swing.components.XScrollablePanel;
  23. import com.dmdirc.util.collections.ListenerList;
  24. import java.awt.Color;
  25. import java.awt.event.ActionEvent;
  26. import java.awt.event.ActionListener;
  27. import java.util.ArrayList;
  28. import java.util.List;
  29. import javax.swing.BorderFactory;
  30. import javax.swing.JButton;
  31. import javax.swing.JLabel;
  32. import javax.swing.JPanel;
  33. import javax.swing.JScrollPane;
  34. import javax.swing.border.EtchedBorder;
  35. import net.miginfocom.swing.MigLayout;
  36. /**
  37. * Wizard panel.
  38. */
  39. public class WizardPanel extends JPanel implements ActionListener {
  40. /** Serial version UID. */
  41. private static final long serialVersionUID = 2;
  42. /** Wizard title. */
  43. private final String title;
  44. /** Step Listeners. */
  45. private final ListenerList stepListeners;
  46. /** List of steps. */
  47. private final List<Step> steps;
  48. /** Step scroll pane. */
  49. private JScrollPane sp;
  50. /** Step panel. */
  51. private JPanel stepsPanel;
  52. /** Title panel. */
  53. private TitlePanel titleLabel;
  54. /** Current step. */
  55. private int currentStep;
  56. /** Previous step button. */
  57. private JButton prev;
  58. /** Next step button. */
  59. private JButton next;
  60. /** Progress label. */
  61. private JLabel progressLabel;
  62. /**
  63. * Creates a new instance of WizardPanel.
  64. *
  65. * @param title Title for the wizard
  66. * @param steps Steps for the wizard
  67. */
  68. public WizardPanel(final String title, final List<Step> steps) {
  69. stepListeners = new ListenerList();
  70. this.steps = new ArrayList<>(steps);
  71. this.title = title;
  72. initComponents();
  73. layoutComponents();
  74. steps.forEach(this::addStep);
  75. }
  76. /** Initialises the components. */
  77. private void initComponents() {
  78. titleLabel = new TitlePanel(new EtchedLineBorder(EtchedBorder.LOWERED,
  79. BorderSide.BOTTOM), title);
  80. stepsPanel = new XScrollablePanel(new MigLayout("fillx"));
  81. sp = new JScrollPane(stepsPanel);
  82. progressLabel = new JLabel();
  83. next = new JButton();
  84. prev = new JButton("\u00AB Previous");
  85. next.setText("Next \u00BB");
  86. next.addActionListener(this);
  87. prev.addActionListener(this);
  88. }
  89. /** Lays out the components. */
  90. private void layoutComponents() {
  91. final JPanel progressPanel = new JPanel(new MigLayout("fill"));
  92. progressPanel.add(progressLabel, "growx, pushx");
  93. progressPanel.add(prev, "sg button");
  94. progressPanel.add(next, "sg button");
  95. progressPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,
  96. Color.BLACK));
  97. progressPanel.setBorder(new EtchedLineBorder(EtchedBorder.LOWERED,
  98. BorderSide.TOP));
  99. setLayout(new MigLayout("fill, wrap 1, ins 0"));
  100. add(titleLabel, "growx, pushx");
  101. add(sp, "grow, push");
  102. add(progressPanel, "growx, pushx");
  103. }
  104. /** Displays the wizard. */
  105. public void display() {
  106. if (!steps.isEmpty()) {
  107. stepsPanel.removeAll();
  108. stepsPanel.add(steps.get(0));
  109. currentStep = 0;
  110. titleLabel.setText(steps.get(currentStep).getTitle());
  111. UIUtilities.resetScrollPane(sp);
  112. prev.setEnabled(false);
  113. if (steps.size() == 1) {
  114. next.setText("Finish");
  115. }
  116. updateProgressLabel();
  117. }
  118. }
  119. @Override
  120. public void actionPerformed(final ActionEvent e) {
  121. if (e.getSource() == next) {
  122. nextStep();
  123. } else if (e.getSource() == prev) {
  124. prevStep();
  125. }
  126. }
  127. /**
  128. * Adds a step to the wizard.
  129. *
  130. * @param step Step to add
  131. */
  132. public void addStep(final Step step) {
  133. steps.add(step);
  134. }
  135. /**
  136. * Enables or disables the "next step" button.
  137. *
  138. * @param newValue boolean true to make "next" button enabled, else false
  139. */
  140. public void enableNextStep(final boolean newValue) {
  141. next.setEnabled(newValue);
  142. }
  143. /**
  144. * Enables or disables the "previous step" button.
  145. *
  146. * @param newValue boolean true to make "previous" button enabled, else false
  147. */
  148. public void enablePreviousStep(final boolean newValue) {
  149. prev.setEnabled(newValue);
  150. }
  151. /** Moves to the next step. */
  152. protected void nextStep() {
  153. switch (next.getText()) {
  154. case "Next \u00BB":
  155. prev.setEnabled(true);
  156. fireStepAboutToBeDisplayed(steps.get(currentStep + 1));
  157. stepsPanel.setVisible(false);
  158. stepsPanel.removeAll();
  159. stepsPanel.add(steps.get(currentStep + 1));
  160. stepsPanel.setVisible(true);
  161. fireStepHidden(steps.get(currentStep));
  162. currentStep++;
  163. if (currentStep == steps.size() - 1) {
  164. next.setText("Finish");
  165. }
  166. titleLabel.setText(steps.get(currentStep).getTitle());
  167. updateProgressLabel();
  168. break;
  169. case "Finish":
  170. fireWizardFinished();
  171. break;
  172. }
  173. }
  174. /** Moves to the previous step. */
  175. protected void prevStep() {
  176. fireStepAboutToBeDisplayed(steps.get(currentStep - 1));
  177. stepsPanel.setVisible(false);
  178. stepsPanel.removeAll();
  179. stepsPanel.add(steps.get(currentStep - 1));
  180. stepsPanel.setVisible(true);
  181. fireStepHidden(steps.get(currentStep));
  182. currentStep--;
  183. if (currentStep == 0) {
  184. prev.setEnabled(false);
  185. }
  186. next.setText("Next \u00BB");
  187. titleLabel.setText(steps.get(currentStep).getTitle());
  188. updateProgressLabel();
  189. }
  190. /**
  191. * Returns the step at the specified index.
  192. *
  193. * @param stepNumber step number
  194. *
  195. * @return Specified step.
  196. */
  197. public Step getStep(final int stepNumber) {
  198. return steps.get(stepNumber);
  199. }
  200. /**
  201. * Returns the current step.
  202. *
  203. * @return Current step number
  204. */
  205. public int getCurrentStep() {
  206. return currentStep;
  207. }
  208. /** Updates the progress label. */
  209. private void updateProgressLabel() {
  210. progressLabel.setText("Step " + (currentStep + 1) + " of "
  211. + steps.size());
  212. }
  213. /**
  214. * Adds a step listener to the list.
  215. *
  216. * @param listener Listener to add
  217. */
  218. public void addStepListener(final StepListener listener) {
  219. stepListeners.add(StepListener.class, listener);
  220. }
  221. /**
  222. * Removes a step listener from the list.
  223. *
  224. * @param listener Listener to remove
  225. */
  226. public void removeStepListener(final StepListener listener) {
  227. stepListeners.remove(StepListener.class, listener);
  228. }
  229. /**
  230. * Adds a wizard listener to the list.
  231. *
  232. * @param listener Listener to add
  233. */
  234. public void addWizardListener(final WizardListener listener) {
  235. stepListeners.add(WizardListener.class, listener);
  236. }
  237. /**
  238. * Removes a wizard listener from the list.
  239. *
  240. * @param listener Listener to remove
  241. */
  242. public void removeWizardListener(final WizardListener listener) {
  243. stepListeners.remove(WizardListener.class, listener);
  244. }
  245. /**
  246. * Fires step about to be displayed events.
  247. *
  248. * @param step Step to be displayed
  249. */
  250. private void fireStepAboutToBeDisplayed(final Step step) {
  251. for (StepListener listener : stepListeners.get(StepListener.class)) {
  252. listener.stepAboutToDisplay(step);
  253. }
  254. }
  255. /**
  256. * Fires step hidden events.
  257. *
  258. * @param step step that's been hidden
  259. */
  260. private void fireStepHidden(final Step step) {
  261. for (StepListener listener : stepListeners.get(StepListener.class)) {
  262. listener.stepHidden(step);
  263. }
  264. }
  265. /**
  266. * Fires wizard finished events.
  267. */
  268. private void fireWizardFinished() {
  269. stepListeners.get(WizardListener.class)
  270. .forEach(WizardListener::wizardFinished);
  271. }
  272. /**
  273. * Fires wizard cancelled events.
  274. */
  275. protected void fireWizardCancelled() {
  276. stepListeners.get(WizardListener.class)
  277. .forEach(WizardListener::wizardCancelled);
  278. }
  279. }