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 168547
Collapse All | Expand All

(-)a/core.ui/nbproject/project.xml (-1 / +1 lines)
Lines 94-100 Link Here
94
                    <build-prerequisite/>
94
                    <build-prerequisite/>
95
                    <compile-dependency/>
95
                    <compile-dependency/>
96
                    <run-dependency>
96
                    <run-dependency>
97
                        <specification-version>7.10</specification-version>
97
                        <specification-version>7.12</specification-version>
98
                    </run-dependency>
98
                    </run-dependency>
99
                </dependency>
99
                </dependency>
100
                <dependency>
100
                <dependency>
(-)a/core.ui/src/org/netbeans/core/ui/resources/layer.xml (+1 lines)
Lines 73-78 Link Here
73
                <attr name="key" stringvalue="delete"/>
73
                <attr name="key" stringvalue="delete"/>
74
                <attr name="iconBase" stringvalue="org/openide/resources/actions/delete.gif"/>
74
                <attr name="iconBase" stringvalue="org/openide/resources/actions/delete.gif"/>
75
                <attr name="displayName" bundlevalue="org.openide.actions.Bundle#Delete"/>
75
                <attr name="displayName" bundlevalue="org.openide.actions.Bundle#Delete"/>
76
                <attr name="asynchronous" boolvalue="true"/>
76
            </file>
77
            </file>
77
            <file name="org-openide-actions-FindAction.instance">
78
            <file name="org-openide-actions-FindAction.instance">
78
                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.callback"/>
79
                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.callback"/>
(-)a/openide.awt/apichanges.xml (+26 lines)
Lines 47-52 Link Here
47
<apidef name="awt">AWT API</apidef>
47
<apidef name="awt">AWT API</apidef>
48
</apidefs>
48
</apidefs>
49
<changes>
49
<changes>
50
    <change id="Actions.asynchronous">
51
        <api name="awt"/>
52
        <summary>Support for asynchronous actions</summary>
53
        <version major="7" minor="12"/>
54
        <date day="30" month="7" year="2009"/>
55
        <author login="jtulach"/>
56
        <compatibility addition="yes" binary="compatible" semantic="compatible" deprecation="no" deletion="no" modification="no"/>
57
        <description>
58
            The layer definition used by factory methods for
59
            <a href="@TOP@/org/openide/awt/Actions.html#context(java.lang.Class,%20boolean,%20boolean,%20org.openide.util.ContextAwareAction,%20java.lang.String,%20javax.swing.Action,%20java.lang.String,%20java.lang.String,%20boolean)">
60
            context</a>
61
            and
62
            <a href="@TOP@/org/openide/awt/Actions.html#callback(java.lang.String,%20javax.swing.Action,%20boolean,%20java.lang.String,%20java.lang.String,%20boolean)">
63
            callback</a>
64
            and
65
            <a href="@TOP@/org/openide/awt/Actions.html#alwaysEnabled(java.awt.event.ActionListener,%20java.lang.String,%20java.lang.String,%20boolean)">
66
                alwaysEnabledAction</a>
67
            were enhanced to understand <code>&lt;attr name="asynchronous" boolvalue="true"/&gt;</code>
68
            attribute. This extends these new factories with capabilities
69
            already present in old <code>SystemAction</code>, thus makes
70
            it easier to migrate from old to new while retaining compatible
71
            behaviour.
72
        </description>
73
        <class package="org.openide.awt" name="Actions"/>
74
        <issue number="168547"/>
75
    </change>
50
    <change id="HtmlBrowser.dispose">
76
    <change id="HtmlBrowser.dispose">
51
        <api name="awt"/>
77
        <api name="awt"/>
52
        <summary>Added dispose() method.</summary>
78
        <summary>Added dispose() method.</summary>
(-)a/openide.awt/nbproject/project.properties (-1 / +1 lines)
Lines 44-47 Link Here
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
46
47
spec.version.base=7.11.0
47
spec.version.base=7.12.0
(-)a/openide.awt/src/org/openide/awt/Actions.java (+3 lines)
Lines 404-409 Link Here
404
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
404
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
405
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
405
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
406
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
406
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
407
     *   &lt;!-- if desired: &lt;attr name="asynchronous" boolvalue="true"/&gt; --&gt;
407
     * &lt;/file&gt;
