KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > installer > SwingInstall


1 /*
2  * SwingInstall.java
3  *
4  * Originally written by Slava Pestov for the jEdit installer project. This work
5  * has been placed into the public domain. You may use this work in any way and
6  * for any purpose you wish.
7  *
8  * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE
9  * IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES
10  * _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION,
11  * OR REDISTRIBUTION OF THIS SOFTWARE.
12  */

13
14 package installer;
15
16 import javax.swing.border.*;
17 import javax.swing.*;
18 import java.awt.event.*;
19 import java.awt.*;
20 import java.io.File JavaDoc;
21 import java.util.*;
22
23 /*
24  * Graphical front-end to installer.
25  */

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