Index: openide/dialogs/apichanges.xml =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/apichanges.xml,v retrieving revision 1.4 diff -u -r1.4 apichanges.xml --- openide/dialogs/apichanges.xml 22 May 2005 07:14:42 -0000 1.4 +++ openide/dialogs/apichanges.xml 29 Nov 2005 08:14:26 -0000 @@ -17,6 +17,23 @@ Dialogs API + + + Interface AsynchronousInstantiatingIterator added + + + + + + The AsynchronousInstantiatingIterator allows to implement + asynchronous instantating of newly created objects. Wizard's framework + esures that the method AsynchronousInstantiatingIterator.instantiate() + will be called ouside of an event queue. + + + + + Interface AsynchronousValidationgPanel added Index: openide/dialogs/manifest.mf =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/manifest.mf,v retrieving revision 1.5 diff -u -r1.5 manifest.mf --- openide/dialogs/manifest.mf 10 Nov 2005 05:55:11 -0000 1.5 +++ openide/dialogs/manifest.mf 29 Nov 2005 08:14:26 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.dialogs -OpenIDE-Module-Specification-Version: 6.4 +OpenIDE-Module-Specification-Version: 6.5 OpenIDE-Module-Localizing-Bundle: org/openide/Bundle.properties Index: openide/dialogs/nbproject/project.xml =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/nbproject/project.xml,v retrieving revision 1.4 diff -u -r1.4 project.xml --- openide/dialogs/nbproject/project.xml 25 May 2005 23:56:55 -0000 1.4 +++ openide/dialogs/nbproject/project.xml 29 Nov 2005 08:14:26 -0000 @@ -18,7 +18,7 @@ org.openide.dialogs - org.openide.util + org.openide.awt @@ -26,7 +26,7 @@ - org.openide.awt + org.openide.util Index: openide/dialogs/src/org/openide/Bundle.properties =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/src/org/openide/Bundle.properties,v retrieving revision 1.2 diff -u -r1.2 Bundle.properties --- openide/dialogs/src/org/openide/Bundle.properties 17 May 2005 00:15:01 -0000 1.2 +++ openide/dialogs/src/org/openide/Bundle.properties 29 Nov 2005 08:14:26 -0000 @@ -100,3 +100,7 @@ #Property - wizard panel image alignment #NOI18N STRING_WizardImageAlignment=South + +# MSG_WizardDescriptor_FinishInProgress=In progress ... +MSG_WizardDescriptor_FinishInProgress= +CTL_InstantiateProgress_Title=Instantiating new objects Index: openide/dialogs/src/org/openide/WizardDescriptor.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/src/org/openide/WizardDescriptor.java,v retrieving revision 1.15 diff -u -r1.15 WizardDescriptor.java --- openide/dialogs/src/org/openide/WizardDescriptor.java 20 Oct 2005 07:28:04 -0000 1.15 +++ openide/dialogs/src/org/openide/WizardDescriptor.java 29 Nov 2005 08:14:27 -0000 @@ -12,11 +12,13 @@ */ package org.openide; +import java.lang.reflect.InvocationTargetException; import org.openide.awt.HtmlBrowser; import org.openide.util.HelpCtx; import org.openide.util.Mutex; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; +import org.openide.util.RequestProcessor.Task; import org.openide.util.Utilities; import org.openide.util.WeakListeners; @@ -1175,11 +1177,10 @@ panels.current().storeSettings(settings); if (panels instanceof InstantiatingIterator) { - // PENDING: disable all buttons to indicate that instantiate runs - // PENDING: write something to errorMessage (e.g. Wait to finishing.) showWaitCursor(); try { + assert ! (panels instanceof AsynchronousInstantiatingIterator) || ! SwingUtilities.isEventDispatchThread () : "Cannot invoked within EDT if AsynchronousInstantiatingIterator!"; newObjects = ((InstantiatingIterator) panels).instantiate(); } finally { @@ -1461,6 +1462,26 @@ */ public void uninitialize(WizardDescriptor wizard); } + + /** + * Iterator for a wizard that needs to somehow instantiate new objects outside ATW queue. + * (This interface can replace + * TemplateWizard.Iterator + * in a template's declaration.) + * @since org.openide/1 6.5 + */ + public interface AsynchronousInstantiatingIterator extends InstantiatingIterator { + + /** + * Is called in separate thread when the Finish button + * are clicked and allows implement asynchronous + * instantating of newly created objects. + * + * @throws WizardValidationException when validation fails + */ + public Set /**/ instantiate () throws IOException; + + } /** Special iterator that works on an array of Panels. */ @@ -1620,33 +1641,57 @@ if (ev.getSource() == finishButton) { Runnable onValidPerformer = new Runnable() { public void run() { - // do instantiate - try { - callInstantiate(); - } catch (IOException ioe) { - // notify to log - ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); - - setValueWithoutPCH(NEXT_OPTION); - updateStateWithFeedback(); - - // notify user by the wizard's status line - putProperty(PROP_ERROR_MESSAGE, ioe.getLocalizedMessage()); + // disable all buttons to indicate that instantiate runs + cancelButton.setEnabled (false); + previousButton.setEnabled (false); + nextButton.setEnabled (false); + finishButton.setEnabled (false); + + // write something to errorMessage (e.g. Wait to finishing.) + if (wizardPanel != null) wizardPanel.setErrorMessage (NbBundle.getMessage (WizardDescriptor.class, "MSG_WizardDescriptor_FinishInProgress"), Boolean.TRUE); // NOI18N + + Runnable performFinish = new Runnable () { + public void run () { + // do instantiate + try { + callInstantiate(); + } catch (IOException ioe) { + // notify to log + ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); + + setValueWithoutPCH(NEXT_OPTION); + updateStateWithFeedback(); + + // notify user by the wizard's status line + putProperty(PROP_ERROR_MESSAGE, ioe.getLocalizedMessage()); + + // if validation failed => cannot move to next panel + return; + } + Object oldValue = getValue(); + setValueWithoutPCH(OK_OPTION); + + resetWizard(); + + firePropertyChange(PROP_VALUE, oldValue, OK_OPTION); + + SwingUtilities.invokeLater (new Runnable () { + public void run () { + // all is OK + // close wizrad + finishOption.fireActionPerformed(); - // if validation failed => cannot move to next panel - return; + } + }); + } + }; + + if (panels instanceof AsynchronousInstantiatingIterator) { + RequestProcessor.getDefault ().post (performFinish); + } else { + performFinish.run (); } - - // all is OK - // close wizrad - finishOption.fireActionPerformed(); - - Object oldValue = getValue(); - setValueWithoutPCH(OK_OPTION); - - resetWizard(); - - firePropertyChange(PROP_VALUE, oldValue, OK_OPTION); + } }; lazyValidate(panels.current(), onValidPerformer); Index: openide/dialogs/test/unit/src/org/openide/AsynchronousInstantiatingIteratorTest.java =================================================================== RCS file: openide/dialogs/test/unit/src/org/openide/AsynchronousInstantiatingIteratorTest.java diff -N openide/dialogs/test/unit/src/org/openide/AsynchronousInstantiatingIteratorTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openide/dialogs/test/unit/src/org/openide/AsynchronousInstantiatingIteratorTest.java 29 Nov 2005 08:14:27 -0000 @@ -0,0 +1,201 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.openide; + + +import org.netbeans.junit.NbTestSuite; + +import java.awt.Component; +import java.io.IOException; +import java.util.*; +import javax.swing.*; +import javax.swing.JLabel; +import javax.swing.event.ChangeListener; +import org.openide.InstantiatingIteratorTest.Listener; +import org.openide.util.HelpCtx; + +/** Testing functional implementation calling the methods to interface WizardDescriptor.AsynchronousInstantiatingIterator + * from WizardDescriptor. Check if the method instantiate() is called outside AWT in particular. + * @see Issue 62161 + */ +public class AsynchronousInstantiatingIteratorTest extends InstantiatingIteratorTest { + + + public AsynchronousInstantiatingIteratorTest (String name) { + super(name); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run (new NbTestSuite (AsynchronousInstantiatingIteratorTest.class)); + System.exit (0); + } + + private Iterator iterator; + + protected void setUp () { + iterator = new Iterator (); + wd = new WizardDescriptor (iterator); + wd.addPropertyChangeListener(new Listener ()); + java.awt.Dialog d = DialogDisplayer.getDefault ().createDialog (wd); + checkOrder = false; + shouldThrowException = false; + //d.show(); + } + + /** Run all tests in AWT thread */ + protected boolean runInEQ() { + return true; + } + + public void testInstantiateInAWTQueueOrNot () { + checkIfInAWT = true; + + wd.doNextClick (); + finishWizard (wd); + try { + Set newObjects = wd.getInstantiatedObjects (); + } catch (IllegalStateException ise) { + fail ("IllegalStateException was caught because WD.instantiate() called in AWT queue."); + } + assertNotNull ("InstantiatingIterator was correctly instantiated.", getResult ()); + } + + public class Panel implements WizardDescriptor.FinishablePanel { + private JLabel component; + private String text; + public Panel(String text) { + this.text = text; + } + + public Component getComponent() { + if (component == null) { + component = new JLabel (text); + } + return component; + } + + public void addChangeListener(ChangeListener l) { + changeListenersInPanel.add (l); + } + + public HelpCtx getHelp() { + return null; + } + + public boolean isValid() { + return true; + } + + public void readSettings(Object settings) { + log ("readSettings of panel: " + text + " [time: " + System.currentTimeMillis () + + "] with PROP_VALUE: " + handleValue (wd.getValue ())); + } + + public void removeChangeListener(ChangeListener l) { + changeListenersInPanel.remove (l); + } + + public void storeSettings(Object settings) { + if (checkOrder) { + assertNull ("WD.P.storeSettings() called before WD.I.instantiate()", iterator.result); + // bugfix #45093, remember storeSettings could be called multiple times + // do check order only when the first time + checkOrder = false; + } + log ("storeSettings of panel: " + text + " [time: " + System.currentTimeMillis () + + "] with PROP_VALUE: " + handleValue (wd.getValue ())); + if (exceptedValue != null) { + assertEquals ("WD.getValue() returns excepted value.", exceptedValue, handleValue (wd.getValue ())); + } + } + + public boolean isFinishPanel () { + return true; + } + + } + + protected Boolean getInitialized () { + return iterator.initialized; + } + + protected Set getResult () { + return iterator.result; + } + + public class Iterator implements WizardDescriptor.AsynchronousInstantiatingIterator { + int index = 0; + WizardDescriptor.Panel panels[] = new WizardDescriptor.Panel[2]; + java.util.Set helpSet; + + private Boolean initialized = null; + private Set result = null; + + public WizardDescriptor.Panel current () { + assertTrue ("WD.current() called on initialized iterator.", initialized != null && initialized.booleanValue ()); + return panels[index]; + } + public String name () { + return "Test iterator"; + } + public boolean hasNext () { + return index < 1; + } + public boolean hasPrevious () { + return index > 0; + } + public void nextPanel () { + if (!hasNext ()) throw new NoSuchElementException (); + index ++; + } + public void previousPanel () { + if (!hasPrevious ()) throw new NoSuchElementException (); + index --; + } + public void addChangeListener (ChangeListener l) { + changeListenersInIterator.add (l); + } + public void removeChangeListener (ChangeListener l) { + changeListenersInIterator.remove (l); + } + public java.util.Set instantiate () throws IOException { + if (checkIfInAWT) { + if (SwingUtilities.isEventDispatchThread ()) { + throw new IOException ("Cannot run in AWT queue."); + } + } + if (shouldThrowException) { + throw new IOException ("Test throw IOException during instantiate()."); + } + if (initialized.booleanValue ()) { + helpSet.add ("member"); + result = helpSet; + } else { + result = null; + } + return result; + } + public void initialize (WizardDescriptor wizard) { + helpSet = new HashSet (); + panels[0] = new Panel("first panel"); + panels[1] = new Panel("second panel"); + initialized = Boolean.TRUE; + } + public void uninitialize (WizardDescriptor wizard) { + helpSet.clear (); + initialized = Boolean.FALSE; + panels = null; + } + } + +} Index: openide/dialogs/test/unit/src/org/openide/InstantiatingIteratorTest.java =================================================================== RCS file: /shared/data/ccvs/repository/openide/dialogs/test/unit/src/org/openide/InstantiatingIteratorTest.java,v retrieving revision 1.1 diff -u -r1.1 InstantiatingIteratorTest.java --- openide/dialogs/test/unit/src/org/openide/InstantiatingIteratorTest.java 27 Sep 2005 11:20:24 -0000 1.1 +++ openide/dialogs/test/unit/src/org/openide/InstantiatingIteratorTest.java 29 Nov 2005 08:14:27 -0000 @@ -7,12 +7,13 @@ * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide; +import java.lang.reflect.InvocationTargetException; import org.netbeans.junit.*; import junit.framework.Test; import junit.framework.TestSuite; @@ -30,6 +31,7 @@ import org.netbeans.junit.NbTestCase; import org.openide.util.*; import org.openide.util.HelpCtx; +import org.openide.util.RequestProcessor.Task; /** Testing functional implementation calling the methods to interface WizardDescriptor.InstantiatingIterator * from WizardDescriptor. @@ -46,25 +48,24 @@ System.exit (0); } - private WizardDescriptor wd; - private String exceptedValue; + protected WizardDescriptor wd; + protected String exceptedValue; private Iterator iterator; - private int attachedInIterator = 0; - private int attachedInPanel = 0; - private boolean checkOrder = false; - private boolean shouldThrowException = false; - private boolean checkAWTQueue = false; - private Set/**/ changeListenersInIterator = new HashSet (); - private Set/**/ changeListenersInPanel = new HashSet (); + protected int attachedInIterator = 0; + protected int attachedInPanel = 0; + protected boolean checkOrder = false; + protected boolean shouldThrowException = false; + protected Set/**/ changeListenersInIterator = new HashSet (); + protected Set/**/ changeListenersInPanel = new HashSet (); + protected boolean checkIfInAWT; - protected final void setUp () { + protected void setUp () { iterator = new Iterator (); wd = new WizardDescriptor (iterator); wd.addPropertyChangeListener(new Listener ()); java.awt.Dialog d = DialogDisplayer.getDefault ().createDialog (wd); checkOrder = false; shouldThrowException = false; - checkAWTQueue = false; //d.show(); } @@ -79,7 +80,7 @@ assertEquals ("Still only one listener is attached after Next.", 1, changeListenersInIterator.size ()); wd.doPreviousClick (); assertEquals ("Still only one listener is attached after Previous.", 1, changeListenersInIterator.size ()); - wd.doFinishClick (); + finishWizard (wd); assertEquals ("No one listener is attached after Finish.", 0, changeListenersInIterator.size ()); assertEquals ("No one listener is attached in WD.Panel after Finish.", 0, changeListenersInPanel.size ()); } @@ -92,56 +93,62 @@ } public void testInitializeIterator () throws Exception { - assertTrue ("InstantiatingIterator was initialized.", iterator.initialized.booleanValue ()); - assertNull ("InstantiatingIterator wasn't instantiated.", iterator.result); + assertTrue ("InstantiatingIterator was initialized.", getInitialized ().booleanValue ()); + assertNull ("InstantiatingIterator wasn't instantiated.", getResult ()); } public void testUninitializeIterator () throws Exception { - assertTrue ("InstantiatingIterator was initialized at start.", iterator.initialized.booleanValue ()); + assertTrue ("InstantiatingIterator was initialized at start.", getInitialized ().booleanValue ()); wd.doCancelClick (); - assertFalse ("InstantiatingIterator was uninitialized after cancel.", iterator.initialized.booleanValue ()); - assertNull ("InstantiatingIterator wasn't instantiated.", iterator.result); + assertFalse ("InstantiatingIterator was uninitialized after cancel.", getInitialized ().booleanValue ()); + assertNull ("InstantiatingIterator wasn't instantiated.", getResult ()); } public void testFinishAndUninitializeIterator () throws Exception { - assertTrue ("InstantiatingIterator was initialized at start.", iterator.initialized.booleanValue ()); + assertTrue ("InstantiatingIterator was initialized at start.", getInitialized ().booleanValue ()); wd.doNextClick (); - assertTrue ("InstantiatingIterator wasn't uninitialized after next.", iterator.initialized.booleanValue ()); - wd.doFinishClick (); - assertFalse ("InstantiatingIterator wasn uninitialized after finish.", iterator.initialized.booleanValue ()); - assertNotNull ("InstantiatingIterator was instantiated.", iterator.result); + assertTrue ("InstantiatingIterator wasn't uninitialized after next.", getInitialized ().booleanValue ()); + finishWizard (wd); + assertFalse ("InstantiatingIterator wasn uninitialized after finish.", getInitialized ().booleanValue ()); + assertNotNull ("InstantiatingIterator was instantiated.", getResult ()); } public void testUninitializeIteratorAndCalledCurrent () throws Exception { - assertTrue ("InstantiatingIterator was initialized at start.", iterator.initialized.booleanValue ()); + assertTrue ("InstantiatingIterator was initialized at start.", getInitialized ().booleanValue ()); wd.doNextClick (); - assertTrue ("InstantiatingIterator wasn't uninitialized after next.", iterator.initialized.booleanValue ()); - wd.doFinishClick (); - assertFalse ("InstantiatingIterator wasn uninitialized after finish.", iterator.initialized.booleanValue ()); - assertNotNull ("InstantiatingIterator was instantiated.", iterator.result); + assertTrue ("InstantiatingIterator wasn't uninitialized after next.", getInitialized ().booleanValue ()); + finishWizard (wd); + assertFalse ("InstantiatingIterator was uninitialized after finish.", getInitialized ().booleanValue ()); + assertNotNull ("InstantiatingIterator was instantiated.", getResult ()); } public void testOrderStoreSettingAndInstantiate () throws Exception { checkOrder = true; wd.doNextClick (); - wd.doFinishClick (); - assertNotNull ("InstantiatingIterator was instantiated.", iterator.result); + finishWizard (wd); + assertNotNull ("InstantiatingIterator was instantiated.", getResult ()); } public void testGetInstantiatedObjects () throws Exception { wd.doNextClick (); - wd.doFinishClick (); - assertNotNull ("InstantiatingIterator was instantiated.", iterator.result); + finishWizard (wd); + assertNotNull ("InstantiatingIterator was instantiated.", getResult ()); Set newObjects = wd.getInstantiatedObjects (); - assertEquals ("WD returns same objects as InstantiatingIterator instantiated.", iterator.result, newObjects); + assertEquals ("WD returns same objects as InstantiatingIterator instantiated.", getResult (), newObjects); } - public void testInstantiateOutsideAWTQueue () { - checkAWTQueue = true; + public void testInstantiateInAWTQueueOrNot () { + checkIfInAWT = true; wd.doNextClick (); - wd.doFinishClick (); + finishWizard (wd); + try { + Set newObjects = wd.getInstantiatedObjects (); + } catch (IllegalStateException ise) { + fail ("IllegalStateException was caught because WD.instantiate() called outside AWT queue."); + } + assertNotNull ("InstantiatingIterator was correctly instantiated.", getResult ()); } public void testFinishOptionWhenInstantiateFails () throws Exception { @@ -149,12 +156,16 @@ wd.doNextClick (); Object state = wd.getValue(); - wd.doFinishClick (); + finishWizard (wd); - assertNull ("InstantiatingIterator was not correctly instantiated.", iterator.result); -// Set newObjects = wd.getInstantiatedObjects (); -// assertEquals ("WD returns no object.", Collections.EMPTY_SET, newObjects); - assertSame ("The state is same as before instantiate()", state, wd.getValue ()); + assertNull ("InstantiatingIterator was not correctly instantiated.", getResult ()); + try { + Set newObjects = wd.getInstantiatedObjects (); + fail ("No IllegalStateException was caught. Should be thrown when invoked getInstantiatedObjects() on unfinished wizard."); + } catch (IllegalStateException ise) { + // correct behavior + } + assertEquals ("The state is same as before instantiate()", state, wd.getValue ()); } public class Panel implements WizardDescriptor.FinishablePanel { @@ -194,7 +205,7 @@ public void storeSettings(Object settings) { if (checkOrder) { - assertNull ("WD.P.storeSettings() called before WD.I.instantiate()", iterator.result); + assertNull ("WD.P.storeSettings() called before WD.I.instantiate()", getResult ()); // bugfix #45093, remember storeSettings could be called multiple times // do check order only when the first time checkOrder = false; @@ -212,13 +223,21 @@ } + protected Boolean getInitialized () { + return iterator.initialized; + } + + protected Set getResult () { + return iterator.result; + } + public class Iterator implements WizardDescriptor.InstantiatingIterator { int index = 0; WizardDescriptor.Panel panels[] = new WizardDescriptor.Panel[2]; java.util.Set helpSet; - public Boolean initialized = null; - Set result = null; + private Boolean initialized = null; + private Set result = null; public WizardDescriptor.Panel current () { assertTrue ("WD.current() called on initialized iterator.", initialized != null && initialized.booleanValue ()); @@ -248,8 +267,10 @@ changeListenersInIterator.remove (l); } public java.util.Set instantiate () throws IOException { - if (checkAWTQueue && SwingUtilities.isEventDispatchThread ()) { - throw new IOException ("Don't call from AWT queue."); + if (checkIfInAWT) { + if (! SwingUtilities.isEventDispatchThread ()) { + throw new IOException ("Must run in AWT queue."); + } } if (shouldThrowException) { throw new IOException ("Test throw IOException during instantiate()."); @@ -303,4 +324,11 @@ } return "UNKNOWN OPTION: " + val; } -} \ No newline at end of file + + public static void finishWizard (WizardDescriptor wd) { + wd.doFinishClick (); + RequestProcessor.getDefault ().post (new Runnable () { + public void run () {} + }).waitFinished (); + } +}