View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.component;
21  
22  import java.awt.BorderLayout;
23  import java.awt.CardLayout;
24  import java.awt.Color;
25  import java.awt.Component;
26  import java.awt.Dimension;
27  import java.awt.Font;
28  import java.awt.event.ActionEvent;
29  import java.util.Iterator;
30  import java.util.LinkedList;
31  
32  import javax.swing.AbstractAction;
33  import javax.swing.Action;
34  import javax.swing.BorderFactory;
35  import javax.swing.JButton;
36  import javax.swing.JLabel;
37  import javax.swing.JPanel;
38  import javax.swing.SwingConstants;
39  import javax.swing.border.EmptyBorder;
40  
41  import org.xnap.XNap;
42  import org.xnap.gui.Dialogs;
43  import org.xnap.gui.SettingsPanel;
44  import org.xnap.gui.util.IconHelper;
45  
46  public class DefaultWizardDialog extends DefaultDialog
47  {
48  
49      //--- Constant(s) ---
50  
51      //--- Data field(s) ---
52  
53  	private JLabel jlTitle;
54  	private JLabel jlIcon;
55  	private MultiLineLabel jtaDescription;
56      
57      private JPanel ctPanels;
58      private CardLayout clPanels;
59  
60      private LinkedList panels = new LinkedList();
61      private int selectedIndex = 0;
62  
63      private JButton jbNext;
64      private JButton jbFinish;
65  
66      private PreviousAction acPrevious = new PreviousAction();
67      private NextAction acNext = new NextAction();
68      private FinishAction acFinish = new FinishAction();
69  
70      //--- Constructor(s) ---
71  
72      public DefaultWizardDialog(int buttons)
73      {
74  		super(buttons);
75  
76  		// top
77  		JPanel jpTop = new JPanel(new BorderLayout());
78  		jpTop.setBackground(Color.white);
79  		jpTop.setBorder(BorderFactory.createEtchedBorder());
80  		getContentPane().add(jpTop, BorderLayout.NORTH);
81  
82  		JPanel jpTitle = new JPanel(new BorderLayout());
83  		jpTitle.setBackground(Color.white);
84  		jpTop.add(jpTitle, BorderLayout.CENTER);
85  		
86  		jlTitle = new JLabel(" ");
87  		jlTitle.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
88  		jlTitle.setFont(new Font("Dialog", Font.BOLD, 16));
89  		jlTitle.setForeground(Color.black);
90  		jpTitle.add(jlTitle, BorderLayout.NORTH);
91  
92  		jtaDescription = new MultiLineLabel(" ");
93  		jtaDescription.setBackground(Color.white);
94  		jtaDescription.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
95  		jtaDescription.setForeground(Color.black);
96  		jpTitle.add(jtaDescription, BorderLayout.CENTER);
97  
98  		jlIcon = new JLabel();
99  		jlIcon.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
100 		jpTop.add(jlIcon, BorderLayout.EAST);
101 
102 		// center
103 		clPanels = new CardLayout();
104 		ctPanels = new JPanel();
105 		ctPanels.setBorder(new EmptyBorder(5, 5, 5, 5));
106 		ctPanels.setLayout(clPanels);
107 
108 		// bottom
109 		JPanel jpButtons = getButtonPanel();
110 
111 		jpButtons.add(new XNapButton(acPrevious), 0);
112 
113 		jbNext = new XNapButton(acNext);
114 		jbNext.setHorizontalTextPosition(SwingConstants.LEFT);
115 		jpButtons.add(jbNext, 1);
116 
117 		jbFinish = new XNapButton(acFinish);
118 		jpButtons.add(jbFinish, 2);
119 
120 		// set me up
121 		setMainComponent(ctPanels);
122 		setSize(640, 480);
123     }
124 
125 	public DefaultWizardDialog()
126 	{
127 		this(BUTTON_CANCEL);
128 	}
129 
130     //--- Method(s) ---
131 
132     public void addPanel(SettingsPanel panel)
133     {
134 		ctPanels.add(panel.getPanel(), panel.getTitle());
135 		panels.add(panel);
136 		updatePanel(0);
137     }
138 
139 	public void finish()
140 	{
141 		boolean canClose = true;
142 		for (Iterator i = panels.iterator(); i.hasNext();) {
143 			try {
144 				((SettingsPanel)i.next()).apply();
145 			}
146 			catch (Exception e) {
147 				canClose = false;
148 				Dialogs.error(this, e.toString());
149 			}
150 		}
151 		
152 		if (canClose) {
153 			isOkay = true;
154 			close();
155 		}
156 	}
157 
158 	public Action getFinishAction()
159 	{
160 		return acFinish;
161 	}
162 
163 	public Action getNextAction()
164 	{
165 		return acNext;
166 	}
167 
168 	public int getSelectedIndex()
169 	{
170 		return selectedIndex;
171 	}
172 
173 	public SettingsPanel getSelectedPanel()
174 	{
175 		return (SettingsPanel)panels.get(getSelectedIndex());
176 	}
177 
178 	/***
179 	 * Invoked when the user presses next or previous. 
180 	 *
181 	 * <p>Sub classes can overwrite this method.
182 	 */
183 	protected void panelChanged(SettingsPanel panel)
184 	{
185 	}
186 
187     private void updateActions()
188     {
189 		acPrevious.setEnabled(selectedIndex > 0);
190 		acNext.setEnabled(selectedIndex < panels.size() - 1);
191 		if (acNext.isEnabled()) {
192 			jbNext.requestFocus();
193 		}
194 		else {
195 			jbFinish.requestFocus();
196 		}
197     }
198 
199 	private void updatePanel(int index) 
200 	{
201 		if (index == 1) {
202 			clPanels.next(ctPanels);
203 		}
204 		else if (index == -1) {
205 			clPanels.previous(ctPanels);
206 		}
207 		else if (index != 0) {
208 			// this should never happen
209 			return;
210 		}
211 		
212 		selectedIndex += index;
213 		updateActions();
214 
215 		// update top
216 		SettingsPanel panel = getSelectedPanel();
217 		jlTitle.setText(panel.getTitle());
218 		jlIcon.setIcon(panel.getIcon());
219 		jtaDescription.setText(panel.getDescription());
220 		if (index != 0 || (selectedIndex == 0 && index == 0)) {
221 			panelChanged(panel);
222 		}
223 	}
224 
225     public class PreviousAction extends AbstractAction {
226 	
227 		public PreviousAction()
228 		{
229 			putValue(Action.NAME, XNap.tr("Previous"));
230 			putValue(IconHelper.XNAP_ICON, "1leftarrow.png");
231             putValue(Action.SHORT_DESCRIPTION,
232 					 XNap.tr("Goes to previous page."));
233         }
234 
235         public void actionPerformed(ActionEvent event) 
236 		{
237 			updatePanel(-1);
238         }
239 
240     }
241 
242     public class NextAction extends AbstractAction {
243 	
244 		public NextAction()
245 		{
246 			putValue(Action.NAME, XNap.tr("Next"));
247 			putValue(IconHelper.XNAP_ICON, "1rightarrow.png");
248             putValue(Action.SHORT_DESCRIPTION, XNap.tr("Goes to next page."));
249         }
250 
251         public void actionPerformed(ActionEvent event) 
252 		{
253 			updatePanel(1);
254         }
255 
256     }
257 
258     public class FinishAction extends AbstractAction {
259 	
260 		public FinishAction()
261 		{
262 			putValue(Action.NAME, XNap.tr("Finish"));
263             putValue(Action.SHORT_DESCRIPTION, 
264 					 XNap.tr("Closes the dialog saving changes."));
265         }
266 
267         public void actionPerformed(ActionEvent event) 
268 		{
269 			finish();
270         }
271 
272     }
273 
274     protected class PContainer extends JPanel
275     {
276 		Dimension maxDim = new Dimension(0, 0);
277 
278 		public void add(Component comp, Object constraints) 
279 		{
280 			Dimension d = comp.getPreferredSize();
281 			if (d.height > maxDim.height) {
282 				maxDim.height = d.height;
283 			}
284 			if (d.width > maxDim.width) {
285 				maxDim.width = d.width;
286 			}
287 
288 			super.add(comp, constraints);
289 		}
290 
291 		public Dimension getPreferredSize()
292 		{
293 			// looks like the height is too small
294 			return new Dimension(maxDim.width + 10, maxDim.height + 30);
295 		}
296     }
297 
298 }