--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Tue Feb 28 10:44:56 2012 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Tue Feb 28 16:09:15 2012 +0200
@@ -152,8 +152,8 @@
if (!c.isEnabled()) {
state = DISABLED;
}
- if (SynthLookAndFeel.selectedUI == this) {
- return SynthLookAndFeel.selectedUIState | SynthConstants.ENABLED;
+ if (SynthLookAndFeel.getSelectedUI() == this) {
+ return SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED;
}
AbstractButton button = (AbstractButton) c;
ButtonModel model = button.getModel();
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java Tue Feb 28 10:44:56 2012 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java Tue Feb 28 16:09:15 2012 +0200
@@ -97,9 +97,9 @@
private int getComponentState(JComponent c) {
int state = SynthLookAndFeel.getComponentState(c);
- if (SynthLookAndFeel.selectedUI == this &&
+ if (SynthLookAndFeel.getSelectedUI() == this &&
state == SynthConstants.ENABLED) {
- state = SynthLookAndFeel.selectedUIState | SynthConstants.ENABLED;
+ state = SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED;
}
return state;
}
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Tue Feb 28 10:44:56 2012 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Tue Feb 28 16:09:15 2012 +0200
@@ -77,27 +77,25 @@
new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache");
/**
+ * AppContext key to get selectedUI.
+ */
+ private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI");
+
+ /**
+ * AppContext key to get selectedUIState.
+ */
+ private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState");
+
+ /**
* The last SynthStyleFactory that was asked for from AppContext
* <code>lastContext</code>.
*/
private static SynthStyleFactory lastFactory;
/**
- * If this is true it indicates there is more than one AppContext active
- * and that we need to make sure in getStyleCache the requesting
- * AppContext matches that of <code>lastContext</code> before returning
- * it.
- */
- private static boolean multipleApps;
- /**
* AppContext lastLAF came from.
*/
private static AppContext lastContext;
- // Refer to setSelectedUI
- static ComponentUI selectedUI;
- // Refer to setSelectedUI
- static int selectedUIState;
-
/**
* SynthStyleFactory for the this SynthLookAndFeel.
*/
@@ -111,6 +109,10 @@
private Handler _handler;
+ static ComponentUI getSelectedUI() {
+ return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY);
+ }
+
/**
* Used by the renderers. For the most part the renderers are implemented
* as Labels, which is problematic in so far as they are never selected.
@@ -122,8 +124,8 @@
static void setSelectedUI(ComponentUI uix, boolean selected,
boolean focused, boolean enabled,
boolean rollover) {
- selectedUI = uix;
- selectedUIState = 0;
+ int selectedUIState = 0;
+
if (selected) {
selectedUIState = SynthConstants.SELECTED;
if (focused) {
@@ -140,19 +142,32 @@
else {
if (enabled) {
selectedUIState |= SynthConstants.ENABLED;
- selectedUIState = SynthConstants.FOCUSED;
+ if (focused) {
+ selectedUIState |= SynthConstants.FOCUSED;
+ }
}
else {
selectedUIState |= SynthConstants.DISABLED;
}
}
+
+ AppContext context = AppContext.getAppContext();
+
+ context.put(SELECTED_UI_KEY, uix);
+ context.put(SELECTED_UI_STATE_KEY, Integer.valueOf(selectedUIState));
+ }
+
+ static int getSelectedUIState() {
+ Integer result = (Integer) AppContext.getAppContext().get(SELECTED_UI_STATE_KEY);
+
+ return result == null ? 0 : result.intValue();
}
/**
* Clears out the selected UI that was last set in setSelectedUI.
*/
static void resetSelectedUI() {
- selectedUI = null;
+ AppContext.getAppContext().remove(SELECTED_UI_KEY);
}
@@ -167,10 +182,6 @@
// for a particular AppContext.
synchronized(SynthLookAndFeel.class) {
AppContext context = AppContext.getAppContext();
- if (!multipleApps && context != lastContext &&
- lastContext != null) {
- multipleApps = true;
- }
lastFactory = cache;
lastContext = context;
context.put(STYLE_FACTORY_KEY, cache);
@@ -184,17 +195,13 @@
*/
public static SynthStyleFactory getStyleFactory() {
synchronized(SynthLookAndFeel.class) {
- if (!multipleApps) {
- return lastFactory;
- }
AppContext context = AppContext.getAppContext();
if (lastContext == context) {
return lastFactory;
}
lastContext = context;
- lastFactory = (SynthStyleFactory)AppContext.getAppContext().get
- (STYLE_FACTORY_KEY);
+ lastFactory = (SynthStyleFactory) context.get(STYLE_FACTORY_KEY);
return lastFactory;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/synth/7143614/bug7143614.java Tue Feb 28 16:09:15 2012 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 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 7143614
+ * @summary Issues with Synth Look&Feel
+ * @author Pavel Porvatov
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicButtonUI;
+import javax.swing.plaf.synth.SynthConstants;
+import javax.swing.plaf.synth.SynthLookAndFeel;
+import java.lang.reflect.Method;
+
+public class bug7143614 {
+ private static Method setSelectedUIMethod;
+
+ private static ComponentUI componentUI = new BasicButtonUI();
+
+ public static void main(String[] args) throws Exception {
+ setSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("setSelectedUI", ComponentUI.class,
+ boolean.class, boolean.class, boolean.class, boolean.class);
+ setSelectedUIMethod.setAccessible(true);
+
+ setSelectedUIMethod.invoke(null, componentUI, true, true, true, true);
+
+ validate();
+
+ Thread thread = new ThreadInAnotherAppContext();
+
+ thread.start();
+ thread.join();
+
+ validate();
+
+ System.out.println("Test bug7143614 passed.");
+ }
+
+ private static void validate() throws Exception {
+ Method getSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUI");
+
+ getSelectedUIMethod.setAccessible(true);
+
+ Method getSelectedUIStateMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUIState");
+
+ getSelectedUIStateMethod.setAccessible(true);
+
+ if (getSelectedUIMethod.invoke(null) != componentUI) {
+ throw new RuntimeException("getSelectedUI returns invalid value");
+ }
+ if (((Integer) getSelectedUIStateMethod.invoke(null)).intValue() !=
+ (SynthConstants.SELECTED | SynthConstants.FOCUSED)) {
+ throw new RuntimeException("getSelectedUIState returns invalid value");
+ }
+
+ }
+
+ private static class ThreadInAnotherAppContext extends Thread {
+ public ThreadInAnotherAppContext() {
+ super(new ThreadGroup("7143614"), "ThreadInAnotherAppContext");
+ }
+
+ public void run() {
+ SunToolkit.createNewAppContext();
+
+ try {
+ setSelectedUIMethod.invoke(null, null, false, false, false, false);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}