408
     * &lt;/file&gt;
408
     * </pre>
409
     * </pre>
409
     * In case the "delegate" is not just {@link ActionListener}, but also
410
     * In case the "delegate" is not just {@link ActionListener}, but also
Lines 451-456 Link Here
451
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
452
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
452
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
453
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
453
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
454
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
455
     *   &lt;!-- if desired: &lt;attr name="asynchronous" boolvalue="true"/&gt; --&gt;
454
     * &lt;/file&gt;
456
     * &lt;/file&gt;
455
     * </pre>
457
     * </pre>
456
     * 
458
     * 
Lines 508-513 Link Here
508
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
510
     *   &lt;attr name="displayName" bundlevalue="your.pkg.Bundle#key"/&gt;
509
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
511
     *   &lt;attr name="iconBase" stringvalue="your/pkg/YourImage.png"/&gt;
510
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
512
     *   &lt;!-- if desired: &lt;attr name="noIconInMenu" boolvalue="false"/&gt; --&gt;
513
     *   &lt;!-- if desired: &lt;attr name="asynchronous" boolvalue="true"/&gt; --&gt;
511
     * &lt;/file&gt;
514
     * &lt;/file&gt;
512
     * </pre>
515
     * </pre>
513
     * In the previous case there has to be a class with public default constructor
516
     * In the previous case there has to be a class with public default constructor
(-)a/openide.awt/src/org/openide/awt/AlwaysEnabledAction.java (-2 / +11 lines)
Lines 16-21 Link Here
16
import javax.swing.Icon;
16
import javax.swing.Icon;
17
import javax.swing.KeyStroke;
17
import javax.swing.KeyStroke;
18
import javax.swing.text.Keymap;
18
import javax.swing.text.Keymap;
19
import org.netbeans.modules.openide.util.ActionsBridge;
20
import org.netbeans.modules.openide.util.ActionsBridge.ActionRunnable;
19
import org.openide.util.ContextAwareAction;
21
import org.openide.util.ContextAwareAction;
20
import org.openide.util.ImageUtilities;
22
import org.openide.util.ImageUtilities;
21
import org.openide.util.Lookup;
23
import org.openide.util.Lookup;
Lines 102-108 Link Here
102
        return true;
104
        return true;
103
    }
105
    }
104
106
105
    public void actionPerformed(ActionEvent e) {
107
    public void actionPerformed(final ActionEvent e) {
106
        assert EventQueue.isDispatchThread();
108
        assert EventQueue.isDispatchThread();
107
        if (getDelegate() instanceof Action) {
109
        if (getDelegate() instanceof Action) {
108
            if (!((Action)getDelegate()).isEnabled()) {
110
            if (!((Action)getDelegate()).isEnabled()) {
Lines 112-118 Link Here
112
            }
114
            }
113
        }
115
        }
114
116
115
        getDelegate().actionPerformed(e);
117
        boolean async = Boolean.TRUE.equals(map.get("asynchronous")); // NOI18N
118
        ActionRunnable ar = new ActionRunnable(e, this, async) {
119
            @Override
120
            protected void run() {
121
                getDelegate().actionPerformed(e);
122
            }
123
        };
124
        ActionsBridge.doPerformAction(this, ar);
116
    }
125
    }
117
126
118
    @Override
127
    @Override
(-)a/openide.awt/src/org/openide/awt/ContextAction.java (-2 lines)
Lines 103-110 Link Here
103
    /** Invoked when an action occurs.
103
    /** Invoked when an action occurs.
104
     */
104
     */
105
    public void actionPerformed(final java.awt.event.ActionEvent e) {
105
    public void actionPerformed(final java.awt.event.ActionEvent e) {
106
        assert EventQueue.isDispatchThread();
107
108
        global.actionPerformed(e, performer, type, selectMode);
106
        global.actionPerformed(e, performer, type, selectMode);
109
    }
107
    }
