Index: projects/projectuiapi/apichanges.xml =================================================================== RCS file: /cvs/projects/projectuiapi/apichanges.xml,v retrieving revision 1.14 diff -u -r1.14 apichanges.xml --- projects/projectuiapi/apichanges.xml 14 Jul 2005 20:32:51 -0000 1.14 +++ projects/projectuiapi/apichanges.xml 17 Jul 2005 19:53:26 -0000 @@ -76,6 +76,25 @@ + + + Added ability to set whether a project customizer's categories are valid + + + + + +

+ Added ProjectCustomizer.Category.setValid and + ProjectCustomizer.Category.isValid methods. + With those methods client can affect enability of the OK + button of the Customizer dialog. +

+
+ + +
+ Delete Action Added Index: projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java =================================================================== RCS file: /cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java,v retrieving revision 1.2 diff -u -r1.2 CustomizerDialog.java --- projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java 3 Mar 2005 17:43:36 -0000 1.2 +++ projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java 17 Jul 2005 19:53:26 -0000 @@ -20,6 +20,7 @@ import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JPanel; +import org.netbeans.spi.project.ui.support.ProjectCustomizer; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.util.HelpCtx; @@ -44,14 +45,20 @@ private static final String COMMAND_OK = "OK"; // NOI18N private static final String COMMAND_CANCEL = "CANCEL"; // NOI18N - public static Dialog createDialog( ActionListener okOptionListener, JPanel innerPane, HelpCtx helpCtx ) { + public static Dialog createDialog( ActionListener okOptionListener, JPanel innerPane, + HelpCtx helpCtx, ProjectCustomizer.Category[] categories ) { + + ListeningButton okButton = new ListeningButton( + NbBundle.getMessage(CustomizerDialog.class, "LBL_Customizer_Ok_Option"), + categories); // NOI18N + okButton.setEnabled(CustomizerDialog.checkValidity(categories)); // Create options JButton options[] = new JButton[] { - new JButton( NbBundle.getMessage( CustomizerDialog.class, "LBL_Customizer_Ok_Option") ), // NOI18N + okButton, new JButton( NbBundle.getMessage( CustomizerDialog.class, "LBL_Customizer_Cancel_Option" ) ) , // NOI18N }; - + // Set commands options[ OPTION_OK ].setActionCommand( COMMAND_OK ); options[ OPTION_CANCEL ].setActionCommand( COMMAND_CANCEL ); @@ -92,8 +99,18 @@ Dialog dialog = DialogDisplayer.getDefault().createDialog( dialogDescriptor ); return dialog; - } + } + /** Returns whether all given categories are valid or not. */ + private static boolean checkValidity(ProjectCustomizer.Category[] categories) { + for (int i = 0; i < categories.length; i++) { + if (!categories[i].isValid()) { + return false; + } + } + return true; + } + /** Listens to the actions on the Customizer's option buttons */ private static class OptionListener implements ActionListener { @@ -135,6 +152,28 @@ } } + + private static class ListeningButton extends JButton implements PropertyChangeListener { + + private ProjectCustomizer.Category[] categories; + + public ListeningButton(String label, ProjectCustomizer.Category[] categories) { + super(label); + this.categories = categories; + for (int i = 0; i < categories.length; i++) { + categories[i].addPropertyChangeListener(this); + } + + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName() == ProjectCustomizer.Category.VALID_PROPERTY) { + boolean valid = ((Boolean) evt.getNewValue()).booleanValue(); + // enable only if all categories are valid + setEnabled(valid && CustomizerDialog.checkValidity(categories)); + } + } + + } - } Index: projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java =================================================================== RCS file: /cvs/projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java,v retrieving revision 1.2 diff -u -r1.2 ProjectCustomizer.java --- projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java 15 May 2005 15:43:57 -0000 1.2 +++ projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java 17 Jul 2005 19:53:26 -0000 @@ -16,6 +16,8 @@ import java.awt.Dialog; import java.awt.Image; import java.awt.event.ActionListener; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import javax.swing.JComponent; import javax.swing.JPanel; @@ -23,6 +25,7 @@ import org.netbeans.modules.project.uiapi.CategoryView; import org.netbeans.modules.project.uiapi.CustomizerDialog; import org.netbeans.modules.project.uiapi.CustomizerPane; +import org.netbeans.spi.project.ui.support.ProjectCustomizer.Category; import org.openide.util.HelpCtx; /** Support for creating dialogs which can be used as project @@ -41,13 +44,16 @@ * of {@link org.netbeans.spi.project.ui.CustomizerProvider}. You don't need * to call pack() method on the dialog. The resulting dialog will * be non-modal.
- * Call show() on the dialog to make it visible. If you wnat the dialog to be + * Call show() on the dialog to make it visible. If you want the dialog to be * closed after user presses the "OK" button you have to call hide() and dispose() on it. * (Usually in the actionPerformed(...) method of the listener * you provided as a parameter. In case of the click on the "Cancel" button * the dialog will be closed automatically. - * @param categories array of descriptions of categories to be shown in - * the dialog. + * @param categories array of descriptions of categories to be shown in the + * dialog. Note that categories have the valid + * property. If any of the given categories is not valid cusomizer's + * OK button will be disabled until all categories become valid + * again. * @param componentProvider creator of GUI components for categories in the * customizer dialog. * @param preselectedCategory name of one of the supplied categories or null. @@ -65,8 +71,8 @@ String preselectedCategory, ActionListener okOptionListener, HelpCtx helpCtx ) { - JPanel innerPane = createCustomizerPane( categories, componentProvider, preselectedCategory ); - Dialog dialog = CustomizerDialog.createDialog( okOptionListener, innerPane, helpCtx ); + CustomizerPane innerPane = (CustomizerPane) createCustomizerPane( categories, componentProvider, preselectedCategory ); + Dialog dialog = CustomizerDialog.createDialog( okOptionListener, innerPane, helpCtx, categories ); return dialog; } @@ -112,7 +118,13 @@ private String displayName; private Image icon; private Category[] subcategories; + private boolean valid; + + private PropertyChangeSupport changeSupport; + /** Name for the valid property. */ + public static final String VALID_PROPERTY = "isCategoryValid"; // NOI18N + /** Private constructor. See the factory method. */ private Category( String name, @@ -124,6 +136,7 @@ this.displayName = displayName; this.icon = icon; this.subcategories = subcategories; + this.valid = true; // default } /** Factory method which creates new category description. @@ -170,6 +183,57 @@ public Category[] getSubcategories() { return this.subcategories; } + + /** + * Returns whether this category is valid or not. See {@link + * ProjectCustomizer#createCustomizerDialog} for more details. + * @return whether this category is valid or not (true by default) + */ + public boolean isValid() { + return valid; + } + + /** + * Set a validity of this category. See {@link + * ProjectCustomizer#createCustomizerDialog} for more details. + * @param valid set whether this category is valid or not + */ + public void setValid(boolean valid) { + if (this.valid != valid) { + this.valid = valid; + firePropertyChange(VALID_PROPERTY, Boolean.valueOf(!valid), Boolean.valueOf(valid)); + } + } + + public synchronized void addPropertyChangeListener( + PropertyChangeListener listener) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(listener); + } + + public synchronized void removePropertyChangeListener( + PropertyChangeListener listener) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(listener); + } + + protected void firePropertyChange(String propertyName, + Object oldValue, Object newValue) { + PropertyChangeSupport changeSupport = this.changeSupport; + if (changeSupport == null || + (oldValue != null && newValue != null && oldValue.equals(newValue))) { + return; + } + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + } - + }