1 19 20 package org.openide; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Color ; 24 import java.awt.Component ; 25 import java.awt.Container ; 26 import java.awt.Cursor ; 27 import java.awt.Dimension ; 28 import java.awt.FocusTraversalPolicy ; 29 import java.awt.Font ; 30 import java.awt.Graphics ; 31 import java.awt.Image ; 32 import java.awt.Insets ; 33 import java.awt.KeyboardFocusManager ; 34 import java.awt.MediaTracker ; 35 import java.awt.Rectangle ; 36 import java.awt.Window ; 37 import java.awt.event.ActionEvent ; 38 import java.awt.event.ActionListener ; 39 import java.awt.event.KeyEvent ; 40 import java.awt.event.WindowEvent ; 41 import java.awt.event.WindowListener ; 42 import java.beans.PropertyChangeEvent ; 43 import java.beans.PropertyChangeListener ; 44 import java.io.IOException ; 45 import java.net.URL ; 46 import java.text.MessageFormat ; 47 import java.util.Arrays ; 48 import java.util.Collections ; 49 import java.util.HashMap ; 50 import java.util.Map ; 51 import java.util.ResourceBundle ; 52 import java.util.Set ; 53 import java.util.logging.Level ; 54 import java.util.logging.Logger ; 55 import javax.accessibility.Accessible ; 56 import javax.swing.BorderFactory ; 57 import javax.swing.ImageIcon ; 58 import javax.swing.JButton ; 59 import javax.swing.JComponent ; 60 import javax.swing.JLabel ; 61 import javax.swing.JList ; 62 import javax.swing.JPanel ; 63 import javax.swing.JProgressBar ; 64 import javax.swing.JScrollPane ; 65 import javax.swing.JSeparator ; 66 import javax.swing.JTabbedPane ; 67 import javax.swing.JTextArea ; 68 import javax.swing.KeyStroke ; 69 import javax.swing.ListCellRenderer ; 70 import javax.swing.SwingConstants ; 71 import javax.swing.SwingUtilities ; 72 import javax.swing.UIManager ; 73 import javax.swing.event.ChangeEvent ; 74 import javax.swing.event.ChangeListener ; 75 import org.openide.awt.HtmlBrowser; 76 import org.openide.awt.Mnemonics; 77 import org.openide.util.Exceptions; 78 import org.openide.util.HelpCtx; 79 import org.openide.util.Mutex; 80 import org.openide.util.NbBundle; 81 import org.openide.util.RequestProcessor; 82 import org.openide.util.Utilities; 83 import org.openide.util.WeakListeners; 84 import org.netbeans.api.progress.ProgressHandle; 85 import org.netbeans.api.progress.ProgressHandleFactory; 86 87 96 public class WizardDescriptor extends DialogDescriptor { 97 99 public static final Object NEXT_OPTION = new String ("NEXT_OPTION"); 101 103 public static final Object FINISH_OPTION = OK_OPTION; 104 105 107 public static final Object PREVIOUS_OPTION = new String ("PREVIOUS_OPTION"); private static final ActionListener CLOSE_PREVENTER = new ActionListener () { 109 public void actionPerformed(ActionEvent evt) { 110 } 111 112 public String toString() { 113 return "CLOSE_PREVENTER"; } 115 }; 116 117 124 private static final String PROP_AUTO_WIZARD_STYLE = "WizardPanel_autoWizardStyle"; 126 131 private static final String PROP_HELP_DISPLAYED = "WizardPanel_helpDisplayed"; 133 138 private static final String PROP_CONTENT_DISPLAYED = "WizardPanel_contentDisplayed"; 140 145 private static final String PROP_CONTENT_NUMBERED = "WizardPanel_contentNumbered"; 147 151 private static final String PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; 153 157 private static final String PROP_CONTENT_DATA = "WizardPanel_contentData"; 159 163 private static final String PROP_CONTENT_BACK_COLOR = "WizardPanel_contentBackColor"; 165 169 private static final String PROP_CONTENT_FOREGROUND_COLOR = "WizardPanel_contentForegroundColor"; 171 175 private static final String PROP_IMAGE = "WizardPanel_image"; 177 181 private static final String PROP_IMAGE_ALIGNMENT = "WizardPanel_imageAlignment"; 183 188 private static final String PROP_LEFT_DIMENSION = "WizardPanel_leftDimension"; 190 194 private static final String PROP_HELP_URL = "WizardPanel_helpURL"; 196 202 private static final String PROP_ERROR_MESSAGE = "WizardPanel_errorMessage"; 204 private static Logger err = Logger.getLogger(WizardDescriptor.class.getName ()); 205 206 207 private final JButton nextButton = new JButton (); 208 private final JButton finishButton = new JButton (); 209 private final JButton cancelButton = new JButton (); 210 private final JButton previousButton = new JButton (); 211 private FinishAction finishOption; 212 private Set newObjects = Collections.EMPTY_SET; 213 214 215 private Component waitingComponent; 216 private boolean changeStateInProgress = false; 217 218 222 private boolean autoWizardStyle = false; 223 224 227 private boolean init = false; 228 229 230 private WizardPanel wizardPanel; 231 232 233 private Image image; 234 235 236 private String [] contentData = new String [] { }; 237 238 239 private int contentSelectedIndex = -1; 240 241 242 private Color contentBackColor; 243 244 245 private Color contentForegroundColor; 246 247 248 private URL helpURL; 249 250 251 private PropL propListener; 252 253 254 private String imageAlignment = "North"; 256 257 private SettingsAndIterator<?> data; 258 259 260 private ChangeListener weakChangeListener; 261 private PropertyChangeListener weakPropertyChangeListener; 262 private ActionListener weakNextButtonListener; 263 private ActionListener weakPreviousButtonListener; 264 private ActionListener weakFinishButtonListener; 265 private ActionListener weakCancelButtonListener; 266 267 private Listener baseListener; 269 270 271 private MessageFormat titleFormat; 272 273 276 private Map <String ,Object > properties; 277 ResourceBundle bundle = NbBundle.getBundle(WizardDescriptor.class); 278 279 283 static final RequestProcessor ASYNCHRONOUS_JOBS_RP = 284 new RequestProcessor("wizard-descriptor-asynchronous-jobs", 1, true); 286 private RequestProcessor.Task backgroundValidationTask; 287 288 private boolean validationRuns; 289 290 private ProgressHandle handle; 291 292 private static final String PROGRESS_BAR_DISPLAY_NAME = NbBundle.getMessage (WizardDescriptor.class, "CTL_InstantiateProgress_Title"); 294 private ActionListener escapeActionListener; 295 296 { 297 ResourceBundle b = NbBundle.getBundle("org.openide.Bundle"); nextButton.setText(b.getString("CTL_NEXT")); 300 Mnemonics.setLocalizedText(previousButton, b.getString("CTL_PREVIOUS")); 301 Mnemonics.setLocalizedText(finishButton, b.getString("CTL_FINISH")); 302 finishButton.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_FINISH")); 303 cancelButton.setText(b.getString("CTL_CANCEL")); 304 cancelButton.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_CANCEL")); 305 306 finishButton.setDefaultCapable(true); 307 nextButton.setDefaultCapable(true); 308 previousButton.setDefaultCapable(false); 309 cancelButton.setDefaultCapable(false); 310 } 311 312 317 public <Data> WizardDescriptor(Panel <Data>[] wizardPanels, Data settings) { 318 this(new SettingsAndIterator<Data>(new ArrayIterator<Data>(wizardPanels), settings)); 319 } 320 321 327 public WizardDescriptor(Panel <WizardDescriptor>[] wizardPanels) { 328 this(SettingsAndIterator.create(new ArrayIterator<WizardDescriptor>(wizardPanels))); 329 } 330 331 337 public <Data>WizardDescriptor(Iterator<Data> panels, Data settings) { 338 this(new SettingsAndIterator<Data>(panels, settings)); 339 } 340 341 private <Data> WizardDescriptor(SettingsAndIterator<Data> data) { 342 super("", "", true, DEFAULT_OPTION, null, CLOSE_PREVENTER); 344 this.data = data; 345 346 baseListener = new Listener (); 347 348 weakNextButtonListener = WeakListeners.create( 349 ActionListener .class, baseListener, nextButton 350 ); weakPreviousButtonListener = WeakListeners.create( 352 ActionListener .class, baseListener, previousButton 353 ); weakFinishButtonListener = WeakListeners.create( 355 ActionListener .class, baseListener, finishButton 356 ); weakCancelButtonListener = WeakListeners.create( 358 ActionListener .class, baseListener, cancelButton 359 ); 361 nextButton.addActionListener(weakNextButtonListener); 362 previousButton.addActionListener(weakPreviousButtonListener); 363 finishButton.addActionListener(weakFinishButtonListener); 364 cancelButton.addActionListener(weakCancelButtonListener); 365 366 finishOption = new WizardDescriptor.FinishAction(); 367 368 super.setOptions(new Object [] { previousButton, nextButton, finishButton, cancelButton }); 369 super.setClosingOptions(new Object [] { finishOption, cancelButton }); 370 371 weakChangeListener = WeakListeners.change(baseListener, data.getIterator(this)); 373 data.getIterator(this).addChangeListener(weakChangeListener); 374 375 callInitialize(); 376 } 377 378 383 public WizardDescriptor(Iterator<WizardDescriptor> panels) { 384 this(SettingsAndIterator.create(panels)); 385 } 386 387 389 protected void initialize() { 390 super.initialize(); 391 392 updateState(); 393 394 SwingUtilities.invokeLater (new Runnable () { 396 public void run () { 397 final Window w = SwingUtilities.getWindowAncestor((Component ) getMessage()); 398 if (w != null) { 399 w.addWindowListener (new WindowListener () { 400 public void windowActivated (WindowEvent e) { 401 } 402 public void windowClosed (WindowEvent e) { 403 } 404 public void windowClosing (WindowEvent e) { 405 if (!changeStateInProgress) { 406 w.setVisible (false); 407 w.dispose (); 408 } 409 } 410 public void windowDeactivated (WindowEvent e) { 411 } 412 public void windowDeiconified (WindowEvent e) { 413 } 414 public void windowIconified (WindowEvent e) { 415 } 416 public void windowOpened (WindowEvent e) { 417 } 418 }); 419 } 420 } 421 }); 422 } 423 424 429 @Deprecated 430 @SuppressWarnings ("unchecked") 431 public final synchronized void setPanels(Iterator panels) { 432 if (data.getIterator(this) != null) { 433 data.getIterator(this).removeChangeListener(weakChangeListener); 434 } 435 436 data = data.clone(panels); 437 weakChangeListener = WeakListeners.change(baseListener, data.getIterator(this)); 438 data.getIterator(this).addChangeListener(weakChangeListener); 439 init = false; 440 441 updateState(); 442 } 443 444 450 public final synchronized <Data> void setPanelsAndSettings(Iterator<Data> panels, Data settings) { 451 if (data.getIterator(this) != null) { 452 data.getIterator(this).removeChangeListener(weakChangeListener); 453 } 454 455 data = new SettingsAndIterator<Data>(panels, settings); 456 weakChangeListener = WeakListeners.change(baseListener, data.getIterator(this)); 457 data.getIterator(this).addChangeListener(weakChangeListener); 458 init = false; 459 460 updateState(); 461 } 462 463 468 public void setOptions(Object [] options) { 469 super.setOptions(convertOptions(options)); 470 } 471 472 475 public void setAdditionalOptions(Object [] options) { 476 super.setAdditionalOptions(convertOptions(options)); 477 } 478 479 482 public void setClosingOptions(Object [] options) { 483 super.setClosingOptions(convertOptions(options)); 484 } 485 486 488 private Object [] convertOptions(Object [] options) { 489 Object [] clonedOptions = options.clone(); 490 491 for (int i = clonedOptions.length - 1; i >= 0; i--) { 492 if (clonedOptions[i] == NEXT_OPTION) { 493 clonedOptions[i] = nextButton; 494 } 495 496 if (clonedOptions[i] == PREVIOUS_OPTION) { 497 clonedOptions[i] = previousButton; 498 } 499 500 if (clonedOptions[i] == FINISH_OPTION) { 501 clonedOptions[i] = finishButton; 502 } 503 504 if (clonedOptions[i] == CANCEL_OPTION) { 505 clonedOptions[i] = cancelButton; 506 } 507 } 508 509 return clonedOptions; 510 } 511 512 515 public Object getValue() { 516 return backConvertOption(super.getValue()); 517 } 518 519 522 private Object backConvertOption(Object op) { 523 if (op == nextButton) { 524 return NEXT_OPTION; 525 } 526 527 if (op == previousButton) { 528 return PREVIOUS_OPTION; 529 } 530 531 if (op == finishButton) { 532 return FINISH_OPTION; 533 } 534 535 if (op == cancelButton) { 536 return CANCEL_OPTION; 537 } 538 539 return op; 541 } 542 543 559 public void setTitleFormat(MessageFormat format) { 560 titleFormat = format; 561 562 if (init) { 563 updateState(); 564 } 565 } 566 567 571 public synchronized MessageFormat getTitleFormat() { 572 if (titleFormat == null) { 573 titleFormat = new MessageFormat (NbBundle.getMessage(WizardDescriptor.class, "CTL_WizardName")); 575 } 576 577 return titleFormat; 578 } 579 580 586 public void putProperty(final String name, final Object value) { 587 Object oldValue; 588 589 synchronized (this) { 590 if (properties == null) { 591 properties = new HashMap <String ,Object >(7); 592 } 593 594 oldValue = properties.get(name); 595 properties.put(name, value); 596 } 597 598 firePropertyChange(name, oldValue, value); 600 601 if (propListener != null) { 602 Mutex.EVENT.readAccess( 603 new Runnable () { 604 public void run() { 605 propListener.propertyChange(new PropertyChangeEvent (this, name, null, null)); 606 } 607 } 608 ); 609 } 610 611 if (PROP_ERROR_MESSAGE.equals(name)) { 612 if (init && OK_OPTION.equals (getValue ())) return ; if (wizardPanel != null) { 615 SwingUtilities.invokeLater (new Runnable () { 616 public void run () { 617 wizardPanel.setErrorMessage((String ) ((value == null) ? " " : value), (nextButton.isEnabled () || finishButton.isEnabled ()) ? Boolean.TRUE : Boolean.FALSE); } 619 }); 620 } 621 } 622 } 623 624 628 public synchronized Object getProperty(String name) { 629 return (properties == null) ? null : properties.get(name); 630 } 631 632 636 public synchronized Map <String ,Object > getProperties() { 637 return properties == null ? Collections.<String ,Object >emptyMap() : new HashMap <String ,Object >(properties); 638 } 639 640 public void setHelpCtx(final HelpCtx helpCtx) { 641 if ((wizardPanel != null) && (helpCtx != null)) { 642 HelpCtx.setHelpIDString(wizardPanel, helpCtx.getHelpID()); 643 } 644 645 super.setHelpCtx(helpCtx); 648 } 649 650 658 public Set getInstantiatedObjects() { 659 if (!(FINISH_OPTION.equals(getValue()))) { 661 throw new IllegalStateException (); 662 } 663 664 return newObjects; 665 } 666 667 675 protected synchronized void updateState() { 676 updateStateOpen(data); 677 } 678 private <A> void updateStateOpen(SettingsAndIterator<A> data) { 679 Panel <A> p = data.getIterator(this).current(); 680 681 if (data.current != p) { 683 if (data.current != null) { 684 data.current.removeChangeListener(weakChangeListener); 686 data.current.storeSettings(data.getSettings(this)); 687 } 688 689 p = data.getIterator(this).current(); 693 694 data.getIterator(this).removeChangeListener(weakChangeListener); 696 weakChangeListener = WeakListeners.change(baseListener, p); 697 data.getIterator(this).addChangeListener(weakChangeListener); 698 p.addChangeListener(weakChangeListener); 699 700 data.current = p; 701 p.readSettings(data.getSettings(this)); 702 } 703 704 boolean next = data.getIterator(this).hasNext(); 705 boolean prev = data.getIterator(this).hasPrevious(); 706 boolean valid = p.isValid(); 707 708 if (SwingUtilities.isEventDispatchThread ()) { 710 updateStateInAWT (); 711 } else { 712 SwingUtilities.invokeLater (new Runnable () { 713 public void run () { 714 updateStateInAWT (); 715 } 716 }); 717 } 718 720 setHelpCtx(p.getHelp()); 729 730 java.awt.Component c = p.getComponent(); 731 732 if ((c == null) || c instanceof java.awt.Window ) { 733 throw new IllegalStateException ("Wizard panel " + p + " gave a strange component " + c); } 735 736 if (!init) { 737 if (c instanceof JComponent ) { 738 autoWizardStyle = getBooleanProperty((JComponent ) c, PROP_AUTO_WIZARD_STYLE); 739 740 if (autoWizardStyle) { 741 wizardPanel = new WizardPanel( 742 getBooleanProperty((JComponent ) c, PROP_CONTENT_DISPLAYED), 743 getBooleanProperty((JComponent ) c, PROP_HELP_DISPLAYED), 744 getBooleanProperty((JComponent ) c, PROP_CONTENT_NUMBERED), getLeftDimension((JComponent ) c) 745 ); 746 initBundleProperties(); 747 } 748 } 749 750 if (propListener == null) { 751 propListener = new PropL(); 752 } 753 754 init = true; 755 } 756 757 if (wizardPanel != null) { 759 Component oldComp = wizardPanel.getRightComponent(); 760 761 if (oldComp != null) { 762 oldComp.removePropertyChangeListener(weakPropertyChangeListener); 763 } 764 765 if (c instanceof JComponent ) { 766 setPanelProperties((JComponent ) c); 767 wizardPanel.setContent(contentData); 768 wizardPanel.setSelectedIndex(contentSelectedIndex); 769 wizardPanel.setContentBackColor(contentBackColor); 770 wizardPanel.setContentForegroundColor(contentForegroundColor); 771 wizardPanel.setImage(image); 772 wizardPanel.setImageAlignment(imageAlignment); 773 wizardPanel.setHelpURL(helpURL); 774 updateButtonAccessibleDescription(); 775 weakPropertyChangeListener = WeakListeners.propertyChange(propListener, c); 776 c.addPropertyChangeListener(weakPropertyChangeListener); 777 } 778 779 if (wizardPanel.getRightComponent() != c) { 780 wizardPanel.setRightComponent(c); 781 782 if (wizardPanel != getMessage()) { 783 setMessage(wizardPanel); 784 } else { 785 firePropertyChange(DialogDescriptor.PROP_MESSAGE, null, wizardPanel); 788 } 789 } 790 } else if (c != getMessage()) { 791 setMessage(c); 792 } 793 794 String panelName = c.getName(); 795 796 if (panelName == null) { 797 panelName = ""; } 799 800 Object [] args = { panelName, data.getIterator(this).name() }; 801 MessageFormat mf = getTitleFormat(); 802 803 if (autoWizardStyle) { 804 wizardPanel.setPanelName(mf.format(args)); 805 } else { 806 setTitle(mf.format(args)); 807 } 808 809 Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 810 811 if ((fo != null) && (!fo.isEnabled()) && (wizardPanel != null)) { 812 wizardPanel.requestFocus(); 813 } 814 } 815 816 boolean isForwardEnabled () { 818 return data.getIterator(this).current ().isValid () && !validationRuns; 819 } 820 821 private void updateStateInAWT () { 822 Panel <?> p = data.getIterator(this).current (); 823 boolean next = data.getIterator(this).hasNext (); 824 boolean prev = data.getIterator(this).hasPrevious (); 825 boolean valid = p.isValid () && !validationRuns; 826 827 nextButton.setEnabled (next && valid); 828 previousButton.setEnabled (prev); 829 cancelButton.setEnabled (true); 830 831 if (data.current instanceof FinishablePanel) { 832 if (((FinishablePanel)data.current).isFinishPanel ()) { 834 finishButton.setEnabled (valid); 835 } else { 836 finishButton.setEnabled (valid && !next); 838 } 839 } else { 840 finishButton.setEnabled ( 842 valid && 843 (!next || (data.current instanceof FinishPanel)) 844 ); 845 } 846 } 847 848 849 850 private void updateStateWithFeedback() { 851 try { 852 showWaitCursor(); 853 updateState(); 854 } finally { 855 showNormalCursor(); 856 } 857 } 858 859 861 private void goToNextStep(Dimension previousSize) { 862 try { 863 showWaitCursor(); 864 865 boolean alreadyUpdated = false; 866 Font controlFont = (Font ) UIManager.getDefaults().get("controlFont"); Integer defaultSize = (Integer ) UIManager.get("nbDefaultFontSize"); 868 869 if (defaultSize == null) { 870 defaultSize = new Integer (11); 872 } 873 874 if ((controlFont != null) && (controlFont.getSize() > defaultSize.intValue())) { 877 Window parentWindow = SwingUtilities.getWindowAncestor((Component ) getMessage()); 878 879 if (parentWindow != null) { 880 updateState(); 881 alreadyUpdated = true; 882 resizeWizard(parentWindow, previousSize); 883 } 884 } 885 886 if (!alreadyUpdated) { 887 updateState(); 888 } 889 890 if (wizardPanel != null) { 891 wizardPanel.requestFocus(); 892 } 893 } finally { 894 showNormalCursor(); 895 } 896 } 897 898 902 private void resizeWizard(Window parentWindow, Dimension prevSize) { 903 Dimension curSize = data.getIterator(this).current().getComponent().getPreferredSize(); 904 905 if ((curSize.width > prevSize.width) || (curSize.height > prevSize.height)) { 907 Rectangle origBounds = parentWindow.getBounds(); 908 int newWidth = Math.max(origBounds.width + (curSize.width - prevSize.width), origBounds.width); 909 int newHeight = Math.max(origBounds.height + (curSize.height - prevSize.height), origBounds.height); 910 Rectangle screenBounds = Utilities.getUsableScreenBounds(); 911 Rectangle newBounds; 912 913 if (((origBounds.x + newWidth) > screenBounds.width) || ((origBounds.y + newHeight) > screenBounds.height)) { 915 newWidth = Math.min(screenBounds.width, newWidth); 916 newHeight = Math.min(screenBounds.height, newHeight); 917 newBounds = Utilities.findCenterBounds(new Dimension (newWidth, newHeight)); 918 } else { 919 newBounds = new Rectangle (origBounds.x, origBounds.y, newWidth, newHeight); 920 } 921 922 parentWindow.setBounds(newBounds); 923 parentWindow.invalidate(); 924 parentWindow.validate(); 925 parentWindow.repaint(); 926 } 927 } 928 929 private void showWaitCursor() { 930 if ((wizardPanel == null) || (wizardPanel.getRootPane() == null)) { 931 return; 933 } 934 935 if (wizardPanel != null) { 942 KeyStroke ks = KeyStroke.getKeyStroke (KeyEvent.VK_ESCAPE, 0); 944 escapeActionListener = wizardPanel.getRootPane ().getActionForKeyStroke (ks); 945 wizardPanel.getRootPane ().unregisterKeyboardAction (ks); 946 } 947 948 waitingComponent = wizardPanel.getRootPane().getContentPane(); 949 waitingComponent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 950 changeStateInProgress = true; 951 } 952 953 private void showNormalCursor() { 954 if (waitingComponent == null) { 955 return; 957 } 958 959 Window parentWindow = SwingUtilities.getWindowAncestor((Component ) getMessage()); 960 if (parentWindow != null) { 961 parentWindow.setEnabled (true); 962 } 963 964 if (wizardPanel != null) { 965 if (escapeActionListener != null) { 967 wizardPanel.getRootPane ().registerKeyboardAction (escapeActionListener, "Escape", 968 KeyStroke.getKeyStroke (KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 969 } 970 } 971 972 waitingComponent.setCursor(null); 973 waitingComponent = null; 974 changeStateInProgress = false; 975 } 976 977 991 992 998 private boolean getBooleanProperty(JComponent c, String s) { 999 Object property = getProperty(s); 1000 1001 if (property instanceof Boolean ) { 1002 return ((Boolean ) property).booleanValue(); 1003 } 1004 1005 property = c.getClientProperty(s); 1006 1007 if (property instanceof Boolean ) { 1008 return ((Boolean ) property).booleanValue(); 1009 } 1010 1011 return false; 1012 } 1013 1014 1019 private Dimension getLeftDimension(JComponent c) { 1020 Dimension leftDimension; 1021 Object property = c.getClientProperty(PROP_LEFT_DIMENSION); 1022 1023 if (property instanceof Dimension ) { 1024 leftDimension = (Dimension ) property; 1025 } else { 1026 leftDimension = new Dimension (198, 233); 1027 } 1028 1029 return leftDimension; 1030 } 1031 1032 1039 private void setPanelProperties(JComponent c) { 1040 Object property = getProperty(PROP_CONTENT_SELECTED_INDEX); 1042 1043 if (property instanceof Integer ) { 1044 contentSelectedIndex = ((Integer ) property).intValue(); 1045 } else { 1046 property = c.getClientProperty(PROP_CONTENT_SELECTED_INDEX); 1047 1048 if (property instanceof Integer ) { 1049 contentSelectedIndex = ((Integer ) property).intValue(); 1050 } 1051 } 1052 1053 property = getProperty(PROP_CONTENT_DATA); 1054 1055 if (property instanceof String []) { 1056 contentData = (String []) property; 1057 } else { 1058 property = c.getClientProperty(PROP_CONTENT_DATA); 1059 1060 if (property instanceof String []) { 1061 contentData = (String []) property; 1062 } 1063 } 1064 1065 property = getProperty(PROP_IMAGE); 1066 1067 if (property instanceof Image ) { 1068 image = (Image ) property; 1069 } else if ((properties == null) || (!properties.containsKey(PROP_IMAGE))) { 1070 property = c.getClientProperty(PROP_IMAGE); 1071 1072 if (property instanceof Image ) { 1073 image = (Image ) property; 1074 } 1075 } 1076 1077 property = getProperty(PROP_IMAGE_ALIGNMENT); 1078 1079 if (property instanceof String ) { 1080 imageAlignment = (String ) property; 1081 } else { 1082 property = c.getClientProperty(PROP_IMAGE_ALIGNMENT); 1083 1084 if (property instanceof String ) { 1085 imageAlignment = (String ) property; 1086 } 1087 } 1088 1089 property = getProperty(PROP_CONTENT_BACK_COLOR); 1090 1091 if (property instanceof Color ) { 1092 contentBackColor = (Color ) property; 1093 } else { 1094 property = c.getClientProperty(PROP_CONTENT_BACK_COLOR); 1095 1096 if (property instanceof Color ) { 1097 contentBackColor = (Color ) property; 1098 } 1099 } 1100 1101 property = getProperty(PROP_CONTENT_FOREGROUND_COLOR); 1102 1103 if (property instanceof Color ) { 1104 contentForegroundColor = (Color ) property; 1105 } else { 1106 property = c.getClientProperty(PROP_CONTENT_FOREGROUND_COLOR); 1107 1108 if (property instanceof Color ) { 1109 contentForegroundColor = (Color ) property; 1110 } 1111 } 1112 1113 property = c.getClientProperty(PROP_HELP_URL); 1114 1115 if (property instanceof URL ) { 1116 helpURL = (URL ) property; 1117 } else if (property == null) { 1118 helpURL = null; 1119 } 1120 } 1121 1122 private void initBundleProperties() { 1123 contentBackColor = new Color ( 1124 getIntFromBundle("INT_WizardBackRed"), getIntFromBundle("INT_WizardBackGreen"), getIntFromBundle("INT_WizardBackBlue") ); 1129 contentForegroundColor = new Color ( 1130 getIntFromBundle("INT_WizardForegroundRed"), getIntFromBundle("INT_WizardForegroundGreen"), getIntFromBundle("INT_WizardForegroundBlue") ); imageAlignment = bundle.getString("STRING_WizardImageAlignment"); } 1136 1137 1139 public void setValue(Object value) { 1140 setValueOpen(value, data); 1141 } 1142 1143 private <A> void setValueOpen(Object value, SettingsAndIterator<A> data) { 1144 Object convertedValue = backConvertOption(value); 1145 Object oldValue = getValue(); 1147 setValueWithoutPCH(convertedValue); 1148 1149 if (CLOSED_OPTION.equals(convertedValue)) { 1151 try { 1152 resetWizard(); 1153 } catch (RuntimeException x) { 1154 err.log(Level.FINE, null, x); 1156 } 1157 } else if (FINISH_OPTION.equals(convertedValue) || NEXT_OPTION.equals(convertedValue)) { 1158 if (data.current != null) { 1161 data.current.storeSettings(data.getSettings(this)); 1162 } 1163 } 1164 1165 firePropertyChange(PROP_VALUE, oldValue, convertedValue); 1167 } 1168 1169 1170 private void resetWizard() { 1171 resetWizardOpen(data); 1172 } 1173 1174 private <A> void resetWizardOpen(SettingsAndIterator<A> data) { 1175 if (data.current != null) { 1176 data.current.storeSettings(data.getSettings(this)); 1177 data.current.removeChangeListener(weakChangeListener); 1178 data.current = null; 1179 1180 if (wizardPanel != null) { 1181 wizardPanel.resetPreferredSize(); 1182 } 1183 } 1184 1185 callUninitialize(); 1186 1187 data.getIterator(this).removeChangeListener(weakChangeListener); 1189 } 1190 1191 private int getIntFromBundle(String key) { 1192 return Integer.parseInt(bundle.getString(key)); 1193 } 1194 1195 private static Image getDefaultImage() { 1196 return Utilities.loadImage("org/netbeans/modules/dialogs/defaultWizard.gif", true); 1197 } 1198 1199 private void updateButtonAccessibleDescription() { 1200 String stepName = ((contentData != null) && (contentSelectedIndex > 0) && 1201 ((contentSelectedIndex - 1) < contentData.length)) ? contentData[contentSelectedIndex - 1] : ""; previousButton.getAccessibleContext().setAccessibleDescription( 1203 NbBundle.getMessage(WizardDescriptor.class, "ACSD_PREVIOUS", new Integer (contentSelectedIndex), stepName) 1204 ); 1205 1206 stepName = ((contentData != null) && (contentSelectedIndex < (contentData.length - 1)) && 1207 ((contentSelectedIndex + 1) >= 0)) ? contentData[contentSelectedIndex + 1] : ""; nextButton.getAccessibleContext().setAccessibleDescription( 1209 NbBundle.getMessage(WizardDescriptor.class, "ACSD_NEXT", new Integer (contentSelectedIndex + 2), stepName) 1210 ); 1211 } 1212 1213 private void lazyValidate(final WizardDescriptor.Panel panel, final Runnable onValidPerformer) { 1214 1215 Runnable validationPeformer = new Runnable () { 1216 public void run() { 1217 1218 err.log (Level.FINE, "validationPeformer entry."); ValidatingPanel v = (ValidatingPanel) panel; 1220 1221 try { 1222 v.validate(); 1224 validationRuns = false; 1225 1226 if (SwingUtilities.isEventDispatchThread ()) { 1228 err.log (Level.FINE, "Runs onValidPerformer directly in EDT."); onValidPerformer.run(); 1230 } else { 1231 err.log (Level.FINE, "invokeLater onValidPerformer."); SwingUtilities.invokeLater (new Runnable () { 1233 public void run () { 1234 err.log (Level.FINE, "Runs onValidPerformer from invokeLater."); onValidPerformer.run(); 1236 } 1237 }); 1238 } 1239 } catch (WizardValidationException wve) { 1240 validationRuns = false; 1241 updateState (); 1242 1243 if (wizardPanel != null) { 1245 wizardPanel.setErrorMessage(wve.getLocalizedMessage(), Boolean.FALSE); 1246 } 1247 1248 final JComponent comp = wve.getSource(); 1250 if (comp != null && comp.isFocusable()) { 1251 comp.requestFocus(); 1252 } 1253 } 1254 1255 } 1256 }; 1257 1258 if (panel instanceof AsynchronousValidatingPanel) { 1259 AsynchronousValidatingPanel p = (AsynchronousValidatingPanel) panel; 1260 validationRuns = true; p.prepareValidation(); 1262 err.log (Level.FINE, "Do ASYNCHRONOUS_JOBS_RP.post(validationPeformer)."); updateStateWithFeedback (); 1264 backgroundValidationTask = ASYNCHRONOUS_JOBS_RP.post(validationPeformer); 1265 } else if (panel instanceof ValidatingPanel) { 1266 validationRuns = true; 1267 err.log (Level.FINE, "Runs validationPeformer."); validationPeformer.run(); 1269 } else { 1270 err.log (Level.FINE, "Runs onValidPerformer."); onValidPerformer.run(); 1272 } 1273 1274 } 1275 1276 private void callInitialize() { 1278 assert data.getIterator(this) != null; 1279 1280 if (data.getIterator(this) instanceof InstantiatingIterator) { 1281 ((InstantiatingIterator) data.getIterator(this)).initialize(this); 1282 } 1283 1284 newObjects = Collections.EMPTY_SET; 1285 } 1286 1287 private void callUninitialize() { 1288 assert data.getIterator(this) != null; 1289 1290 if (data.getIterator(this) instanceof InstantiatingIterator) { 1291 ((InstantiatingIterator) data.getIterator(this)).uninitialize(this); 1292 } 1293 } 1294 1295 private void callInstantiate() throws IOException { 1296 callInstantiateOpen(data); 1297 } 1298 1299 private <A> void callInstantiateOpen(SettingsAndIterator<A> data) throws IOException { 1300 Iterator<A> panels = data.getIterator(this); 1301 1302 assert panels != null; 1303 1304 err.log (Level.FINE, "Is AsynchronousInstantiatingIterator? " + (panels instanceof AsynchronousInstantiatingIterator)); 1305 err.log (Level.FINE, "Is ProgressInstantiatingIterator? " + (panels instanceof ProgressInstantiatingIterator)); 1306 if (panels instanceof ProgressInstantiatingIterator) { 1307 handle = ProgressHandleFactory.createHandle (PROGRESS_BAR_DISPLAY_NAME); 1308 1309 JComponent progressComp = ProgressHandleFactory.createProgressComponent (handle); 1310 if (wizardPanel != null) { 1311 wizardPanel.setProgressComponent (progressComp, ProgressHandleFactory.createDetailLabelComponent (handle)); 1312 } 1313 1314 err.log (Level.FINE, "Show progressPanel controlled by iterator later."); 1315 } else if (panels instanceof AsynchronousInstantiatingIterator) { 1316 handle = ProgressHandleFactory.createHandle (PROGRESS_BAR_DISPLAY_NAME); 1317 1318 JComponent progressComp = ProgressHandleFactory.createProgressComponent (handle); 1319 if (wizardPanel != null) { 1320 wizardPanel.setProgressComponent (progressComp, ProgressHandleFactory.createMainLabelComponent (handle)); 1321 } 1322 1323 handle.start (); 1324 err.log (Level.FINE, "Show progressPanel later."); 1325 } 1326 1327 panels.current().storeSettings(data.getSettings(this)); 1329 1330 if (panels instanceof InstantiatingIterator) { 1331 showWaitCursor(); 1332 1333 try { 1334 assert ! (panels instanceof AsynchronousInstantiatingIterator) || ! SwingUtilities.isEventDispatchThread () : "Cannot invoked within EDT if AsynchronousInstantiatingIterator!"; 1335 1336 if (panels instanceof ProgressInstantiatingIterator) { 1337 assert handle != null : "ProgressHandle must be not null."; 1338 err.log (Level.FINE, "Calls instantiate(ProgressHandle) on iterator: " + panels.getClass ().getName ()); 1339 newObjects = ((ProgressInstantiatingIterator) panels).instantiate (handle); 1340 } else { 1341 err.log (Level.FINE, "Calls instantiate() on iterator: " + panels.getClass ().getName ()); 1342 newObjects = ((InstantiatingIterator) panels).instantiate (); 1343 } 1344 } finally { 1345 1346 showNormalCursor(); 1348 1349 } 1350 } 1351 } 1352 1353 private static Font doDeriveFont(Font original, int style) { 1354 if (Utilities.isMac()) { 1355 return new Font (original.getName(), style, original.getSize()); 1357 } 1358 1359 return original.deriveFont(style); 1360 } 1361 1362 final void doNextClick() { 1364 if (nextButton.isEnabled()) { 1365 nextButton.doClick(); 1366 } 1367 } 1368 1369 final void doPreviousClick() { 1370 if (previousButton.isEnabled()) { 1371 previousButton.doClick(); 1372 } 1373 } 1374 1375 final void doFinishClick() { 1376 if (finishButton.isEnabled()) { 1377 finishButton.doClick(); 1378 } 1379 } 1380 1381 final void doCancelClick() { 1382 if (cancelButton.isEnabled()) { 1383 cancelButton.doClick(); 1384 } 1385 } 1386 1387 final boolean isNextEnabled() { 1390 return nextButton.isEnabled(); 1391 } 1392 1393 final boolean isFinishEnabled() { 1396 return finishButton.isEnabled(); 1397 } 1398 1399 1402 public interface Iterator<Data> { 1403 1406 public Panel <Data> current(); 1407 1408 1411 public String name(); 1412 1413 1416 public boolean hasNext(); 1417 1418 1421 public boolean hasPrevious(); 1422 1423 1427 public void nextPanel(); 1428 1429 1433 public void previousPanel(); 1434 1435 1439 public void addChangeListener(ChangeListener l); 1440 1441 1444 public void removeChangeListener(ChangeListener l); 1445 } 1446 1447 1455 public interface Panel<Data> { 1456 1465 public java.awt.Component getComponent(); 1466 1467 1471 public HelpCtx getHelp(); 1472 1473 1483 public void readSettings(Data settings); 1484 1485 1498 public void storeSettings(Data settings); 1499 1500 1508 public boolean isValid(); 1509 1510 1514 public void addChangeListener(ChangeListener l); 1515 1516 1519 public void removeChangeListener(ChangeListener l); 1520 } 1521 1522 1528 @Deprecated 1529 public interface FinishPanel<Data> extends Panel <Data> { 1530 } 1531 1532 1536 public interface ValidatingPanel<Data> extends Panel <Data> { 1537 1545 public void validate() throws WizardValidationException; 1546 } 1547 1548 1549 1562 public interface AsynchronousValidatingPanel<Data> extends ValidatingPanel<Data> { 1563 1564 1569 public void prepareValidation(); 1570 1571 1578 public void validate() throws WizardValidationException; 1579 } 1580 1581 1582 1586 public interface FinishablePanel<Data> extends Panel <Data> { 1587 1594 boolean isFinishPanel(); 1595 } 1596 1597 1604 public interface InstantiatingIterator<Data> extends Iterator<Data> { 1605 1610 public Set instantiate() throws IOException ; 1611 1612 1616 public void initialize(WizardDescriptor wizard); 1617 1618 1623 public void uninitialize(WizardDescriptor wizard); 1624 } 1625 1626 1633 public interface AsynchronousInstantiatingIterator<Data> extends InstantiatingIterator<Data> { 1634 1635 1643 public Set instantiate () throws IOException ; 1644 1645 } 1646 1647 1655 public interface ProgressInstantiatingIterator<Data> extends AsynchronousInstantiatingIterator<Data> { 1656 1657 1669 public Set instantiate (ProgressHandle handle) throws IOException ; 1670 1671 } 1672 1673 1675 public static class ArrayIterator<Data> extends Object implements Iterator<Data> { 1676 1678 private Panel <Data>[] panels; 1679 1680 1682 private int index; 1683 1684 1687 public ArrayIterator() { 1688 panels = initializePanels(); 1689 index = 0; 1690 } 1691 1692 1695 public ArrayIterator(Panel <Data>[] array) { 1696 panels = array; 1697 index = 0; 1698 } 1699 1700 1704 @SuppressWarnings ("unchecked") 1705 protected Panel <Data>[] initializePanels() { 1706 return new Panel [0]; 1707 } 1708 1709 1711 public Panel <Data> current() { 1712 return panels[index]; 1713 } 1714 1715 1716 public String name() { 1717 return NbBundle.getMessage( 1718 WizardDescriptor.class, "CTL_ArrayIteratorName", new Integer (index + 1), new Integer (panels.length) 1719 ); 1720 } 1721 1722 1725 public boolean hasNext() { 1726 return index < (panels.length - 1); 1727 } 1728 1729 1732 public boolean hasPrevious() { 1733 return index > 0; 1734 } 1735 1736 1739 public synchronized void nextPanel() { 1740 if ((index + 1) == panels.length) { 1741 throw new java.util.NoSuchElementException (); 1742 } 1743 1744 index++; 1745 } 1746 1747 1750 public synchronized void previousPanel() { 1751 if (index == 0) { 1752 throw new java.util.NoSuchElementException (); 1753 } 1754 1755 index--; 1756 } 1757 1758 1760 public void addChangeListener(ChangeListener l) { 1761 } 1762 1763 1765 public void removeChangeListener(ChangeListener l) { 1766 } 1767 1768 1771 protected void reset() { 1772 index = 0; 1773 } 1774 } 1775 1776 1778 private final class Listener implements ChangeListener , ActionListener { 1779 Listener() { 1780 } 1781 1782 1783 public void stateChanged(ChangeEvent ev) { 1784 updateState(); 1785 } 1786 1787 1788 public void actionPerformed(ActionEvent ev) { 1789 final Iterator<?> panels = data.getIterator(WizardDescriptor.this); 1790 if (wizardPanel != null) { 1791 wizardPanel.setErrorMessage(" ", null); } 1793 1794 Object src = ev.getSource(); 1795 err.log (Level.FINE, "actionPerformed entry. Source: " + src); if (src == nextButton) { 1797 final Dimension previousSize = panels.current().getComponent().getSize(); 1798 Runnable onValidPerformer = new Runnable () { 1799 1800 public void run() { 1801 err.log(Level.FINE, 1802 "onValidPerformer on next button entry."); 1803 panels.nextPanel(); 1804 try { 1805 goToNextStep(previousSize); 1808 } 1809 catch (IllegalStateException ise) { 1810 panels.previousPanel(); 1811 String msg = ise.getMessage(); 1812 if (msg != null) { 1813 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(msg)); 1815 } else { 1816 Exceptions.printStackTrace(ise); 1819 } 1820 updateState(); 1821 } 1822 err.log(Level.FINE, 1823 "onValidPerformer on next button exit."); 1824 } 1825 }; 1826 lazyValidate(panels.current(), onValidPerformer); 1827 } 1828 1829 if (ev.getSource() == previousButton) { 1830 panels.previousPanel(); 1831 1832 updateStateWithFeedback(); 1834 } 1835 1836 if (ev.getSource() == finishButton) { 1837 Runnable onValidPerformer = new Runnable () { 1838 public void run() { 1839 err.log (Level.FINE, "onValidPerformer on finish button entry."); 1841 previousButton.setEnabled (false); 1843 nextButton.setEnabled (false); 1844 finishButton.setEnabled (false); 1845 cancelButton.setEnabled (false); 1846 1847 Runnable performFinish = new Runnable () { 1848 public void run () { 1849 err.log (Level.FINE, "performFinish entry."); Object oldValue = getValue(); 1851 1852 try { 1854 callInstantiate(); 1855 setValueWithoutPCH(OK_OPTION); 1856 resetWizard(); 1857 } catch (IOException ioe) { 1858 err.log(Level.FINE, null, ioe); 1860 1861 setValueWithoutPCH(NEXT_OPTION); 1862 updateStateWithFeedback(); 1863 1864 putProperty(PROP_ERROR_MESSAGE, ioe.getLocalizedMessage()); 1866 1867 return; 1869 } catch (RuntimeException x) { 1870 err.log(Level.FINE, null, x); 1872 1873 setValueWithoutPCH(NEXT_OPTION); 1874 updateStateWithFeedback(); 1875 1876 putProperty(PROP_ERROR_MESSAGE, x.getLocalizedMessage()); 1878 1879 return; 1881 } 1882 firePropertyChange(PROP_VALUE, oldValue, OK_OPTION); 1883 1884 SwingUtilities.invokeLater (new Runnable () { 1885 public void run () { 1886 err.log (Level.FINE, "WD.finishOption.fireActionPerformed()"); 1889 finishOption.fireActionPerformed(); 1890 err.log (Level.FINE, "Set value to OK_OPTION."); 1891 setValue (OK_OPTION); 1892 } 1893 }); 1894 err.log (Level.FINE, "performFinish exit."); } 1896 }; 1897 1898 if (panels instanceof AsynchronousInstantiatingIterator) { 1899 err.log (Level.FINE, "Do ASYNCHRONOUS_JOBS_RP.post(performFinish)."); ASYNCHRONOUS_JOBS_RP.post (performFinish); 1901 } else { 1902 err.log (Level.FINE, "Run performFinish."); performFinish.run (); 1904 } 1905 1906 err.log (Level.FINE, "onValidPerformer on finish button exit."); 1908 } 1909 }; 1910 lazyValidate(panels.current(), onValidPerformer); 1911 } 1912 1913 if (ev.getSource() == cancelButton) { 1914 if (backgroundValidationTask != null) { 1915 backgroundValidationTask.cancel(); 1916 } 1917 Object oldValue = getValue(); 1918 setValueWithoutPCH(CANCEL_OPTION); 1919 1920 if (Arrays.asList(getClosingOptions()).contains(cancelButton)) { 1921 try { 1922 resetWizard(); 1923 } catch (RuntimeException x) { 1924 err.log(Level.FINE, null, x); 1926 } 1927 1928 } 1929 1930 firePropertyChange(PROP_VALUE, oldValue, CANCEL_OPTION); 1931 } 1932 } 1933 } 1934 1935 1937 private class PropL implements PropertyChangeListener { 1938 PropL() { 1939 } 1940 1941 1942 public void propertyChange(PropertyChangeEvent e) { 1943 if (wizardPanel == null) { 1944 return; 1945 } 1946 1947 String propName = e.getPropertyName(); 1948 setPanelProperties((JComponent ) wizardPanel.getRightComponent()); 1949 1950 if (PROP_CONTENT_DATA.equals(propName)) { 1951 wizardPanel.setContent(contentData); 1952 updateButtonAccessibleDescription(); 1953 } else if (PROP_CONTENT_SELECTED_INDEX.equals(propName)) { 1954 wizardPanel.setSelectedIndex(contentSelectedIndex); 1955 updateButtonAccessibleDescription(); 1956 } else if (PROP_CONTENT_BACK_COLOR.equals(propName)) { 1957 wizardPanel.setContentBackColor(contentBackColor); 1958 } else if (PROP_CONTENT_FOREGROUND_COLOR.equals(propName)) { 1959 wizardPanel.setContentForegroundColor(contentForegroundColor); 1960 } else if (PROP_IMAGE.equals(propName)) { 1961 wizardPanel.setImage(image); 1962 } else if (PROP_IMAGE_ALIGNMENT.equals(propName)) { 1963 wizardPanel.setImageAlignment(imageAlignment); 1964 } else if (PROP_HELP_URL.equals(propName)) { 1965 wizardPanel.setHelpURL(helpURL); 1966 } 1967 } 1968 } 1969 1970 1972 1974 private static class ImagedPanel extends JComponent implements Accessible , Runnable { 1975 1976 Image image; 1977 1978 1980 Image tempImage; 1981 1982 1984 Image image2Load; 1985 1986 1987 boolean isDefault = false; 1988 1989 1990 boolean loadPending = false; 1991 boolean north = true; 1992 1993 1994 private final Object IMAGE_LOCK = new Object (); 1995 1996 1999 public ImagedPanel(Image im) { 2000 setImage(im); 2001 setLayout(new BorderLayout ()); 2002 setOpaque(true); 2003 } 2004 2005 2006 protected void paintComponent(Graphics graphics) { 2007 graphics.setColor(getBackground()); 2008 graphics.fillRect(0, 0, getWidth(), getHeight()); 2009 2010 if (image != null) { 2011 graphics.drawImage(image, 0, north ? 0 : (getHeight() - image.getHeight(null)), this); 2012 } else if (image2Load != null) { 2013 loadImageInBackground(image2Load); 2014 image2Load = null; 2015 } 2016 } 2017 2018 public void setImageAlignment(String align) { 2019 north = "North".equals(align); } 2021 2022 2025 public void setImage(Image im) { 2026 if (im != null) { 2027 loadImage(im); 2028 isDefault = false; 2029 2030 return; 2031 } 2032 2033 if (!isDefault) { 2034 loadImage(getDefaultImage()); 2035 isDefault = true; 2036 } 2037 } 2038 2039 private void loadImage(Image im) { 2040 MediaTracker mt = new MediaTracker (this); 2042 mt.addImage(im, 0); 2043 2044 if (mt.checkID(0)) { 2045 image = im; 2046 2047 if (isShowing()) { 2048 repaint(); 2049 } 2050 2051 return; 2052 } 2053 2054 if (isShowing()) { 2057 loadImageInBackground(im); 2058 } else { 2059 synchronized (IMAGE_LOCK) { 2060 image = null; 2061 } 2062 2063 image2Load = im; 2064 } 2065 } 2066 2067 private void loadImageInBackground(Image image) { 2068 synchronized (IMAGE_LOCK) { 2069 tempImage = image; 2070 2071 if (loadPending) { 2073 return; 2074 } 2075 2076 loadPending = true; 2077 } 2078 2079 RequestProcessor.getDefault().post(this, 30); 2081 } 2082 2083 2086 public void run() { 2087 Image localImage; 2088 2089 synchronized (IMAGE_LOCK) { 2091 localImage = tempImage; 2092 tempImage = null; 2093 loadPending = false; 2094 } 2095 2096 ImageIcon localImageIcon = new ImageIcon (localImage); 2098 boolean shouldRepaint = false; 2099 2100 synchronized (IMAGE_LOCK) { 2101 if (!loadPending) { 2103 image = localImageIcon.getImage(); 2104 2105 shouldRepaint = true; 2107 } 2108 } 2109 2110 if (shouldRepaint) { 2111 repaint(); 2112 } 2113 } 2114 } 2115 2116 2119 private static class WrappedCellRenderer extends JPanel implements ListCellRenderer { 2120 JTextArea ta = new JTextArea (); 2121 JLabel numberLabel; 2122 int selected = -1; 2123 boolean contentNumbered; 2124 int taWidth; 2125 2126 2130 private WrappedCellRenderer(boolean contentNumbered, int wrappingWidth) { 2131 super(new BorderLayout ()); 2132 this.contentNumbered = contentNumbered; 2133 2134 ta.setOpaque(false); 2135 ta.setEditable(false); 2136 ta.setLineWrap(true); 2137 ta.setWrapStyleWord(true); 2138 ta.setFont(UIManager.getFont("Label.font")); ta.getAccessibleContext().setAccessibleDescription(""); 2141 taWidth = wrappingWidth - 12 - 12; 2142 2143 numberLabel = new JLabel () { 2144 protected void paintComponent(Graphics g) { 2145 super.paintComponent(g); 2146 2147 if (!WrappedCellRenderer.this.contentNumbered) { 2149 java.awt.Rectangle rect = g.getClipBounds(); 2150 g.fillOval(rect.x, rect.y, 7, 7); 2151 } 2152 } 2153 }; 2154 numberLabel.setLabelFor(ta); numberLabel.setHorizontalAlignment(SwingConstants.LEFT); 2156 numberLabel.setFont(ta.getFont()); 2157 numberLabel.setOpaque(false); 2158 numberLabel.setPreferredSize(new Dimension (25, 0)); 2159 add(numberLabel, BorderLayout.WEST); 2160 taWidth -= 25; 2161 2162 Insets taInsets = ta.getInsets(); 2163 ta.setSize(taWidth, taInsets.top + taInsets.bottom + 1); 2164 2165 add(ta, BorderLayout.CENTER); 2166 setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 12)); 2167 setOpaque(false); 2168 } 2169 2170 public Component getListCellRendererComponent( 2171 JList list, Object value, int index, boolean isSelected, boolean cellHasFocus 2172 ) { 2173 if (index == selected) { 2174 numberLabel.setFont(doDeriveFont(numberLabel.getFont(), Font.BOLD)); 2175 ta.setFont(doDeriveFont(ta.getFont(), Font.BOLD)); 2176 } else { 2177 numberLabel.setFont(doDeriveFont(numberLabel.getFont(), Font.PLAIN)); 2178 ta.setFont(doDeriveFont(ta.getFont(), Font.PLAIN)); 2179 } 2180 2181 if (contentNumbered) { 2182 numberLabel.setText(Integer.toString(index + 1) + "."); } 2184 2185 Insets taInsets = ta.getInsets(); 2187 ta.setSize(taWidth, taInsets.top + taInsets.bottom + 1); 2188 ta.setText((String ) value); 2189 2190 return this; 2191 } 2192 2193 private void setSelectedIndex(int i) { 2194 selected = i; 2195 } 2196 2197 private void setForegroundColor(Color color) { 2198 if (numberLabel != null) { 2199 numberLabel.setForeground(color); 2200 numberLabel.setBackground(color); 2201 } 2202 2203 ta.setForeground(color); 2204 } 2205 } 2206 2207 2209 private static class WizardPanel extends JPanel { 2210 2211 private JPanel rightPanel = new JPanel (new BorderLayout ()); 2212 2213 2214 private JLabel panelName = new JLabel ("Step"); 2216 2217 private JList contentList; 2218 2219 2220 private Component rightComponent; 2221 2222 2223 private ImagedPanel contentPanel; 2224 2225 2226 private JPanel contentLabelPanel; 2227 2228 2229 private WrappedCellRenderer cellRenderer; 2230 2231 2232 private JTabbedPane tabbedPane; 2233 2234 2235 private HtmlBrowser htmlBrowser; 2236 2237 2238 private Dimension cachedDimension; 2239 2240 2241 private JLabel label; 2242 2243 private JPanel progressBarPanel; 2244 2245 2246 private int selectedIndex; 2247 private javax.swing.JLabel m_lblMessage; 2248 private Color nbErrorForeground; 2249 private Color nbWarningForeground; 2250 2251 2257 public WizardPanel( 2258 boolean contentDisplayed, boolean helpDispalyed, boolean contentNumbered, Dimension leftDimension 2259 ) { 2260 super(new BorderLayout ()); 2261 initComponents(contentDisplayed, helpDispalyed, contentNumbered, leftDimension); 2262 setOpaque(false); 2263 resetPreferredSize(); 2264 } 2265 2266 private void initComponents( 2267 boolean contentDisplayed, boolean helpDisplayed, boolean contentNumbered, Dimension leftDimension 2268 ) { 2269 if (contentDisplayed) { 2270 createContentPanel(contentNumbered, leftDimension); 2271 2272 if (!helpDisplayed) { 2273 add(contentPanel, BorderLayout.WEST); 2274 } 2275 } 2276 2277 if (helpDisplayed) { 2278 htmlBrowser = new BoundedHtmlBrowser(leftDimension); 2279 htmlBrowser.setPreferredSize(leftDimension); 2280 2281 if (!contentDisplayed) { 2282 add(htmlBrowser, BorderLayout.WEST); 2283 } 2284 } 2285 2286 if (helpDisplayed && contentDisplayed) { 2287 tabbedPane = new JTabbedPane (JTabbedPane.BOTTOM); 2288 tabbedPane.addTab(NbBundle.getMessage(WizardDescriptor.class, "CTL_ContentName"), contentPanel); 2289 tabbedPane.addTab(NbBundle.getMessage(WizardDescriptor.class, "CTL_HelpName"), htmlBrowser); 2290 tabbedPane.setEnabledAt(1, false); 2291 tabbedPane.setOpaque(false); 2292 2293 add(tabbedPane, BorderLayout.WEST); 2295 } 2296 2297 panelName.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, panelName.getForeground())); 2298 panelName.setFont(doDeriveFont(panelName.getFont(), Font.BOLD)); 2299 2300 JPanel labelPanel = new JPanel (new BorderLayout ()); 2301 labelPanel.add(panelName, BorderLayout.NORTH); 2302 labelPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 11)); 2303 rightPanel.setBorder(BorderFactory.createEmptyBorder(0, 12, 11, 11)); 2304 panelName.setLabelFor(labelPanel); 2305 2306 nbErrorForeground = UIManager.getColor("nb.errorForeground"); if (nbErrorForeground == null) { 2308 nbErrorForeground = new Color (255, 0, 0); } 2311 2312 nbWarningForeground = UIManager.getColor("nb.warningForeground"); if (nbWarningForeground == null) { 2314 nbWarningForeground = new Color (51, 51, 51); } 2316 2317 JPanel errorPanel = new JPanel (new BorderLayout ()); 2318 errorPanel.setBorder(BorderFactory.createEmptyBorder(0, 12, 12, 11)); 2319 m_lblMessage = new FixedHeightLabel (); 2320 m_lblMessage.setForeground (nbErrorForeground); 2321 errorPanel.add(m_lblMessage, BorderLayout.CENTER); 2322 2323 progressBarPanel = new JPanel (new BorderLayout ()); 2324 progressBarPanel.setVisible (false); 2325 2326 if (contentDisplayed) { 2327 progressBarPanel.setOpaque (false); 2329 progressBarPanel.setBorder (BorderFactory.createEmptyBorder (0, 4, 7, 4)); 2330 contentPanel.add (progressBarPanel, BorderLayout.SOUTH); 2331 } else { 2332 progressBarPanel.add (new JLabel (), BorderLayout.NORTH); 2334 JProgressBar pb = new JProgressBar (); 2335 pb.setOrientation (JProgressBar.HORIZONTAL); 2336 pb.setAlignmentX(0.5f); 2337 pb.setAlignmentY(0.5f); 2338 pb.setString ("0"); progressBarPanel.add (pb, BorderLayout.CENTER); 2340 2341 progressBarPanel.setBorder (BorderFactory.createEmptyBorder (4, 0, 0, 0)); 2342 errorPanel.add (progressBarPanel, BorderLayout.SOUTH); 2343 } 2344 2345 JPanel fullRightPanel = new JPanel (new BorderLayout ()); 2346 fullRightPanel.add(labelPanel, BorderLayout.NORTH); 2347 fullRightPanel.add(rightPanel, BorderLayout.CENTER); 2348 fullRightPanel.add(errorPanel, BorderLayout.SOUTH); 2349 2350 add(fullRightPanel, BorderLayout.CENTER); 2352 2353 if (getBorder() == null) { 2354 JSeparator sep = new JSeparator (); 2356 sep.setForeground(Color.darkGray); 2357 add(sep, BorderLayout.SOUTH); 2358 } 2359 } 2360 2361 public void setErrorMessage(String msg, Boolean canContinue) { 2362 m_lblMessage.setForeground(nbErrorForeground); 2363 if (msg != null && msg.trim ().length () > 0 && canContinue != null) { 2364 if (canContinue.booleanValue ()) { 2365 m_lblMessage.setIcon (new ImageIcon (Utilities.loadImage ("org/netbeans/modules/dialogs/warning.gif"))); m_lblMessage.setForeground (nbWarningForeground); 2367 } else { 2368 m_lblMessage.setIcon (new ImageIcon (Utilities.loadImage ("org/netbeans/modules/dialogs/error.gif"))); } 2370 m_lblMessage.setToolTipText (msg); 2371 } else { 2372 m_lblMessage.setIcon (null); 2373 m_lblMessage.setToolTipText (null); 2374 } 2375 2376 m_lblMessage.setText(msg); 2377 } 2378 2379 private void setProgressComponent (JComponent progressComp, JLabel progressLabel) { 2380 if (progressLabel != null) { 2381 progressLabel.setText (PROGRESS_BAR_DISPLAY_NAME); 2382 progressBarPanel.add (progressLabel, BorderLayout.NORTH); 2383 } 2384 progressBarPanel.add (progressComp, BorderLayout.CENTER); 2385 progressBarPanel.setVisible (true); 2386 } 2387 2388 2392 private void createContentPanel(boolean contentNumbered, Dimension leftDimension) { 2393 contentList = new JList (); 2394 cellRenderer = new WrappedCellRenderer(contentNumbered, leftDimension.width); 2395 cellRenderer.setOpaque(false); 2396 contentList.setCellRenderer(cellRenderer); 2397 contentList.setOpaque(false); 2398 contentList.setEnabled(false); 2399 contentList.getAccessibleContext().setAccessibleDescription(""); 2401 JScrollPane scroll = new JScrollPane (contentList); 2402 scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 2403 scroll.getViewport().setOpaque(false); 2404 scroll.setBorder(null); 2405 scroll.setOpaque(false); 2406 scroll.setViewportBorder(null); 2408 2409 label = new JLabel (NbBundle.getMessage(WizardDescriptor.class, "CTL_ContentName")); 2410 label.setForeground(Color.white); 2411 label.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, label.getForeground())); 2412 label.setFont(doDeriveFont(label.getFont(), Font.BOLD)); 2413 contentLabelPanel = new JPanel (new BorderLayout ()); 2414 contentLabelPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 11, 11)); 2415 contentLabelPanel.setOpaque(false); 2416 contentLabelPanel.add(label, BorderLayout.NORTH); 2417 2418 contentPanel = new ImagedPanel(null); 2419 contentPanel.add(contentLabelPanel, BorderLayout.NORTH); 2420 contentPanel.add(scroll, BorderLayout.CENTER); 2421 2422 contentPanel.setPreferredSize(leftDimension); 2423 label.setLabelFor(contentList); 2424 } 2425 2426 2429 public void setContent(final String [] content) { 2430 final JList list = contentList; 2431 2432 if (list == null) { 2433 return; 2434 } 2435 2436 Mutex.EVENT.writeAccess( 2440 new Runnable () { 2441 public void run() { 2442 list.setListData(content); 2443 list.revalidate(); 2444 list.repaint(); 2445 contentLabelPanel.setVisible(content.length > 0); 2446 } 2447 } 2448 ); 2449 } 2450 2451 2454 public void setSelectedIndex(final int index) { 2455 selectedIndex = index; 2456 2457 if (cellRenderer != null) { 2458 cellRenderer.setSelectedIndex(index); 2459 2460 final JList list = contentList; 2461 2462 if (list == null) { 2463 return; 2464 } 2465 2466 Mutex.EVENT.readAccess( 2468 new Runnable () { 2469 public void run() { 2470 list.ensureIndexIsVisible(index); 2471 2472 list.setFixedCellWidth(0); 2478 list.setFixedCellWidth(-1); 2479 } 2480 } 2481 ); 2482 } 2483 } 2484 2485 2488 public void setContentBackColor(Color color) { 2489 if (contentPanel != null) { 2490 contentPanel.setBackground(color); 2491 } 2492 } 2493 2494 2497 public void setContentForegroundColor(Color color) { 2498 if (cellRenderer == null) { 2499 return; 2500 } 2501 2502 cellRenderer.setForegroundColor(color); 2503 label.setForeground(color); 2504 label.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, label.getForeground())); 2505 } 2506 2507 2510 public void setImage(Image image) { 2511 if (contentPanel != null) { 2512 contentPanel.setImage(image); 2513 } 2514 } 2515 2516 2519 public void setImageAlignment(String align) { 2520 if (contentPanel != null) { 2521 contentPanel.setImageAlignment(align); 2522 } 2523 } 2524 2525 2528 public void setRightComponent(Component c) { 2529 if (rightComponent != null) { 2530 rightPanel.remove(rightComponent); 2531 } 2532 2533 rightComponent = c; 2534 rightPanel.add(rightComponent, BorderLayout.CENTER); 2535 2536 } 2538 2539 2542 public Component getRightComponent() { 2543 return rightComponent; 2544 } 2545 2546 2549 public void setPanelName(String name) { 2550 panelName.setText(name); 2551 } 2552 2553 2556 public void setHelpURL(URL helpURL) { 2557 if (htmlBrowser == null) { 2558 return; 2559 } 2560 2561 if (helpURL != null) { 2562 if (!helpURL.equals(htmlBrowser.getDocumentURL())) { 2563 htmlBrowser.setURL(helpURL); 2564 } 2565 2566 if (tabbedPane != null) { 2567 tabbedPane.setEnabledAt(tabbedPane.indexOfComponent(htmlBrowser), true); 2568 } 2569 } else if (tabbedPane != null) { 2570 tabbedPane.setSelectedComponent(contentPanel); 2571 tabbedPane.setEnabledAt(tabbedPane.indexOfComponent(htmlBrowser), false); 2572 } 2573 } 2574 2575 public void resetPreferredSize() { 2576 cachedDimension = new Dimension (600, 365); 2577 } 2578 2579 public Dimension getPreferredSize() { 2580 Dimension dim = super.getPreferredSize(); 2581 2582 if (dim.height > cachedDimension.height) { 2583 cachedDimension.height = dim.height; 2584 } 2585 2586 if (dim.width > cachedDimension.width) { 2587 cachedDimension.width = dim.width; 2588 } 2589 2590 return cachedDimension; 2591 } 2592 2593 2595 public void requestFocus() { 2596 if ((rightComponent != null) && rightComponent.isDisplayable()) { 2597 JComponent comp = (JComponent ) rightComponent; 2598 Container rootAnc = comp.getFocusCycleRootAncestor(); 2599 FocusTraversalPolicy policy = rootAnc.getFocusTraversalPolicy(); 2600 Component focus = policy.getComponentAfter(rootAnc, comp); 2601 2602 if (focus != null) { 2603 focus.requestFocus(); 2604 } else { 2605 comp.requestFocus(); 2606 } 2607 } else { 2608 super.requestFocus(); 2609 } 2610 } 2611 2612 2614 @Deprecated 2615 public boolean requestDefaultFocus() { 2616 if (rightComponent instanceof JComponent ) { 2617 return ((JComponent ) rightComponent).requestDefaultFocus(); 2618 } 2619 2620 return super.requestDefaultFocus(); 2621 } 2622 2623 public javax.accessibility.AccessibleContext getAccessibleContext() { 2624 if (accessibleContext == null) { 2625 accessibleContext = new AccessibleWizardPanel(); 2626 } 2627 2628 return accessibleContext; 2629 } 2630 2631 private class AccessibleWizardPanel extends AccessibleJPanel { 2632 AccessibleWizardPanel() { 2633 } 2634 2635 public String getAccessibleDescription() { 2636 if (accessibleDescription != null) { 2637 return accessibleDescription; 2638 } 2639 2640 if (rightComponent instanceof Accessible ) { 2641 if (rightComponent.getAccessibleContext().getAccessibleDescription() == null) { 2642 return null; 2643 } 2644 2645 return NbBundle.getMessage( 2646 WizardDescriptor.class, "ACSD_WizardPanel", new Integer (selectedIndex + 1), panelName.getText(), 2647 rightComponent.getAccessibleContext().getAccessibleDescription() 2648 ); 2649 } 2650 2651 return super.getAccessibleDescription(); 2652 } 2653 } 2654 } 2655 2656 2657 private static class BoundedHtmlBrowser extends HtmlBrowser { 2658 Dimension dim; 2659 2660 public BoundedHtmlBrowser(Dimension d) { 2661 super(false, false); 2662 dim = d; 2663 } 2664 2665 public Dimension getPreferredSize() { 2666 return dim; 2667 } 2668 } 2669 2670 static class FinishAction extends Object { 2672 ActionListener listner; 2673 2674 public void addActionListener(ActionListener ac) { 2675 listner = ac; 2676 } 2677 2678 public void removeActionListener(ActionListener ac) { 2679 listner = null; 2680 } 2681 2682 public void fireActionPerformed() { 2683 if (listner != null) { 2684 listner.actionPerformed(new ActionEvent (this, 0, "")); 2685 } 2686 } 2687 } 2688 2689 private static final class FixedHeightLabel extends JLabel { 2690 2691 private static final int ESTIMATED_HEIGHT = 16; 2692 2693 public FixedHeightLabel () { 2694 super (); 2695 } 2696 2697 public Dimension getPreferredSize() { 2698 Dimension preferredSize = super.getPreferredSize(); 2699 assert ESTIMATED_HEIGHT == Utilities.loadImage ("org/netbeans/modules/dialogs/warning.gif").getHeight (null) : "Use only 16px icon."; 2700 preferredSize.height = Math.max (ESTIMATED_HEIGHT, preferredSize.height); 2701 return preferredSize; 2702 } 2703 } 2704 2705 private static final class SettingsAndIterator<Data> { 2706 private final Iterator<Data> panels; 2707 private final Data settings; 2708 private final boolean useThis; 2709 2710 private Panel <Data> current; 2711 2712 2713 public SettingsAndIterator(Iterator<Data> iterator, Data settings) { 2714 this(iterator, settings, false); 2715 } 2716 public SettingsAndIterator(Iterator<Data> iterator, Data settings, boolean useThis) { 2717 this.panels = iterator; 2718 this.settings = settings; 2719 this.useThis = useThis; 2720 } 2721 public static SettingsAndIterator<WizardDescriptor> create(Iterator<WizardDescriptor> iterator) { 2722 return new SettingsAndIterator<WizardDescriptor>(iterator, null, true); 2723 } 2724 2725 public Iterator<Data> getIterator(WizardDescriptor caller) { 2726 return panels; 2727 } 2728 2729 @SuppressWarnings ("unchecked") 2730 public Data getSettings(WizardDescriptor caller) { 2731 return useThis ? (Data)caller : settings; 2732 } 2733 2734 public SettingsAndIterator<Data> clone(Iterator<Data> it) { 2735 SettingsAndIterator<Data> s = new SettingsAndIterator<Data>(it, settings, useThis); 2736 return s; 2737 } 2738 } 2739} 2740 | Popular Tags |