PageRenderTime 94ms CodeModel.GetById 58ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/installer/SwingInstall.java

#
Java | 599 lines | 474 code | 99 blank | 26 comment | 31 complexity | b7f3dc57f7de2467fcbe1da9c769370c MD5 | raw file
  1/*
  2 * SwingInstall.java
  3 * Copyright (C) 1999, 2000, 2001, 2002 Slava Pestov
  4 *
  5 * This program is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU General Public License
  7 * as published by the Free Software Foundation; either version 2
  8 * of the License, or any later version.
  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
 20package installer;
 21
 22import javax.swing.border.*;
 23import javax.swing.event.*;
 24import javax.swing.*;
 25import java.awt.event.*;
 26import java.awt.*;
 27import java.io.File;
 28import java.io.IOException;
 29import java.util.Vector;
 30
 31/*
 32 * Graphical front-end to installer.
 33 */
 34public class SwingInstall extends JFrame
 35{
 36	public SwingInstall()
 37	{
 38		installer = new Install();
 39
 40		appName = installer.getProperty("app.name");
 41		appVersion = installer.getProperty("app.version");
 42
 43		setTitle(appName + " " + appVersion + " installer");
 44
 45		JPanel content = new JPanel(new WizardLayout());
 46		setContentPane(content);
 47
 48		caption = new JLabel();
 49		caption.setFont(new Font("SansSerif",Font.BOLD,18));
 50
 51		ActionHandler actionHandler = new ActionHandler();
 52
 53		cancelButton = new JButton("Cancel");
 54		cancelButton.setRequestFocusEnabled(false);
 55		cancelButton.addActionListener(actionHandler);
 56		prevButton = new JButton("Previous");
 57		prevButton.setRequestFocusEnabled(false);
 58		prevButton.addActionListener(actionHandler);
 59		nextButton = new JButton();
 60		nextButton.setRequestFocusEnabled(false);
 61		nextButton.addActionListener(actionHandler);
 62
 63		content.add(caption);
 64		content.add(cancelButton);
 65		content.add(prevButton);
 66		content.add(nextButton);
 67
 68		String clazz = OperatingSystem.getOperatingSystem()
 69				.getClass().getName();
 70		String completedInfo = "done-" + clazz.substring(
 71			clazz.indexOf('$') + 1) + ".html";
 72
 73		pages = new Component[] {
 74			new TextPanel(installer.getProperty("app.readme")),
 75			new TextPanel(installer.getProperty("app.license")),
 76			chooseDirectory = new ChooseDirectory(),
 77			selectComponents = new SelectComponents(),
 78			progress = new SwingProgress(),
 79			new TextPanel(completedInfo)
 80		};
 81
 82		for(int i = 0; i < pages.length; i++)
 83			content.add(pages[i]);
 84
 85		pageChanged();
 86
 87		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
 88		addWindowListener(new WindowHandler());
 89
 90		Dimension screen = getToolkit().getScreenSize();
 91		pack();
 92		setLocation((screen.width - getSize().width) / 2,
 93			(screen.height - getSize().height) / 2);
 94		show();
 95	}
 96
 97	// package-private members
 98	Install installer;
 99	String appName;
100	String appVersion;
101
102	JLabel caption;
103
104	ChooseDirectory chooseDirectory;
105	SelectComponents selectComponents;
106	SwingProgress progress;
107
108	JButton cancelButton;
109	JButton prevButton;
110	JButton nextButton;
111	Component[] pages;
112	int currentPage;
113
114	private static final int PADDING = 12;
115
116	void install()
117	{
118		Vector components = new Vector();
119		int size = 0;
120
121		JPanel comp = selectComponents.comp;
122		Vector ids = selectComponents.filesets;
123
124		for(int i = 0; i < comp.getComponentCount(); i++)
125		{
126			if(((JCheckBox)comp.getComponent(i))
127				.getModel().isSelected())
128			{
129				size += installer.getIntProperty(
130					"comp." + ids.elementAt(i) + ".real-size");
131				components.addElement(installer.getProperty(
132					"comp." + ids.elementAt(i) + ".fileset"));
133			}
134		}
135
136		JTextField binDir = chooseDirectory.binDir;
137		String installDir = chooseDirectory.installDir.getText();
138
139		InstallThread thread = new InstallThread(
140			installer,progress,
141			(installDir == null ? null : installDir),
142			(binDir == null ? null : binDir.getText()),
143			size,components);
144		progress.setThread(thread);
145		thread.start();
146	}
147
148	private void pageChanged()
149	{
150		switch(currentPage)
151		{
152		case 0:
153			caption.setText("Installing " + appName);
154
155			nextButton.setText("Next");
156			prevButton.setEnabled(false);
157			break;
158		case 1:
159			caption.setText(installer.getProperty("app.license.title"));
160
161			nextButton.setText("Next");
162			prevButton.setEnabled(true);
163			break;
164		case 2:
165			caption.setText("Specify where " + appName
166				+ " is to be installed");
167
168			nextButton.setText("Next");
169			prevButton.setEnabled(true);
170			break;
171		case 3:
172			caption.setText("Choose components to install");
173
174			nextButton.setText("Install");
175			prevButton.setEnabled(true);
176			break;
177		case 4:
178			caption.setText("Installing " + appName);
179
180			nextButton.setText("Finish");
181			prevButton.setEnabled(false);
182			nextButton.setEnabled(false);
183			install();
184			break;
185		case 5:
186			caption.setText("Installation complete");
187
188			nextButton.setText("Finish");
189			prevButton.setEnabled(false);
190			nextButton.setEnabled(true);
191			break;
192		}
193
194		getRootPane().invalidate();
195		getRootPane().validate();
196	}
197
198	class ActionHandler implements ActionListener
199	{
200		public void actionPerformed(ActionEvent evt)
201		{
202			Object source = evt.getSource();
203			if(evt.getSource() == cancelButton)
204				System.exit(0);
205			else if(evt.getSource() == prevButton)
206			{
207				currentPage--;
208				pageChanged();
209			}
210			else if(evt.getSource() == nextButton)
211			{
212				if(currentPage == pages.length - 1)
213					System.exit(0);
214				else
215				{
216					currentPage++;
217					pageChanged();
218				}
219			}
220		}
221	}
222
223	class WindowHandler extends WindowAdapter
224	{
225		public void windowClosing(WindowEvent evt)
226		{
227			System.exit(0);
228		}
229	}
230
231	class WizardLayout implements LayoutManager
232	{
233		public void addLayoutComponent(String name, Component comp)
234		{
235		}
236
237		public void removeLayoutComponent(Component comp)
238		{
239		}
240
241		public Dimension preferredLayoutSize(Container parent)
242		{
243			Dimension dim = new Dimension();
244
245			Dimension captionSize = caption.getPreferredSize();
246			dim.width = captionSize.width;
247
248			for(int i = 0; i < pages.length; i++)
249			{
250				Dimension _dim = pages[i].getPreferredSize();
251				dim.width = Math.max(_dim.width,dim.width);
252				dim.height = Math.max(_dim.height,dim.height);
253			}
254
255			dim.width += PADDING * 2;
256			dim.height += PADDING * 2;
257			dim.height += nextButton.getPreferredSize().height;
258			dim.height += captionSize.height;
259			return dim;
260		}
261
262		public Dimension minimumLayoutSize(Container parent)
263		{
264			return preferredLayoutSize(parent);
265		}
266
267		public void layoutContainer(Container parent)
268		{
269			Dimension size = parent.getSize();
270
271			Dimension captionSize = caption.getPreferredSize();
272			caption.setBounds(PADDING,PADDING,captionSize.width,
273				captionSize.height);
274
275			// make all buttons the same size
276			Dimension buttonSize = cancelButton.getPreferredSize();
277			buttonSize.width = Math.max(buttonSize.width,prevButton.getPreferredSize().width);
278			buttonSize.width = Math.max(buttonSize.width,nextButton.getPreferredSize().width);
279
280			int bottomBorder = buttonSize.height + PADDING;
281
282			// cancel button goes on far left
283			cancelButton.setBounds(
284				PADDING,
285				size.height - buttonSize.height - PADDING,
286				buttonSize.width,
287				buttonSize.height);
288
289			// prev and next buttons are on the right
290			prevButton.setBounds(
291				size.width - buttonSize.width * 2 - 6 - PADDING,
292				size.height - buttonSize.height - PADDING,
293				buttonSize.width,
294				buttonSize.height);
295
296			nextButton.setBounds(
297				size.width - buttonSize.width - PADDING,
298				size.height - buttonSize.height - PADDING,
299				buttonSize.width,
300				buttonSize.height);
301
302			// calculate size for current page
303			Rectangle currentPageBounds = new Rectangle();
304			currentPageBounds.x = PADDING;
305			currentPageBounds.y = PADDING * 2 + captionSize.height;
306			currentPageBounds.width = size.width - currentPageBounds.x
307				- PADDING;
308			currentPageBounds.height = size.height - buttonSize.height
309				- currentPageBounds.y - PADDING * 2;
310
311			for(int i = 0; i < pages.length; i++)
312			{
313				Component page = pages[i];
314				page.setBounds(currentPageBounds);
315				page.setVisible(i == currentPage);
316			}
317		}
318	}
319
320	class TextPanel extends JPanel
321	{
322		TextPanel(String file)
323		{
324			super(new BorderLayout());
325
326			JEditorPane text = new JEditorPane();
327
328			try
329			{
330				text.setPage(TextPanel.this.getClass().getResource(file));
331			}
332			catch(Exception e)
333			{
334				text.setText("Error loading '" + file + "'");
335				e.printStackTrace();
336			}
337
338			text.setEditable(false);
339
340			JScrollPane scrollPane = new JScrollPane(text);
341			Dimension dim = new Dimension();
342			dim.width = 450;
343			dim.height = 200;
344			scrollPane.setPreferredSize(dim);
345			TextPanel.this.add(BorderLayout.CENTER,scrollPane);
346		}
347	}
348
349	class ChooseDirectory extends JPanel
350	implements ActionListener
351	{
352		JTextField installDir;
353		JButton chooseInstall;
354		JTextField binDir;
355		JButton chooseBin;
356
357		ChooseDirectory()
358		{
359			super(new BorderLayout());
360
361			String _binDir = OperatingSystem.getOperatingSystem()
362				.getShortcutDirectory(appName,appVersion);
363
364			JPanel directoryPanel = new JPanel();
365			GridBagLayout layout = new GridBagLayout();
366			directoryPanel.setLayout(layout);
367			GridBagConstraints cons = new GridBagConstraints();
368			cons.anchor = GridBagConstraints.WEST;
369			cons.fill = GridBagConstraints.HORIZONTAL;
370			cons.gridy = 1;
371			cons.insets = new Insets(0,0,6,0);
372
373			JLabel label = new JLabel("Install program in: ",SwingConstants.RIGHT);
374			label.setBorder(new EmptyBorder(0,0,0,12));
375			layout.setConstraints(label,cons);
376			directoryPanel.add(label);
377
378			cons.weightx = 1.0f;
379			installDir = new JTextField();
380			installDir.setText(OperatingSystem.getOperatingSystem()
381				.getInstallDirectory(appName,appVersion));
382			layout.setConstraints(installDir,cons);
383			directoryPanel.add(installDir);
384
385			if(_binDir != null)
386			{
387				cons.gridy = 2;
388				cons.weightx = 0.0f;
389				cons.insets = new Insets(0,0,0,0);
390				label = new JLabel("Install shortcut in: ",SwingConstants.RIGHT);
391				label.setBorder(new EmptyBorder(0,0,0,12));
392				layout.setConstraints(label,cons);
393				directoryPanel.add(label);
394
395				cons.weightx = 1.0f;
396				binDir = new JTextField(_binDir);
397				layout.setConstraints(binDir,cons);
398				directoryPanel.add(binDir);
399			}
400
401			ChooseDirectory.this.add(BorderLayout.NORTH,directoryPanel);
402
403			Box buttons = new Box(BoxLayout.X_AXIS);
404			buttons.add(Box.createGlue());
405			chooseInstall = new JButton("Choose Install Directory...");
406			chooseInstall.setRequestFocusEnabled(false);
407			chooseInstall.addActionListener(this);
408			buttons.add(chooseInstall);
409			if(_binDir != null)
410			{
411				buttons.add(Box.createHorizontalStrut(6));
412				chooseBin = new JButton("Choose Shortcut Directory...");
413				chooseBin.setRequestFocusEnabled(false);
414				chooseBin.addActionListener(this);
415				buttons.add(chooseBin);
416			}
417			buttons.add(Box.createGlue());
418
419			ChooseDirectory.this.add(BorderLayout.SOUTH,buttons);
420		}
421
422		public void actionPerformed(ActionEvent evt)
423		{
424			JTextField field = (evt.getSource() == chooseInstall
425				? installDir : binDir);
426
427			File directory = new File(field.getText());
428			JFileChooser chooser = new JFileChooser(directory.getParent());
429			chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
430			chooser.setSelectedFile(directory);
431
432			if(chooser.showOpenDialog(SwingInstall.this)
433				== JFileChooser.APPROVE_OPTION)
434				field.setText(chooser.getSelectedFile().getPath());
435		}
436	}
437
438	class SelectComponents extends JPanel
439	implements ActionListener
440	{
441		JPanel comp;
442		JLabel sizeLabel;
443		Vector filesets;
444
445		SelectComponents()
446		{
447			super(new BorderLayout());
448
449			comp = createCompPanel();
450			SelectComponents.this.add(BorderLayout.NORTH,comp);
451
452			sizeLabel = new JLabel("",SwingConstants.LEFT);
453			SelectComponents.this.add(BorderLayout.SOUTH,sizeLabel);
454
455			updateSize();
456		}
457
458		public void actionPerformed(ActionEvent evt)
459		{
460			updateSize();
461		}
462
463		private JPanel createCompPanel()
464		{
465			filesets = new Vector();
466
467			int count = installer.getIntProperty("comp.count");
468			JPanel panel = new JPanel(new GridLayout(count,1));
469
470			String osClass = OperatingSystem.getOperatingSystem()
471				.getClass().getName();
472			osClass = osClass.substring(osClass.indexOf('$') + 1);
473
474			for(int i = 0; i < count; i++)
475			{
476				String os = installer.getProperty("comp." + i + ".os");
477
478				if(os != null && !osClass.equals(os))
479					continue;
480
481				JCheckBox checkBox = new JCheckBox(
482					installer.getProperty("comp." + i + ".name")
483					+ " (" + installer.getProperty("comp." + i
484					+ ".disk-size") + "Kb)");
485				checkBox.getModel().setSelected(true);
486				checkBox.addActionListener(this);
487				checkBox.setRequestFocusEnabled(false);
488
489				filesets.addElement(new Integer(i));
490
491				panel.add(checkBox);
492			}
493
494			Dimension dim = panel.getPreferredSize();
495			dim.width = Integer.MAX_VALUE;
496			panel.setMaximumSize(dim);
497
498			return panel;
499		}
500
501		private void updateSize()
502		{
503			int size = 0;
504
505			for(int i = 0; i < filesets.size(); i++)
506			{
507				if(((JCheckBox)comp.getComponent(i))
508					.getModel().isSelected())
509				{
510					size += installer.getIntProperty("comp."
511						+ filesets.elementAt(i)
512						+ ".disk-size");
513				}
514			}
515
516			sizeLabel.setText("Estimated disk usage of selected"
517				+ " components: " + size + "Kb");
518		}
519	}
520
521	class SwingProgress extends JPanel implements Progress
522	{
523		JProgressBar progress;
524		InstallThread thread;
525
526		SwingProgress()
527		{
528			super(new BorderLayout());
529
530			progress = new JProgressBar();
531			progress.setStringPainted(true);
532
533			SwingProgress.this.add(BorderLayout.NORTH,progress);
534		}
535
536		public void setMaximum(final int max)
537		{
538			SwingUtilities.invokeLater(new Runnable()
539			{
540				public void run()
541				{
542					progress.setMaximum(max);
543				}
544			});
545		}
546
547		public void advance(final int value)
548		{
549			try
550			{
551				SwingUtilities.invokeAndWait(new Runnable()
552				{
553					public void run()
554					{
555						progress.setValue(progress
556							.getValue() + value);
557					}
558				});
559				Thread.yield();
560			}
561			catch(Exception e)
562			{
563			}
564		}
565
566		public void done()
567		{
568			SwingUtilities.invokeLater(new Runnable()
569			{
570				public void run()
571				{
572					currentPage++;
573					pageChanged();
574				}
575			});
576		}
577
578		public void error(final String message)
579		{
580			SwingUtilities.invokeLater(new Runnable()
581			{
582				public void run()
583				{
584					dispose();
585					JOptionPane.showMessageDialog(null,
586						message,
587						"Installation aborted",
588						JOptionPane.ERROR_MESSAGE);
589					System.exit(1);
590				}
591			});
592		}
593
594		public void setThread(InstallThread thread)
595		{
596			this.thread = thread;
597		}
598	}
599}