This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 23116
Collapse All | Expand All

(-)test/unit/src/org/openide/WizardDescTest.java (-2 / +65 lines)
Lines 102-117 Link Here
102
        assertEquals ("Closed with cancel option.", WizardDescriptor.CANCEL_OPTION, wd.getValue ());
102
        assertEquals ("Closed with cancel option.", WizardDescriptor.CANCEL_OPTION, wd.getValue ());
103
    }
103
    }
104
104
105
    public void testNextOptionWhenLazyValidationFails () throws Exception {
106
        Panel panels[] = new Panel[3];
107
        
108
        class MyPanel extends Panel implements WizardDescriptor.ValidatingPanel {
109
            public String validateMsg;
110
            public String failedMsg;
111
            
112
            public MyPanel () {
113
                super ("enhanced panel");
114
            }
115
            
116
            public void validate () throws WizardValidationException {
117
                if (validateMsg != null) {
118
                    failedMsg = validateMsg;
119
                    throw new WizardValidationException (null, validateMsg);
120
                }
121
                return;
122
            }
123
        }
124
        
125
        class MyFinishPanel extends MyPanel implements WizardDescriptor.FinishPanel {
126
        }
127
        
128
        MyPanel mp = new MyPanel ();
129
        MyFinishPanel mfp = new MyFinishPanel ();
130
        panels[0] = mp;
131
        panels[1] = mfp;
132
        panels[2] = new Panel ("Last one");
133
        wd = new WizardDescriptor(panels);
134
        
135
        assertNull ("Component has not been yet initialized", panels[1].component);
136
        mp.failedMsg = null;
137
        mp.validateMsg = "xtest-fail-without-msg";
138
        wd.doNextClick ();
139
        assertEquals ("The lazy validation failed on Next.", mp.validateMsg, mp.failedMsg);
140
        assertNull ("The lazy validation failed, still no initialiaation", panels[1].component);
141
        assertNull ("The lazy validation failed, still no initialiaation", panels[2].component);
142
        mp.failedMsg = null;
143
        mp.validateMsg = null;
144
        wd.doNextClick ();
145
        assertNull ("Validation on Next passes", mp.failedMsg);
146
        assertNotNull ("Now we switched to another panel", panels[1].component);
147
        assertNull ("The lazy validation failed, still no initialiaation", panels[2].component);
148
        
149
        // remember previous state
150
        Object state = wd.getValue();
151
        mfp.validateMsg = "xtest-fail-without-msg";
152
        mfp.failedMsg = null;
153
        wd.doFinishClick();
154
        assertEquals ("The lazy validation failed on Finish.", mfp.validateMsg, mfp.failedMsg);
155
        assertNull ("The validation failed, still no initialiaation", panels[2].component);
156
        assertEquals ("State has not changed", state, wd.getValue ());
157
        
158
        mfp.validateMsg = null;
159
        mfp.failedMsg = null;
160
        wd.doFinishClick ();
161
        assertNull ("Validation on Finish passes", mfp.failedMsg);        
162
        assertNull ("Finish was clicked, no initialization either", panels[2].component);
163
        assertEquals ("The state is finish", WizardDescriptor.FINISH_OPTION, wd.getValue ());
164
    }
105
    
165
    