110
108
(-)a/openide.awt/src/org/openide/awt/GeneralAction.java (-6 / +13 lines)
Lines 49-54 Link Here
49
import java.util.logging.Logger;
49
import java.util.logging.Logger;
50
import javax.swing.Action;
50
import javax.swing.Action;
51
import javax.swing.ActionMap;
51
import javax.swing.ActionMap;
52
import org.netbeans.modules.openide.util.ActionsBridge;
53
import org.netbeans.modules.openide.util.ActionsBridge.ActionRunnable;
52
import org.openide.awt.ContextAction.Performer;
54
import org.openide.awt.ContextAction.Performer;
53
import org.openide.util.ContextAwareAction;
55
import org.openide.util.ContextAwareAction;
54
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
Lines 69-80 Link Here
69
    static final Logger LOG = Logger.getLogger(GeneralAction.class.getName());
71
    static final Logger LOG = Logger.getLogger(GeneralAction.class.getName());
70
    
72
    
71
    public static ContextAwareAction callback(
73
    public static ContextAwareAction callback(
72
        String key, Action defaultDelegate, Lookup context, boolean surviveFocusChange
74
        String key, Action defaultDelegate, Lookup context, boolean surviveFocusChange, boolean async
73
    ) {
75
    ) {
74
        if (key == null) {
76
        if (key == null) {
75
            throw new NullPointerException();
77
            throw new NullPointerException();
76
        }
78
        }
77
        return new DelegateAction(null, key, context, defaultDelegate, surviveFocusChange);
79
        return new DelegateAction(null, key, context, defaultDelegate, surviveFocusChange, async);
78
    }
80
    }
79
    
81
    
80
    public static Action alwaysEnabled(Map map) {
82
    public static Action alwaysEnabled(Map map) {
Lines 161-166 Link Here
161
        private Action fallback;
163
        private Action fallback;
162
        /** key to delegate to */
164
        /** key to delegate to */
163
        private Object key;
165
        private Object key;
166
        /** are we asynchronous? */
167
        private final boolean async;
164
168
165
        /** global lookup to work with */
169
        /** global lookup to work with */
166
        private GlobalManager global;
170
        private GlobalManager global;
Lines 175-186 Link Here
175
         * listens for changes of <code>ActionMap</code> in order to delegate
179
         * listens for changes of <code>ActionMap</code> in order to delegate
176
         * to right action.
180
         * to right action.
177
         */
181
         */
178
        public DelegateAction(Map map, Object key, Lookup actionContext, Action fallback, boolean surviveFocusChange) {
182
        public DelegateAction(Map map, Object key, Lookup actionContext, Action fallback, boolean surviveFocusChange, boolean async) {
179
            this.map = map;
183
            this.map = map;
180
            this.key = key;
184
            this.key = key;
181
            this.fallback = fallback;
185
            this.fallback = fallback;
182
            this.global = GlobalManager.findManager(actionContext, surviveFocusChange);
186
            this.global = GlobalManager.findManager(actionContext, surviveFocusChange);
183
            this.weakL = WeakListeners.propertyChange(this, fallback);
187
            this.weakL = WeakListeners.propertyChange(this, fallback);
188
            this.async = async;
184
            if (fallback != null) {
189
            if (fallback != null) {
185
                fallback.addPropertyChangeListener(weakL);
190
                fallback.addPropertyChangeListener(weakL);
186
            }
191
            }
Lines 192-198 Link Here
192
                map.get("key"), // NOI18N
197
                map.get("key"), // NOI18N
193
                Utilities.actionsGlobalContext(), // NOI18N
198
                Utilities.actionsGlobalContext(), // NOI18N
194
                fallback, // NOI18N
199
                fallback, // NOI18N
195
                Boolean.TRUE.equals(map.get("surviveFocusChange")) // NOI18N
200
                Boolean.TRUE.equals(map.get("surviveFocusChange")), // NOI18N
201
                Boolean.TRUE.equals(map.get("asynchronous")) // NOI18N
196
            );
202
            );
197
        }
203
        }
198
204
Lines 208-214 Link Here
208
            assert EventQueue.isDispatchThread();
214
            assert EventQueue.isDispatchThread();
209
            final javax.swing.Action a = findAction();
215
            final javax.swing.Action a = findAction();
210
            if (a != null) {
216
            if (a != null) {
211
                a.actionPerformed(e);
217
                ActionRunnable ar = ActionRunnable.create(e, a, async);
218
                ActionsBridge.doPerformAction(a, ar);
212
            }
219
            }
213
        }
220
        }
