diff -r e45756bc40c9 core.windows/src/org/netbeans/core/windows/WindowSystemImpl.java --- a/core.windows/src/org/netbeans/core/windows/WindowSystemImpl.java Mon Sep 01 17:46:12 2008 +0200 +++ b/core.windows/src/org/netbeans/core/windows/WindowSystemImpl.java Tue Sep 02 10:19:13 2008 +0200 @@ -43,9 +43,11 @@ package org.netbeans.core.windows; +import java.awt.EventQueue; import org.netbeans.core.NbTopManager; import org.netbeans.core.windows.persistence.PersistenceManager; import org.netbeans.core.windows.services.DialogDisplayerImpl; +import org.netbeans.core.windows.view.ui.MainWindow; /** @@ -59,6 +61,11 @@ public WindowSystemImpl() { } + + public void init() { + assert !EventQueue.isDispatchThread(); + MainWindow.init(); + } // Persistence /** Implements NbTopManager.WindowSystem interface method. diff -r e45756bc40c9 core.windows/src/org/netbeans/core/windows/view/ui/MainWindow.java --- a/core.windows/src/org/netbeans/core/windows/view/ui/MainWindow.java Mon Sep 01 17:46:12 2008 +0200 +++ b/core.windows/src/org/netbeans/core/windows/view/ui/MainWindow.java Tue Sep 02 10:19:13 2008 +0200 @@ -129,6 +129,10 @@ ((JPanel)c).setOpaque(false); root.setGlassPane(c); } + } + + public static void init() { + createMenuBar(); } /** Initializes main window. */ diff -r e45756bc40c9 o.n.core/src/org/netbeans/core/NbTopManager.java --- a/o.n.core/src/org/netbeans/core/NbTopManager.java Mon Sep 01 17:46:12 2008 +0200 +++ b/o.n.core/src/org/netbeans/core/NbTopManager.java Tue Sep 02 10:19:13 2008 +0200 @@ -309,6 +309,7 @@ /** Interface describing basic control over window system. * @since 1.15 */ public interface WindowSystem { + void init(); void show(); void hide(); void load(); diff -r e45756bc40c9 o.n.core/src/org/netbeans/core/NonGui.java --- a/o.n.core/src/org/netbeans/core/NonGui.java Mon Sep 01 17:46:12 2008 +0200 +++ b/o.n.core/src/org/netbeans/core/NonGui.java Tue Sep 02 10:19:13 2008 +0200 @@ -160,7 +160,13 @@ // Starts GUI components to be created and shown on screen. // I.e. main window + current workspace components. + + // Access winsys from AWT thread only. In this case main thread wouldn't harm, just to be kosher. + final NbTopManager.WindowSystem windowSystem = Lookup.getDefault().lookup(NbTopManager.WindowSystem.class); + if (windowSystem != null) { + windowSystem.init(); + } SwingUtilities.invokeLater(new Runnable() { public void run() { StartLog.logProgress("Window system initialization"); @@ -173,7 +179,6 @@ } }); } - NbTopManager.WindowSystem windowSystem = Lookup.getDefault().lookup(NbTopManager.WindowSystem.class); if (windowSystem != null) { windowSystem.load(); StartLog.logProgress("Window system loaded"); diff -r e45756bc40c9 openide.loaders/manifest.mf --- a/openide.loaders/manifest.mf Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/manifest.mf Tue Sep 02 10:19:13 2008 +0200 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.loaders -OpenIDE-Module-Specification-Version: 7.2 +OpenIDE-Module-Specification-Version: 7.3 OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties OpenIDE-Module-Recommends: org.netbeans.modules.templates.v1_0 AutoUpdate-Essential-Module: true diff -r e45756bc40c9 openide.loaders/src/org/openide/awt/AWTTask.java --- a/openide.loaders/src/org/openide/awt/AWTTask.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/awt/AWTTask.java Tue Sep 02 10:19:13 2008 +0200 @@ -41,6 +41,8 @@ package org.openide.awt; +import java.awt.EventQueue; + /** A special task designed to run in AWT thread. * It will fire itself immediatelly. */ @@ -52,6 +54,7 @@ org.openide.util.Mutex.EVENT.readAccess (this); } + @Override public void run () { if (!executed) { super.run (); @@ -59,8 +62,9 @@ } } + @Override public void waitFinished () { - if (javax.swing.SwingUtilities.isEventDispatchThread ()) { + if (EventQueue.isDispatchThread()) { run (); } else { super.waitFinished (); diff -r e45756bc40c9 openide.loaders/src/org/openide/awt/DynaMenuModel.java --- a/openide.loaders/src/org/openide/awt/DynaMenuModel.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/awt/DynaMenuModel.java Tue Sep 02 10:19:13 2008 +0200 @@ -58,7 +58,6 @@ import javax.swing.JPopupMenu; import javax.swing.JSeparator; import org.openide.util.Utilities; -import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.Presenter; /** diff -r e45756bc40c9 openide.loaders/src/org/openide/awt/MenuBar.java --- a/openide.loaders/src/org/openide/awt/MenuBar.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/awt/MenuBar.java Tue Sep 02 10:19:13 2008 +0200 @@ -298,7 +298,9 @@ * @param folder a DataFolder to work with */ public MenuBarFolder (final DataFolder folder) { - super(folder); + super(folder, true); + // preinitialize outside of AWT + new DynaMenuModel(); recreate (); } @@ -432,6 +434,10 @@ /** Menu based on the folder content whith lazy items creation. */ private static class LazyMenu extends JMenu implements NodeListener, Runnable, ChangeListener { + static { + // preinitialize outside of AWT + new DynaMenuModel(); + } DataFolder master; boolean icon; MenuFolder slave; @@ -579,7 +585,7 @@ * It will cause initial update of the Menu */ public MenuFolder () { - super(master); + super(master, true); } diff -r e45756bc40c9 openide.loaders/src/org/openide/awt/Toolbar.java --- a/openide.loaders/src/org/openide/awt/Toolbar.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/awt/Toolbar.java Tue Sep 02 10:19:14 2008 +0200 @@ -969,7 +969,7 @@ * */ public Folder () { - super (backingFolder); + super (backingFolder, true); recreate (); } diff -r e45756bc40c9 openide.loaders/src/org/openide/awt/ToolbarPool.java --- a/openide.loaders/src/org/openide/awt/ToolbarPool.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/awt/ToolbarPool.java Tue Sep 02 10:19:14 2008 +0200 @@ -457,7 +457,7 @@ new WeakHashMap (15); public Folder (DataFolder f) { - super (f); + super (f, true); } /** @@ -569,11 +569,11 @@ } /** Recreate the instance in AWT thread. - */ + */ + @Override protected Task postCreationTask (Runnable run) { return new AWTTask (run); } - } // end of Folder diff -r e45756bc40c9 openide.loaders/src/org/openide/loaders/FolderInstance.java --- a/openide.loaders/src/org/openide/loaders/FolderInstance.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/src/org/openide/loaders/FolderInstance.java Tue Sep 02 10:19:14 2008 +0200 @@ -48,9 +48,9 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.openide.*; import org.openide.filesystems.*; import org.openide.cookies.InstanceCookie; +import org.openide.util.Exceptions; import org.openide.util.Task; import org.openide.util.TaskListener; import org.openide.util.RequestProcessor; @@ -158,6 +158,8 @@ * Started immediately after the recognizingTask is finished. */ private Task creationTask; + /** shall instances be precreated? */ + private boolean precreateInstances; /* -------------------------------------------------------------------- */ /* -- Constructor(s) -------------------------------------------------- */ @@ -168,6 +170,17 @@ */ public FolderInstance (DataFolder df) { this ((DataObject.Container)df); + } + + /** Create new folder instance. + * @param df data folder to create instances from + * @param precreateInstances if true, then instances for all cookies + * are created before {@link #postCreationTask} is called + * @since 7.3 + */ + public FolderInstance (DataFolder df, boolean precreateInstances) { + this ((DataObject.Container)df); + this.precreateInstances = precreateInstances; } /** A new object that listens on changes in a container. @@ -237,15 +250,15 @@ */ public Class instanceClass () throws java.io.IOException, ClassNotFoundException { - Object object = this.object; - if (object != null) { - if (object instanceof java.io.IOException) { - throw (java.io.IOException)object; + Object tmp = this.object; + if (tmp != null) { + if (tmp instanceof java.io.IOException) { + throw (java.io.IOException)tmp; } - if (object instanceof ClassNotFoundException) { - throw (ClassNotFoundException)object; + if (tmp instanceof ClassNotFoundException) { + throw (ClassNotFoundException)tmp; } - return object.getClass (); + return tmp.getClass (); } return Object.class; @@ -258,32 +271,32 @@ */ public Object instanceCreate () throws java.io.IOException, ClassNotFoundException { - Object object = CURRENT.get (); + Object tmp = CURRENT.get (); - if (object == null || LAST_CURRENT.get () != this) { + if (tmp == null || LAST_CURRENT.get () != this) { err.fine("do into waitFinished"); // NOI18N waitFinished (); - object = FolderInstance.this.object; + tmp = FolderInstance.this.object; } if (err.isLoggable(Level.FINE)) { - err.fine("instanceCreate: " + object); // NOI18N + err.fine("instanceCreate: " + tmp); // NOI18N } - if (object instanceof java.io.IOException) { - throw (java.io.IOException)object; + if (tmp instanceof java.io.IOException) { + throw (java.io.IOException)tmp; } - if (object instanceof ClassNotFoundException) { - throw (ClassNotFoundException)object; + if (tmp instanceof ClassNotFoundException) { + throw (ClassNotFoundException)tmp; } - if (object == CURRENT) { + if (tmp == CURRENT) { // uninitialized throw new IOException ("Cyclic reference. Somebody is trying to get value from FolderInstance (" + getClass ().getName () + ") from the same thread that is processing the instance"); // NOI18N } - return object; + return tmp; } /* -------------------------------------------------------------------- */ @@ -406,15 +419,15 @@ } if (cookie == null) { - DataFolder folder = dob.getCookie(DataFolder.class); - if (folder != null) { - HoldInstance previous = map.get (folder.getPrimaryFile ()); + DataFolder fld = dob.getCookie(DataFolder.class); + if (fld != null) { + HoldInstance previous = map.get (fld.getPrimaryFile ()); if (previous != null && previous.cookie != null) { // the old cookie will be returned if the folder is already registered cookie = previous; acceptType = 2; } else { - cookie = acceptFolder (folder); + cookie = acceptFolder (fld); acceptType = 3; } } @@ -650,17 +663,47 @@ * @param arr collection of DataObjects */ final void processObjects (final Collection arr) { - creationTask = postCreationTask (new Runnable () { - public void run () { - defaultProcessObjects (arr); + class R implements Runnable { + HoldInstance[] all; + Object[] instances; + + public void init() { + all = defaultProcessObjects(arr); } - }); + + public void instances() { + instances = new Object[all.length]; + int indx = 0; + for (HoldInstance h : all) { + try { + instances[indx++] = h.instanceClass(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } catch (ClassNotFoundException ex) { + Exceptions.printStackTrace(ex); + } + } + } + + public void run() { + if (all == null) { + init(); + } + defaultProcessObjectsFinal(all); + } + } + R process = new R(); + if (precreateInstances) { + process.init(); + process.instances(); + } + creationTask = postCreationTask (process); } /** Default processing of objects. * @param arr array of objects to process */ - private final void defaultProcessObjects (Collection arr) { + private final HoldInstance[] defaultProcessObjects (Collection arr) { err.fine("defaultProcessObjects"); HashSet toRemove; ArrayList cookies = new ArrayList (); @@ -762,6 +805,10 @@ updateWaitFor (all); + return all; + } + + private void defaultProcessObjectsFinal(HoldInstance[] all) { Object result = null; try { result = createInstance (all); diff -r e45756bc40c9 openide.loaders/test/unit/src/org/openide/awt/MenuBarTest.java --- a/openide.loaders/test/unit/src/org/openide/awt/MenuBarTest.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/test/unit/src/org/openide/awt/MenuBarTest.java Tue Sep 02 10:19:14 2008 +0200 @@ -41,6 +41,7 @@ package org.openide.awt; +import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; @@ -297,6 +298,7 @@ public static int counter; public MyAction() { + assertFalse("Not initialized in AWT thread", EventQueue.isDispatchThread()); counter++; } @@ -328,6 +330,7 @@ public CreateOnlyOnceAction() { new Exception("created for " + (++instancesCount) + " time").printStackTrace(pw); putValue(NAME, "TestAction"); + assertFalse("Not initialized in AWT thread", EventQueue.isDispatchThread()); } } diff -r e45756bc40c9 openide.loaders/test/unit/src/org/openide/awt/ToolbarPoolTest.java --- a/openide.loaders/test/unit/src/org/openide/awt/ToolbarPoolTest.java Mon Sep 01 17:46:12 2008 +0200 +++ b/openide.loaders/test/unit/src/org/openide/awt/ToolbarPoolTest.java Tue Sep 02 10:19:14 2008 +0200 @@ -45,9 +45,12 @@ import java.io.IOException; import java.io.ObjectOutputStream; import java.util.logging.Level; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; +import javax.swing.JPanel; import org.netbeans.junit.NbTestCase; +import org.openide.awt.MenuBarTest.MyAction; import org.openide.cookies.InstanceCookie; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; @@ -75,10 +78,12 @@ return 30000; } + @Override protected Level logLevel() { return Level.FINE; } + @Override protected void setUp() throws Exception { FileObject root = Repository.getDefault ().getDefaultFileSystem ().getRoot (); toolbars = FileUtil.createFolder (root, "Toolbars"); @@ -149,6 +154,38 @@ assertLabels ("Now there are two", 2, myTlbs[0]); } + + public void testWhoCreatesConstructor() throws Exception { + FileObject root = Repository.getDefault ().getDefaultFileSystem ().getRoot (); + FileObject fo = FileUtil.createFolder (root, "ToolbarsWhoCreates"); + final DataFolder df = DataFolder.findFolder(fo); + ToolbarPool pool = new ToolbarPool(df); + + assertEquals("No children now", 0, pool.getToolbars().length); + + class Atom implements FileSystem.AtomicAction { + + FileObject m1, m2; + + public void run() throws IOException { + m1 = FileUtil.createFolder(df.getPrimaryFile(), "m1"); + DataFolder f1 = DataFolder.findFolder(m1); + InstanceDataObject.create(f1, "X", MyAction.class); + } + } + Atom atom = new Atom(); + df.getPrimaryFile().getFileSystem().runAtomicAction(atom); + pool.waitFinished(); + + assertEquals("One toolbar is there", 1, pool.getToolbars().length); + assertEquals("Pool name", "m1", pool.getToolbars()[0].getName()); + + Object o1 = pool.getToolbars()[0].getComponent(1); + if (!(o1 instanceof JButton)) { + fail("Need JPanel " + o1); + } + assertEquals("And now the action is created", 1, MyAction.counter); + } private static Object writeInstance (final FileObject folder, final String name, final Object inst) throws IOException { class W implements FileSystem.AtomicAction {