106
    public class Panel implements WizardDescriptor.Panel, WizardDescriptor.FinishPanel {
166
    public class Panel implements WizardDescriptor.Panel, WizardDescriptor.FinishPanel {
107
167
        private JLabel component;
108
        private String text;
168
        private String text;
109
        public Panel(String text) {
169
        public Panel(String text) {
110
            this.text = text;
170
            this.text = text;
111
        }
171
        }
112
        
172
        
113
        public Component getComponent() {
173
        public Component getComponent() {
114
            return new JLabel(text);
174
            if (component == null) {
175
                component = new JLabel (text);
176
            }
177
            return component;
115
        }
178
        }
116
        
179
        
117
        public void addChangeListener(ChangeListener l) {
180
        public void addChangeListener(ChangeListener l) {
(-)src/org/openide/WizardDescriptor.java (-6 / +84 lines)
Lines 7-13 Link Here
7
 * http://www.sun.com/
7
 * http://www.sun.com/
8
 * 
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
11
 * Microsystems, Inc. All Rights Reserved.
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
12
 */
13
13
Lines 267-273 Link Here
267
        cancelButton.addActionListener (listener);
267
        cancelButton.addActionListener (listener);
268
268
269
        super.setOptions (new Object[] { previousButton, nextButton, finishButton, cancelButton });
269
        super.setOptions (new Object[] { previousButton, nextButton, finishButton, cancelButton });
270
        super.setClosingOptions (new Object[] { finishButton, cancelButton });
270
        super.setClosingOptions (new Object[] { WizardDescriptor.FinishAction.FINISH_ACTION, cancelButton });
271
271
272
        this.panels = panels;
272
        this.panels = panels;
273
        panels.addChangeListener (listener);
273
        panels.addChangeListener (listener);
Lines 1013-1018 Link Here
1013
    public interface FinishPanel extends Panel {
1013
    public interface FinishPanel extends Panel {
1014
    }
1014
    }
1015
1015
1016
    /** A special interface for panels that need to do additional
1017
     * validation when Next or Finish button is clicked.
1018
     */
1019
    public interface ValidatingPanel extends Panel {
1020
1021
        /**
1022
         * Is called when Next of Finish buttons are clicked and
1023
         * allows deeper check to find out that panel is in valid
1024
         * state and it is ok to leave it.
1025
         *
1026
         * @throws WizardValidationException when validation fails
1027
         */
1028
        public void validate () throws WizardValidationException;
1029
    }
1030
    
1016
    /** Special iterator that works on an array of <code>Panel</code>s.
1031
    /** Special iterator that works on an array of <code>Panel</code>s.
1017
    */
1032
    */
1018
    public static class ArrayIterator extends Object implements Iterator {
1033
    public static class ArrayIterator extends Object implements Iterator {
Lines 1109-1114 Link Here
1109
        }
1124
        }
1110
1125
1111
    }
1126
    }
1127
    
1128
    private boolean lazyValidate (WizardDescriptor.Panel panel, WizardDescriptor.WizardPanel wizard) {
1129
        if (panel instanceof ValidatingPanel) {
1130
            ValidatingPanel v = (ValidatingPanel)panel;
1131
            try {
1132
                // try validation current panel
1133
                v.validate();
1134
            } catch (WizardValidationException wve) {
1135
                // cannot continue, notify user
1136
                if (wizardPanel != null) {
1137
                    wizardPanel.setErrorMessage (wve.getLocalizedMessage ());
1138
                }
1139
                // focus source of this problem
1140
                if (wve.getSource () != null) {
1141
                    final JComponent comp = (JComponent) wve.getSource ();
1142
                    if (comp.isFocusable ()) {
1143
                        comp.requestFocus ();
1144
                    }
1145
                }
1146
                // lazy validation failed
1147
                return false;
1148
            }
1149
        }
1150
        return true;
1151
    }
1112
1152
1113
    /** Listener to changes in the iterator and panels.
1153
    /** Listener to changes in the iterator and panels.
1114
    */
1154
    */
Lines 1120-1127 Link Here
1120
        }
1160
        }
1121
        /** Action listener */
1161
        /** Action listener */
