netbeans.org is behind firewall, using runsocks wrapper... Index: src/org/openide/WizardDescriptor.java =================================================================== RCS file: /cvs/openide/dialogs/src/org/openide/WizardDescriptor.java,v retrieving revision 1.1 diff -u -b -r1.1 WizardDescriptor.java --- src/org/openide/WizardDescriptor.java 21 Apr 2005 20:12:38 -0000 1.1 +++ src/org/openide/WizardDescriptor.java 9 May 2005 13:39:09 -0000 @@ -256,6 +256,9 @@ private Map properties; ResourceBundle bundle = NbBundle.getBundle(WizardDescriptor.class); + private Thread backgroundValidationTask; + private Runnable onValidPerformer; + { // button init ResourceBundle b = NbBundle.getBundle("org.openide.Bundle"); // NOI18N @@ -609,21 +612,17 @@ boolean prev = panels.hasPrevious(); boolean valid = p.isValid(); - nextButton.setEnabled(next && valid); - previousButton.setEnabled(prev); - - if (current instanceof FinishablePanel) { - // check if isFinishPanel - if (((FinishablePanel) current).isFinishPanel()) { - finishButton.setEnabled(valid); + // AWT sensitive code + if (SwingUtilities.isEventDispatchThread ()) { + updateStateInAWT (); } else { - // XXX What if the last panel is not FinishPanel ??? enable ? - finishButton.setEnabled(valid && !next); + SwingUtilities.invokeLater (new Runnable () { + public void run () { + updateStateInAWT (); } - } else { - // original way - finishButton.setEnabled(valid && (!next || (current instanceof FinishPanel))); + }); } + // end of AWT sensitive code // nextButton.setVisible (next); // finishButton.setVisible (!next || (current instanceof FinishPanel)); @@ -721,6 +720,33 @@ } } + private void updateStateInAWT () { + Panel p = panels.current (); + boolean next = panels.hasNext (); + boolean prev = panels.hasPrevious (); + boolean valid = p.isValid (); + + nextButton.setEnabled (next && valid); + previousButton.setEnabled (prev); + + if (current instanceof FinishablePanel) { + // check if isFinishPanel + if (((FinishablePanel)current).isFinishPanel ()) { + finishButton.setEnabled (valid); + } else { + // XXX What if the last panel is not FinishPanel ??? enable ? + finishButton.setEnabled (valid && !next); + } + } else { + // original way + finishButton.setEnabled ( + valid && + (!next || (current instanceof FinishPanel)) + ); + } + } + + /** Shows blocking wait cursor during updateState run */ private void updateStateWithFeedback() { try { @@ -1064,13 +1090,24 @@ ); } - private boolean lazyValidate(WizardDescriptor.Panel panel) { - if (panel instanceof ValidatingPanel) { + private void lazyValidate(final WizardDescriptor.Panel panel, final JButton origin) { + + Runnable validationPeformar = new Runnable() { + public void run() { ValidatingPanel v = (ValidatingPanel) panel; try { // try validation current panel v.validate(); + + // validation succesfull + SwingUtilities.invokeLater(new Runnable() { + public void run() { + setValid(true); + onValidPerformer.run(); + } + }); + } catch (WizardValidationException wve) { // cannot continue, notify user if (wizardPanel != null) { @@ -1086,12 +1123,23 @@ } } - // lazy validation failed - return false; } + + } + }; + + if (panel instanceof AsynchronousValidatingPanel) { + AsynchronousValidatingPanel p = (AsynchronousValidatingPanel) panel; + setValid(false); // disable Next> Finish buttons + p.prepareValidation(); + backgroundValidationTask = new Thread(validationPeformar); + backgroundValidationTask.start(); + } else if (panel instanceof ValidatingPanel) { + validationPeformar.run(); + } else { + onValidPerformer.run(); } - return true; } // helper methods which call to InstantiatingIterator @@ -1325,6 +1373,38 @@ public void validate() throws WizardValidationException; } + + /** + * A special interface for panels that need to do additional + * asynchronous validation when Next or Finish button is clicked. + * + *

During backround validation is Next or Finish button + * disabled. On validation success wizard automatically + * progress to next panel or finishes. + * + *

During backround validation Cancel button is hooked + * to signal the validation thread using interrupt(). + */ + public interface AsynchronousValidatingPanel extends ValidatingPanel { + + /** + * Called synchronously from UI thread when Next + * of Finish buttons clicked. It allows to lock user + * input to assure official data for background validation. + */ + public void prepareValidation(); + + /** + * Is called in separate thread when Next of Finish buttons + * are clicked and allows deeper check to find out that panel + * is in valid state and it is ok to leave it. + * + * @throws WizardValidationException when validation fails + */ + public void validate() throws WizardValidationException; + } + + /** A special interface for panel that needs to dynamically enabled * Finish button. * @since 4.28 @@ -1489,14 +1569,9 @@ } if (ev.getSource() == nextButton) { - Dimension previousSize = panels.current().getComponent().getSize(); - - // do lazy validation - if (!lazyValidate(panels.current())) { - // if validation failed => cannot move to next panel - return; - } - + final Dimension previousSize = panels.current().getComponent().getSize(); + onValidPerformer = new Runnable() { + public void run() { panels.nextPanel(); try { @@ -1518,6 +1593,9 @@ updateState(); } } + }; + lazyValidate(panels.current(), nextButton); + } if (ev.getSource() == previousButton) { panels.previousPanel(); @@ -1527,12 +1605,8 @@ } if (ev.getSource() == finishButton) { - // do lazy validation - if (!lazyValidate(panels.current())) { - // if validation failed => cannot move to next panel - return; - } - + onValidPerformer = new Runnable() { + public void run() { // do instantiate try { callInstantiate(); @@ -1561,8 +1635,14 @@ firePropertyChange(PROP_VALUE, oldValue, OK_OPTION); } + }; + lazyValidate(panels.current(), finishButton); + } if (ev.getSource() == cancelButton) { + if (backgroundValidationTask != null) { + backgroundValidationTask.interrupt(); + } Object oldValue = getValue(); setValueWithoutPCH(CANCEL_OPTION);