8032960: Running forms URL throws NullPointerException in Javaconsole.
Reviewed-by: anthony, serb
--- a/jdk/src/share/classes/java/awt/Toolkit.java Fri Feb 28 10:39:03 2014 +0000
+++ b/jdk/src/share/classes/java/awt/Toolkit.java Thu Apr 24 20:58:00 2014 +0400
@@ -2568,30 +2568,23 @@
public void firePropertyChange(final PropertyChangeEvent evt) {
Object oldValue = evt.getOldValue();
Object newValue = evt.getNewValue();
- String propertyName = evt.getPropertyName();
if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
return;
}
- Runnable updater = new Runnable() {
- public void run() {
- PropertyChangeSupport pcs = (PropertyChangeSupport)
- AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
- if (null != pcs) {
- pcs.firePropertyChange(evt);
- }
- }
- };
- final AppContext currentAppContext = AppContext.getAppContext();
for (AppContext appContext : AppContext.getAppContexts()) {
if (null == appContext || appContext.isDisposed()) {
continue;
}
- if (currentAppContext == appContext) {
- updater.run();
- } else {
- final PeerEvent e = new PeerEvent(source, updater, PeerEvent.ULTIMATE_PRIORITY_EVENT);
- SunToolkit.postEvent(appContext, e);
- }
+ final PeerEvent e = new PeerEvent(source,
+ () -> {
+ PropertyChangeSupport pcs = (PropertyChangeSupport)
+ AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
+ if (null != pcs) {
+ pcs.firePropertyChange(evt);
+ }
+ },
+ PeerEvent.ULTIMATE_PRIORITY_EVENT);
+ SunToolkit.postEvent(appContext, e);
}
}
}
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Fri Feb 28 10:39:03 2014 +0000
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Thu Apr 24 20:58:00 2014 +0400
@@ -930,12 +930,7 @@
* Windows doesn't always send WM_SETTINGCHANGE when it should.
*/
private void windowsSettingChange() {
- EventQueue.invokeLater(new Runnable() {
- @Override
- public void run() {
- updateProperties();
- }
- });
+ updateProperties();
}
private synchronized void updateProperties() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/NoAppContextTest.java Thu Apr 24 20:58:00 2014 +0400
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8032960
+ * @summary checks that desktop properties work if Toolkit thread has no AppContext
+ * @author Petr Pchelko
+ */
+
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class NoAppContextTest {
+
+ private static final ThreadGroup stubGroup = new ThreadGroup("stub");
+ private static final ThreadGroup awtGroup = new ThreadGroup("AWT");
+ private static final AtomicBoolean propertyChangeFired = new AtomicBoolean(false);
+ private static Frame frame;
+
+ private static final Object LOCK = new Object();
+
+ public static void main(String[] args) throws Exception {
+
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ // The test is for Windows platform only
+ return;
+ }
+
+ createStubContext();
+
+ Thread awtThread = new Thread(awtGroup, () -> {
+ SunToolkit.createNewAppContext();
+ SwingUtilities.invokeLater(() -> {
+ synchronized (LOCK) {
+ frame = new Frame();
+ frame.setBounds(100, 100, 100, 100);
+ frame.setVisible(true);
+ Toolkit.getDefaultToolkit().addPropertyChangeListener("win.propNames", ev -> {
+ propertyChangeFired.set(true);
+ });
+ }
+ });
+ });
+ awtThread.start();
+ awtThread.join();
+ sync();
+
+ final GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice();
+
+ AtomicReference<DisplayMode> originalRef = new AtomicReference<>();
+ try {
+ AtomicBoolean isSupported = new AtomicBoolean(true);
+ invokeInAWT(() -> {
+ if (device.isFullScreenSupported()) {
+ device.setFullScreenWindow(frame);
+ } else {
+ isSupported.set(false);
+ }
+ });
+ if (!isSupported.get()) {
+ return;
+ }
+ invokeInAWT(() -> {
+ if (device.isDisplayChangeSupported()) {
+ DisplayMode original = device.getDisplayMode();
+ originalRef.set(original);
+ try {
+ DisplayMode[] modes = device.getDisplayModes();
+ for (DisplayMode mode : modes) {
+ if (!mode.equals(original)) {
+ device.setDisplayMode(mode);
+ break;
+ }
+ }
+ } finally {
+ device.setDisplayMode(original);
+ }
+ } else {
+ isSupported.set(false);
+ }
+ });
+ if (!isSupported.get()) {
+ return;
+ }
+ } finally {
+ invokeInAWT(() -> {
+ device.setDisplayMode(originalRef.get());
+ frame.dispose();
+ });
+ }
+
+ if (!propertyChangeFired.get()) {
+ throw new RuntimeException("Failed: PropertyChange did not fire");
+ }
+ }
+
+ private static void invokeInAWT(Runnable r) throws InterruptedException {
+ Thread awtThread = new Thread(awtGroup, () -> {
+ SwingUtilities.invokeLater(() -> {
+ synchronized (LOCK) {
+ r.run();
+ }
+ });
+ });
+ awtThread.start();
+ awtThread.join();
+ sync();
+ }
+
+ private static void createStubContext() throws InterruptedException {
+ Thread stub = new Thread(stubGroup, SunToolkit::createNewAppContext);
+ stub.start();
+ stub.join();
+ }
+
+ /**
+ * Runs realSync on a thread with an AppContext and waits for it to finish
+ */
+ private static void sync() throws InterruptedException {
+ final AtomicReference<InterruptedException> exc = new AtomicReference<>(null);
+
+ Thread syncThread = new Thread(awtGroup, () -> {
+ try {
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ exc.set(e);
+ }
+ });
+ syncThread.start();
+ syncThread.join();
+ if (exc.get() != null) {
+ throw exc.get();
+ }
+ }
+}
+