1122
        public void actionPerformed (ActionEvent ev) {
1162
        public void actionPerformed (ActionEvent ev) {
1163
            if (wizardPanel != null) {
1164
                wizardPanel.setErrorMessage(" "); //NOI18N
1165
            }
1123
            if (ev.getSource () == nextButton) {
1166
            if (ev.getSource () == nextButton) {
1124
                Dimension previousSize = panels.current().getComponent().getSize();
1167
                Dimension previousSize = panels.current().getComponent().getSize();
1168
                
1169
                // do lazy validation
1170
                if (!lazyValidate (panels.current (), wizardPanel)) {
1171
                    // if validation failed => cannot move to next panel
1172
                    return ;
1173
                }
1174
                
1125
                panels.nextPanel ();
1175
                panels.nextPanel ();
1126
                try {
1176
                try {
1127
                    // change UI to show next step, show wait cursor during
1177
                    // change UI to show next step, show wait cursor during
Lines 1142-1156 Link Here
1142
            }
1192
            }
1143
1193
1144
            if (ev.getSource () == previousButton) {
1194
            if (ev.getSource () == previousButton) {
1145
                if (wizardPanel != null) {
1146
                    wizardPanel.setErrorMessage(" "); //NOI18N
1147
                }
1148
                panels.previousPanel ();
1195
                panels.previousPanel ();
1149
                // show wait cursor when updating previous button
1196
                // show wait cursor when updating previous button
1150
                updateStateWithFeedback ();
1197
                updateStateWithFeedback ();
1151
            }
1198
            }
1152
1199
1153
            if (ev.getSource () == finishButton) {
1200
            if (ev.getSource () == finishButton) {
1201
                
1202
                // do lazy validation
1203
                if (!lazyValidate (panels.current (), wizardPanel)) {
1204
                    // if validation failed => cannot move to next panel
1205
                    return ;
1206
                }
1207
                
1208
                // all is OK
1209
1210
                // close wizrd
1211
                FinishAction.FINISH_ACTION.fireActionPerformed ();
1154
                Object oldValue = getValue ();
1212
                Object oldValue = getValue ();
1155
                setValueWithoutPCH (OK_OPTION);
1213
                setValueWithoutPCH (OK_OPTION);
1156
                if (Arrays.asList(getClosingOptions()).contains(finishButton)) {
1214
                if (Arrays.asList(getClosingOptions()).contains(finishButton)) {
Lines 1168-1173 Link Here
1168
                firePropertyChange (PROP_VALUE, oldValue, CANCEL_OPTION);
1226
                firePropertyChange (PROP_VALUE, oldValue, CANCEL_OPTION);
1169
            }
1227
            }
1170
        }
1228
        }
1229
        
1171
    }
1230
    }
1172
    
1231
    
1173
    /** Listenes on a users client property changes
1232
    /** Listenes on a users client property changes
Lines 1526-1532 Link Here
1526
        public void setErrorMessage(String msg) {
1585
        public void setErrorMessage(String msg) {
1527
            m_lblMessage.setText(msg);
1586
            m_lblMessage.setText(msg);
1528
        }
1587
        }
1529
1588
        
1530
        /** Creates content panel.
1589
        /** Creates content panel.
1531
         * @param contentNumbered <CODE>boolean</CODE> whether content will be numbered
1590
         * @param contentNumbered <CODE>boolean</CODE> whether content will be numbered
1532
         * @param leftDimension <CODE>Dimension</CODE> dimension of content pane
1591
         * @param leftDimension <CODE>Dimension</CODE> dimension of content pane
Lines 1789-1794 Link Here
1789
    void doCancelClick () {
1848
    void doCancelClick () {
1790
        if (cancelButton.isEnabled ()) {
1849
        if (cancelButton.isEnabled ()) {
1791
            cancelButton.doClick ();
1850
            cancelButton.doClick ();
1851
        }
1852
    }
1853
    
1854
    // helper, make possible close wizard as finish
1855
    static class FinishAction extends Object {
1856
        static public FinishAction FINISH_ACTION = new FinishAction ();
1857
        ActionListener listner;
1858
        public void addActionListener (ActionListener ac) {
1859
            listner = ac;
1860
        }
1861
        
1862
        public void removeActionListener (ActionListener ac) {
1863
            listner = null;
1864
        }
1865
        
1866
        public void fireActionPerformed () {
1867
            if (listner != null) {
1868
                listner.actionPerformed (new ActionEvent (this, 0, ""));
1869
            }
1792
        }
1870
        }
1793
    }
1871
    }
1794
    
1872
    
(-)src/org/openide/DialogDisplayer.java (-1 / +46 lines)
Lines 7-13 Link Here
7
 * http://www.sun.com/
7
 * http://www.sun.com/
8
 * 
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
11
 * Microsystems, Inc. All Rights Reserved.
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
12
 */
13
13
Lines 22-27 Link Here
22
import java.beans.PropertyChangeEvent;
22
import java.beans.PropertyChangeEvent;
23
import java.beans.PropertyChangeListener;
23
import java.beans.PropertyChangeListener;
24
import java.util.Arrays;
24
import java.util.Arrays;
25
import java.util.HashSet;
26
import java.util.Set;
25
import javax.swing.*;
27
import javax.swing.*;
26
28
27
import org.openide.util.Lookup;
29
import org.openide.util.Lookup;
Lines 172-177 Link Here
172
            }
174
            }