214
221
Lines 288-294 Link Here
288
            if (f instanceof ContextAwareAction) {
295
            if (f instanceof ContextAwareAction) {
289
                f = ((ContextAwareAction)f).createContextAwareInstance(actionContext);
296
                f = ((ContextAwareAction)f).createContextAwareInstance(actionContext);
290
            }
297
            }
291
            return new DelegateAction(map, key, actionContext, f, global.isSurvive());
298
            return new DelegateAction(map, key, actionContext, f, global.isSurvive(), async);
292
        }
299
        }
293
300
294
        public void propertyChange(PropertyChangeEvent evt) {
301
        public void propertyChange(PropertyChangeEvent evt) {
(-)4fe4a8fce84e (+185 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.openide.awt;
43
44
import java.awt.event.ActionEvent;
45
import java.util.logging.Level;
46
import javax.swing.AbstractAction;
47
import javax.swing.Action;
48
import org.netbeans.junit.Log;
49
import org.netbeans.junit.NbTestCase;
50
import org.openide.filesystems.FileUtil;
51
import org.openide.util.ContextAwareAction;
52
import org.openide.util.Lookup;
53
54
/** Verifies asynchronous aspects of actions systems are close to the
55
 * original behaviour of SystemAction one.
56
 * Taken from org.openide.util.actions.AsynchronousTest
57
 * @author Jaroslav Tulach
58
 */
59
public class AsynchronousTest extends NbTestCase {
60
61
    private CharSequence err;
62
    
63
    public AsynchronousTest(String name) {
64
        super(name);
65
    }
66
67
    @Override
68
    protected int timeOut() {
69
        return 5000;
70
    }
71
    
72
    @Override
73
    protected boolean runInEQ() {
74
        return true;
75
    }
76
77
    @Override
78
    protected void setUp() {
79
        err = Log.enable("", Level.WARNING);
80
        AC.finished = false;
81
    }
82
    
83
    public void testExecutionOfActionsThatDoesNotDefineAsynchronousIsSynchronousNoWarningIsPrinted() throws Exception {
84
        Action action = (Action)FileUtil.getConfigFile("actions/async/none.instance").getAttribute("instanceCreate");
85
        
86
        synchronized (AsynchronousTest.class) {
87
            action.actionPerformed(new ActionEvent(this, 0, ""));
88
            assertTrue("The synchronous action is finished immediatelly", AC.finished);
89
        }
90
        
91
        if (err.length() > 0) {
92
            fail("There should be no warning about missing asynchronous: " + err);
93
        }
94
    }
95
    
96
    public void testExecutionCanBeAsynchronous() throws Exception {
97
        Action action = (Action)FileUtil.getConfigFile("actions/async/true.instance").getAttribute("instanceCreate");
98
        
99
        synchronized (AsynchronousTest.class) {
100
            action.actionPerformed(new ActionEvent(this, 0, ""));
101
            Thread.sleep(500);
102
            assertFalse("Shall Not be finished yet", AC.finished);
103
            AsynchronousTest.class.wait();
104
            assertTrue("The asynchronous action is finished", AC.finished);
105
        }
106
        
107
        if (err.length() > 0) {
108
            fail("No warning about the class: " + err);
109
        }
110
    }
111
112
    public void testExecutionCanBeAsynchronousForAlways() throws Exception {
113
        Action action = (Action)FileUtil.getConfigFile("actions/async/true-always.instance").getAttribute("instanceCreate");
114
115
        synchronized (AsynchronousTest.class) {
116
            action.actionPerformed(new ActionEvent(this, 0, ""));
117
            Thread.sleep(500);
118
            assertFalse("Shall Not be finished yet", AC.finished);
119
            AsynchronousTest.class.wait();
120
            assertTrue("The asynchronous action is finished", AC.finished);
121
        }
122
123
        if (err.length() > 0) {
124
            fail("No warning about the class: " + err);
125
        }
126
    }
127
    public void testExecutionCanBeSynchronous() throws Exception {
128
        Action action = (Action)FileUtil.getConfigFile("actions/async/false.instance").getAttribute("instanceCreate");
129
        
130
        synchronized (AsynchronousTest.class) {
131
            action.actionPerformed(new ActionEvent(this, 0, ""));
132
            assertTrue("The synchronous action is finished immediatelly", AC.finished);
133
        }
134
        
135
        if (err.length() > 0) {
136
            fail("No warning about the class: " + err);
137
        }
138
    }
139
    
140
    public void testExecutionCanBeForcedToBeSynchronous() throws Exception {
141
        Action action = (Action)FileUtil.getConfigFile("actions/async/true.instance").getAttribute("instanceCreate");
142
        
143
        synchronized (AsynchronousTest.class) {
144
            action.actionPerformed(new ActionEvent(this, 0, "waitFinished"));
145
            assertTrue("When asked for synchronous the action is finished immediatelly", AC.finished);
146
        }
147
        
148
        if (err.length() > 0) {
149
            fail("No warning about the class: " + err);
150
        }
151
    }
152
    
153
    public void testExecutionCanBeAsynchronousForContext() throws Exception {
154
        Action action = (Action)FileUtil.getConfigFile("actions/async/true-context.instance").getAttribute("instanceCreate");
155
156
        synchronized (AsynchronousTest.class) {
157
            action.actionPerformed(new ActionEvent(this, 0, ""));
158
            Thread.sleep(500);
159
            assertFalse("Shall Not be finished yet", AC.finished);
160
            AsynchronousTest.class.wait();
161
            assertTrue("The asynchronous action is finished", AC.finished);
162
        }
163
164
        if (err.length() > 0) {
165
            fail("No warning about the class: " + err);
166
        }
167
    }
168
169
    public static class AC extends AbstractAction {
170
        static boolean finished;
171
        
172
        public void actionPerformed(ActionEvent ev) {
173
            synchronized (AsynchronousTest.class) {
174
                AsynchronousTest.class.notifyAll();
175
                finished = true;
176
            }
177
        }
178
    }
179
180
    public static class CAC extends AC implements ContextAwareAction {
181
        public Action createContextAwareInstance(Lookup actionContext) {
182
            return this;
183
        }
184
    }
185
}
(-)a/openide.awt/test/unit/src/org/openide/awt/CallbackActionTest.java (-1 / +1 lines)
Lines 180-186 Link Here
180
    }
180
    }
181
181
182
    static ContextAwareAction callback(String key, AbstractAction fallAction, Lookup al, boolean b) {
182
    static ContextAwareAction callback(String key, AbstractAction fallAction, Lookup al, boolean b) {
183
        return GeneralAction.callback(key, fallAction, al, b);
183
        return GeneralAction.callback(key, fallAction, al, b, false);
184
    }
184
    }
185
    
185
    
186
    private static final class CntListener extends Object
186
    private static final class CntListener extends Object
(-)a/openide.awt/test/unit/src/org/openide/awt/GeneralActionTest.java (-1 / +1 lines)
Lines 81-87 Link Here
81
        
81
        
82
        ContextAwareAction expResult = null;
82
        ContextAwareAction expResult = null;
83
        try {
83
        try {
84
            ContextAwareAction result = GeneralAction.callback(key, defaultDelegate, context, false);
84
            ContextAwareAction result = GeneralAction.callback(key, defaultDelegate, context, false, false);
85
            fail("Shall fail as key is null");
85
            fail("Shall fail as key is null");
86
        } catch (NullPointerException ex) {
86
        } catch (NullPointerException ex) {
87
            // ok
87
            // ok
(-)a/openide.awt/test/unit/src/org/openide/awt/test-layer.xml (+37 lines)
Lines 170-174 Link Here
170
                </file>
170
                </file>
171
            </folder>
171
            </folder>
172
        </folder>
172
        </folder>
173
        <folder name="async">
174
            <file name="none.instance">
175
                <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
176
                <attr name='delegate' newvalue='org.openide.awt.AsynchronousTest$AC'/>
177
                <attr name='displayName' bundlevalue='org.openide.awt.TestBundle#Always'/>
178
            </file>
179
            <file name="true-always.instance">
180
                <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.alwaysEnabled'/>
181
                <attr name='delegate' newvalue='org.openide.awt.AsynchronousTest$AC'/>
182
                <attr name='displayName' bundlevalue='org.openide.awt.TestBundle#Always'/>
183
                <attr name="asynchronous" boolvalue="true"/>
184
            </file>
185
            <file name="true.instance">
186
                <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.callback'/>
187
                <attr name='fallback' newvalue='org.openide.awt.AsynchronousTest$AC'/>
188
                <attr name='key' stringvalue='delete'/>
189
                <attr name='displayName' bundlevalue='org.openide.awt.TestBundle#Always'/>
190
                <attr name="asynchronous" boolvalue="true"/>
191
            </file>
192
            <file name="true-context.instance">
193
               <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.context"/>
194
               <attr name="type" stringvalue="org.netbeans.api.actions.Openable"/>
195
               <attr name="selectionType" stringvalue="ANY"/>
196
               <attr name="delegate" newvalue="org.openide.awt.AsynchronousTest$CAC"/>
197
               <attr name="key" stringvalue="KeyInActionMap"/>
198
               <attr name="surviveFocusChange" boolvalue="false"/>
199
               <attr name="displayName" stringvalue="anything"/>
200
               <attr name="asynchronous" boolvalue="true"/>
201
            </file>
202
            <file name="false.instance">
203
                <attr name='instanceCreate' methodvalue='org.openide.awt.Actions.callback'/>
204
                <attr name='fallback' newvalue='org.openide.awt.AsynchronousTest$AC'/>
205
                <attr name='key' stringvalue='delete'/>
206
                <attr name='displayName' bundlevalue='org.openide.awt.TestBundle#Always'/>
207
                <attr name="asynchronous" boolvalue="false"/>
208
            </file>
209
        </folder>
173
    </folder> 
210
    </folder> 
174
</filesystem>
211
</filesystem>
(-)a/openide.util/src/org/netbeans/modules/openide/util/ActionsBridge.java (-1 / +19 lines)
Lines 61-66 Link Here
61
    protected abstract void invokeAction(Action action, ActionEvent ev);
61
    protected abstract void invokeAction(Action action, ActionEvent ev);
62
62
63
    public static void doPerformAction(CallableSystemAction action, final ActionsBridge.ActionRunnable r) {
63
    public static void doPerformAction(CallableSystemAction action, final ActionsBridge.ActionRunnable r) {
64
        implPerformAction(action, r);
65
    }
66
    public static void doPerformAction(Action action, final ActionsBridge.ActionRunnable r) {
67
        implPerformAction(action, r);
68
    }
69
    private static void implPerformAction(Action action, final ActionsBridge.ActionRunnable r) {
64
        assert java.awt.EventQueue.isDispatchThread() : "Action " + action.getClass().getName() +
70
        assert java.awt.EventQueue.isDispatchThread() : "Action " + action.getClass().getName() +
65
        " may not be invoked from the thread " + Thread.currentThread().getName() +
71
        " may not be invoked from the thread " + Thread.currentThread().getName() +
66
        ", only the event queue: http://www.netbeans.org/download/4_1/javadoc/OpenAPIs/apichanges.html#actions-event-thread";
72
        ", only the event queue: http://www.netbeans.org/download/4_1/javadoc/OpenAPIs/apichanges.html#actions-event-thread";
Lines 83-97 Link Here
83
     */
89
     */
84
    public static abstract class ActionRunnable implements Action {
90
    public static abstract class ActionRunnable implements Action {
85
        final ActionEvent ev;
91
        final ActionEvent ev;
86
        final SystemAction action;
92
        final Action action;
87
        final boolean async;
93
        final boolean async;
88
94
89
        public ActionRunnable(ActionEvent ev, SystemAction action, boolean async) {
95
        public ActionRunnable(ActionEvent ev, SystemAction action, boolean async) {
96
            this(ev, (Action)action, async);
97
        }
98
        public ActionRunnable(ActionEvent ev, Action action, boolean async) {
90
            this.ev = ev;
99
            this.ev = ev;
91
            this.action = action;
100
            this.action = action;
92
            this.async = async;
101
            this.async = async;
93
        }
102
        }
94
103
104
        public static ActionRunnable create(ActionEvent ev, Action a, boolean async) {
105
            return new ActionRunnable(ev, a, async) {
106
                @Override
107
                protected void run() {
108
                    action.actionPerformed(ev);
109
                }
110
            };
111
        }
112
95
        public final boolean needsToBeSynchronous() {
113
        public final boolean needsToBeSynchronous() {
96
            return "waitFinished".equals(ev.getActionCommand()); // NOI18N
114
            return "waitFinished".equals(ev.getActionCommand()); // NOI18N
97
        }
115
        }

Return to bug 168547