1 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 ; 21 import java.util.*; 22 23 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 clazz = OperatingSystem.getOperatingSystem() 62 .getClass().getName(); 63 String 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 Install installer; 93 OperatingSystem.OSTask[] osTasks; 94 String appName; 95 String 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 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 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 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 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 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 cancelButton.setBounds( 290 PADDING, 291 size.height - buttonSize.height - PADDING, 292 buttonSize.width, 293 buttonSize.height); 294 295 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 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 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 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 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 label, 388 String 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 directory = new File (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 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 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 (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 () 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 () 547 { 548 public void run() 549 { 550 progress.setValue(progress 551 .getValue() + value); 552 } 553 }); 554 Thread.yield(); 555 } 556 catch(Exception e) 557 { 558 } 559 } 560 561 public void done() 562 { 563 SwingUtilities.invokeLater(new Runnable () 564 { 565 public void run() 566 { 567 currentPage++; 568 pageChanged(); 569 } 570 }); 571 } 572 573 public void error(final String message) 574 { 575 SwingUtilities.invokeLater(new Runnable () 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
|