173
            
175
            
174
            public void updateOptions() {
176
            public void updateOptions() {
177
                Set addedOptions = new HashSet (5);
175
                Object[] options = nd.getOptions();
178
                Object[] options = nd.getOptions();
176
                if (options == null) {
179
                if (options == null) {
177
                    switch (nd.getOptionType()) {
180
                    switch (nd.getOptionType()) {
Lines 203-218 Link Here
203
                buttonPanel.removeAll();
206
                buttonPanel.removeAll();
204
                JRootPane rp = getRootPane();
207
                JRootPane rp = getRootPane();
205
                for (int i = 0; i < options.length; i++) {
208
                for (int i = 0; i < options.length; i++) {
209
                    addedOptions.add (options[i]);
206
                    buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
210
                    buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
207
                }
211
                }
208
                options = nd.getAdditionalOptions();
212
                options = nd.getAdditionalOptions();
209
                if (options != null) {
213
                if (options != null) {
210
                    for (int i = 0; i < options.length; i++) {
214
                    for (int i = 0; i < options.length; i++) {
215
                        addedOptions.add (options[i]);
211
                        buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
216
                        buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
212
                    }
217
                    }
213
                }
218
                }
219
                if (closingOptions != null) {
220
                    for (int i = 0; i < closingOptions.length; i++) {
221
                        if (addedOptions.add (closingOptions[i])) {
222
                            ActionListener l = makeListener (closingOptions[i]);
223
                            attachActionListener (closingOptions[i], l);
224
                        }
225
                    }
226
                }
214
            }
227
            }
215
            
228
            
229
            private void attachActionListener (Object comp, ActionListener l) {
230
                // on JButtons attach simply by method call
231
                if (comp instanceof JButton) {
232
                    JButton b = (JButton)comp;
233
                    b.addActionListener(l);
234
                    return;
235
                } else {
236
                    // we will have to use dynamic method invocation to add the action listener
237
                    // to generic component (and we succeed only if it has the addActionListener method)
238
                    java.lang.reflect.Method m = null;
239
                    try {
240
                        m = comp.getClass().getMethod("addActionListener", new Class[] { ActionListener.class });// NOI18N
241
                        try {
242
                            m.setAccessible (true);
243
                        } catch (SecurityException se) {
244
                            m = null; // no jo, we cannot make accessible
245
                        }
246
                    } catch (NoSuchMethodException e) {
247
                        m = null; // no jo, we cannot attach ActionListener to this Component
248
                    } catch (SecurityException e2) {
249
                        m = null; // no jo, we cannot attach ActionListener to this Component
250
                    }
251
                    if (m != null) {
252
                        try {
253
                            m.invoke(comp, new Object[] { l });
254
                        } catch (Exception e) {
255
                            // not succeeded, so give up
256
                        }
257
                    }
258
                }
259
            }
260
216
            private ActionListener makeListener(final Object option) {
261
            private ActionListener makeListener(final Object option) {
217
                return new ActionListener() {
262
                return new ActionListener() {
218
                    public void actionPerformed(ActionEvent e) {
263
                    public void actionPerformed(ActionEvent e) {
(-)src/org/netbeans/core/windows/services/NbPresenter.java (-3 / +27 lines)
Lines 7-13 Link Here
7
 * http://www.sun.com/
7
 * http://www.sun.com/
8
 *
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
11
 * Microsystems, Inc. All Rights Reserved.
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
12
 */
13
13
Lines 313-318 Link Here
313
        
313
        
314
        descriptor.addPropertyChangeListener(this);
314
        descriptor.addPropertyChangeListener(this);
315
        addWindowListener(this);
315
        addWindowListener(this);
316
        
317
        initializeClosingOptions ();
316
    }
318
    }
317
    
319
    
318
    /** Descriptor can be cached and reused. We need to remove listeners 
320
    /** Descriptor can be cached and reused. We need to remove listeners 
Lines 322-327 Link Here
322
        descriptor.removePropertyChangeListener(this);
324
        descriptor.removePropertyChangeListener(this);
323
        uninitializeMessage();
325
        uninitializeMessage();
324
        uninitializeButtons();
326
        uninitializeButtons();
327
        uninitializeClosingOptions ();
325
    }
328
    }
326
    
329
    
327
    public void addNotify() {
330
    public void addNotify() {
Lines 415-420 Link Here
415
        }
418
        }
416
    }
419
    }
417
    
420
    
421
    private void initializeClosingOptions (boolean init) {
422
        Object[] options = getClosingOptions ();
423
        if (options == null) return ;
424
        for (int i = 0; i < options.length; i++) {
425
            modifyListener (options[i], buttonListener, init);
426
        }
427
    }
428
    
429
    private void initializeClosingOptions () {
430
        initializeClosingOptions (true);
431
    }
432
    
433
    private void uninitializeClosingOptions () {
434
        initializeClosingOptions (false);
435
    }
436
    
418
    protected final void initializeButtons() {
437
    protected final void initializeButtons() {
419
        // -----------------------------------------------------------------------------
438
        // -----------------------------------------------------------------------------
420
        // If there were any buttons previously, remove them and removeActionListener from them
439
        // If there were any buttons previously, remove them and removeActionListener from them
Lines 681-691 Link Here
681
        }
700
        }
682
    }
701
    }
683
    
702
    
684
    private void modifyListener(Component comp, ButtonListener l, boolean add) {
703
    private void modifyListener(Object comp, ButtonListener l, boolean add) {
685
        // on JButtons attach simply by method call
704
        // on JButtons attach simply by method call
686
        if (comp instanceof JButton) {
705
        if (comp instanceof JButton) {
687
            JButton b = (JButton)comp;
706
            JButton b = (JButton)comp;
688
            if (add) {
707
            if (add) { 
689
                b.addActionListener(l);
708
                b.addActionListener(l);
690
                b.addComponentListener(l);
709
                b.addComponentListener(l);
691
                b.addPropertyChangeListener(l);
710
                b.addPropertyChangeListener(l);
Lines 701-706 Link Here
701
            java.lang.reflect.Method m = null;
720
            java.lang.reflect.Method m = null;
702
            try {
721
            try {
703
                m = comp.getClass().getMethod(add ? "addActionListener" : "removeActionListener", new Class[] { ActionListener.class });// NOI18N
722
                m = comp.getClass().getMethod(add ? "addActionListener" : "removeActionListener", new Class[] { ActionListener.class });// NOI18N
723
                try {
724
                    m.setAccessible (true);
725
                } catch (SecurityException se) {
726
                    m = null; // no jo, we cannot make accessible
727
                }
704
            } catch (NoSuchMethodException e) {
728
            } catch (NoSuchMethodException e) {
705
                m = null; // no jo, we cannot attach ActionListener to this Component
729
                m = null; // no jo, we cannot attach ActionListener to this Component
706
            } catch (SecurityException e2) {
730
            } catch (SecurityException e2) {

Return to bug 23116