diff --git a/README b/README index d774ab80b70466958efc3ae02347b54eb84fc1b5..e3cc63ec993be85b2eb12e21d38d3e1a16f007f4 100644 --- a/README +++ b/README @@ -9,25 +9,35 @@ Simple Build Instructions: http://java.sun.com/javase/downloads/index.jsp Set the environment variable ALT_BOOTDIR to the location of this JDK 6. - 2. Download and install the Binary Plugs for the most recent JDK7 from + 2. Download and install the JIBX libraries, version 1.1.5 from + http://sourceforge.net/project/showfiles.php?group_id=69358&package_id=68290 + You'll need the following four JAR files: + bcel.jar + jibx-bind.jar + jibx-run.jar + xpp3.jar + Set the environment variable ALT_JIBX_LIBS_PATH to the location of + these JAR files. + + 3. Download and install the Binary Plugs for the most recent JDK7 from http://download.java.net/openjdk/jdk7/ Set the environment variable ALT_BINARY_PLUGS_PATH to the location of these binary plugs. - 3. Either download and install the latest JDK7 from + 4. Either download and install the latest JDK7 from http://download.java.net/openjdk/jdk7/, or build your own complete OpenJDK7 by using the top level Makefile in the OpenJDK Mercurial forest. Set the environment variable ALT_JDK_IMPORT_PATH to the location of this latest JDK7 or OpenJDK7 build. - 4. Check the sanity of doing a build with the current machine: + 5. Check the sanity of doing a build with the current machine: cd make && gnumake sanity See README-builds.html if you run into problems. - 5. Do a partial build of the jdk: + 6. Do a partial build of the jdk: cd make && gnumake all - 6. Construct the images: + 7. Construct the images: cd make && gnumake images The resulting JDK image should be found in build/*/j2sdk-image diff --git a/make/common/Sanity.gmk b/make/common/Sanity.gmk index 3388be0403fbb6fc9878d4e9af2545edf4830362..eb4f00eb89953fc4449ecdaf229705e98c713bee 100644 --- a/make/common/Sanity.gmk +++ b/make/common/Sanity.gmk @@ -92,7 +92,8 @@ sanity-all:: sanity-base \ sane-ld_run_path \ sane-alt_bootdir \ sane-bootdir \ - sane-alsa-headers + sane-alsa-headers \ + sane-jibx ifdef OPENJDK sanity-all:: sane-freetype diff --git a/make/common/shared/Defs.gmk b/make/common/shared/Defs.gmk index 5da4a29047e20de6af1a8777bb30b59efaad98fc..dc62f1ee5a47409882446c95e670e8199d3a8be4 100644 --- a/make/common/shared/Defs.gmk +++ b/make/common/shared/Defs.gmk @@ -515,6 +515,15 @@ endif # NOTE: ISA_DIR is usually empty, on Solaris it might be /sparcv9 or /amd64 BINDIR = $(OUTPUTDIR)/bin$(ISA_DIR) +# JIBX_LIBS_PATH: path to JIBX libraries, needed for NimbusLookAndFeel +ifdef ALT_JIBX_LIBS_PATH + JIBX_LIBS_PATH:=$(call FullPath,$(ALT_JIBX_LIBS_PATH)) + JIBX_LIBS_PATH:=$(call AltCheckSpaces,JIBX_LIBS_PATH) + JIBX_LIBS_PATH:=$(call AltCheckValue,JIBX_LIBS_PATH) +else + JIBX_LIBS_PATH=$(JDK_DEVTOOLS_DIR)/share/jibx/lib +endif + # MOZILLA_HEADERS_PATH: path to mozilla header files for plugin ifdef ALT_MOZILLA_HEADERS_PATH MOZILLA_HEADERS_PATH :=$(call FullPath,$(ALT_MOZILLA_HEADERS_PATH)) @@ -529,7 +538,7 @@ ifneq ($(PLATFORM), windows) JDK_CUPS_HEADERS_PATH=$(JDK_DEVTOOLS_DIR)/share/cups/include ifdef ALT_CUPS_HEADERS_PATH CUPS_HEADERS_PATH:=$(call FullPath,$(ALT_CUPS_HEADERS_PATH)) - CUP_HEADERS_PATH:=$(call AltCheckValue,CUPS_HEADERS_PATH) + CUPS_HEADERS_PATH:=$(call AltCheckValue,CUPS_HEADERS_PATH) else CUPS_HEADERS_PATH:= \ $(shell if [ -d "$(JDK_CUPS_HEADERS_PATH)" ]; then \ diff --git a/make/common/shared/Sanity-Settings.gmk b/make/common/shared/Sanity-Settings.gmk index b64e3b52a136a931d3230425feebadcd5fad802b..283598e394db424f6cac63f832dddac05129209e 100644 --- a/make/common/shared/Sanity-Settings.gmk +++ b/make/common/shared/Sanity-Settings.gmk @@ -233,6 +233,7 @@ ifeq ($(PLATFORM),windows) endif endif ALL_SETTINGS+=$(call addAltSetting,CACERTS_FILE) +ALL_SETTINGS+=$(call addAltSetting,JIBX_LIBS_PATH) ifndef OPENJDK ALL_SETTINGS+=$(call addAltSetting,MOZILLA_HEADERS_PATH) endif diff --git a/make/common/shared/Sanity.gmk b/make/common/shared/Sanity.gmk index 180e52196a999ee3f366ed96723285ca6d380268..84d5e2201a0b18e42108858f671c704b491a27d3 100644 --- a/make/common/shared/Sanity.gmk +++ b/make/common/shared/Sanity.gmk @@ -213,6 +213,7 @@ include $(JDK_MAKE_SHARED_DIR)/Sanity-Settings.gmk sane-link \ sane-cacerts \ sane-alsa-headers \ + sane-jibx \ sane-ant_version \ sane-zip_version \ sane-unzip_version \ @@ -1497,6 +1498,18 @@ ifeq ($(PLATFORM), solaris) endif +###################################################### +# JIBX_LIBS_PATH must be valid +###################################################### +sane-jibx: + @if [ ! -r $(subst \,/,$(JIBX_LIBS_PATH))/jibx-run.jar ]; then \ + $(ECHO) "ERROR: You do not have access to valid JIBX library files. \n" \ + " Please check your access to \n" \ + " $(subst \,/,$(JIBX_LIBS_PATH))/jibx-run.jar \n" \ + " and/or check your value of ALT_JDK_DEVTOOLS_DIR, ALT_JIBX_LIBS_PATH \n" \ + "" >> $(ERROR_FILE) ; \ + fi + ###################################################### # MOZILLA_HEADERS_PATH must be valid ###################################################### diff --git a/make/javax/swing/plaf/Makefile b/make/javax/swing/plaf/Makefile index f8e5e0c150a30d77d1097864f399da675273d7c8..aea88f2f7ff11aef3bb2785a085d11d6de192713 100644 --- a/make/javax/swing/plaf/Makefile +++ b/make/javax/swing/plaf/Makefile @@ -34,9 +34,14 @@ include $(BUILDDIR)/common/Defs.gmk # include FILES.gmk AUTO_FILES_JAVA_DIRS = javax/swing/plaf sun/swing com/sun/java/swing/plaf +SUBDIRS = nimbus + +# Nimbus is handled in its own directory +AUTO_JAVA_PRUNE = nimbus + ifeq ($(PLATFORM), windows) # Don't build GTK L&F on Windows - AUTO_JAVA_PRUNE = gtk + AUTO_JAVA_PRUNE += gtk endif MISC_FILES = $(MISC_SWING_FILES) @@ -68,8 +73,10 @@ endif # Process LOGO_ICONS and Motif Icons first. # build: $(LOGO_ICONS) $(MISC_SWING_FILES_MOTIF_GIF) $(MISC_SWING_FILES_MOTIF_PNG) other_files + $(SUBDIRS-loop) -clean:: classes.clean +clean clobber:: + $(SUBDIRS-loop) # # Include diff --git a/make/javax/swing/plaf/nimbus/Makefile b/make/javax/swing/plaf/nimbus/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ed59f137e5379b64d7e73d3a8a5c1ff271fa086d --- /dev/null +++ b/make/javax/swing/plaf/nimbus/Makefile @@ -0,0 +1,60 @@ +# +# Copyright 1998-2007 Sun Microsystems, Inc. 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun in the LICENSE file that accompanied this code. +# +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +BUILDDIR = ../../../.. +PACKAGE = javax.swing.plaf.nimbus +PRODUCT = com +SWING_SRC = $(SHARE_SRC)/classes/javax/swing +include $(BUILDDIR)/common/Defs.gmk + +# +# Files +# +NIMBUS_PKG = javax/swing/plaf/nimbus +NIMBUS_COMPAT_PKG = com/sun/java/swing/plaf/nimbus +NIMBUS_GENSRC_DIR = $(GENSRCDIR)/$(NIMBUS_PKG) +NIMBUS_SKIN_FILE = $(SHARE_SRC)/classes/$(NIMBUS_PKG)/skin.laf +NIMBUS_GENERATOR_JAR = $(BUILDTOOLJARDIR)/nimbus_generator.jar + +AUTO_FILES_JAVA_DIRS = $(NIMBUS_PKG) $(NIMBUS_COMPAT_PKG) + + +# +# Rules +# +CLASSES_INIT = $(NIMBUS_GENSRC_DIR) + +include $(BUILDDIR)/common/Classes.gmk + +$(NIMBUS_GENSRC_DIR): $(NIMBUS_SKIN_FILE) $(NIMBUS_GENERATOR_JAR) + @$(ECHO) "Generating Nimbus source files:" + $(BOOT_JAVA_CMD) -jar $(NIMBUS_GENERATOR_JAR) \ + -skinFile $(NIMBUS_SKIN_FILE) \ + -buildDir $(GENSRCDIR) -srcDir $(GENSRCDIR) \ + -packagePrefix $(PACKAGE) -lafName Nimbus + @$(ECHO) "Finished generating Nimbus source files" + +clean clobber:: + $(RM) -r $(NIMBUS_GENSRC_DIR) diff --git a/make/tools/Makefile b/make/tools/Makefile index 3803fbc6edabb494e7b7318384985815ac39ec7d..a927209f3304a497b8ac72da965d1b8ba7c6ffb2 100644 --- a/make/tools/Makefile +++ b/make/tools/Makefile @@ -51,6 +51,7 @@ SUBDIRS = \ makeclasslist \ strip_properties \ spp \ + swing-nimbus \ CharsetMapping all build clean clobber:: diff --git a/make/tools/swing-nimbus/Makefile b/make/tools/swing-nimbus/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..36df571c5f5be4c8f7a283ecdc8af1d905dee0fa --- /dev/null +++ b/make/tools/swing-nimbus/Makefile @@ -0,0 +1,91 @@ +# +# Copyright 1998-2005 Sun Microsystems, Inc. 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. Sun designates this +# particular file as subject to the "Classpath" exception as provided +# by Sun in the LICENSE file that accompanied this code. +# +# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# Makefile for building the Nimbus generator +# + +BUILDDIR = ../.. +PACKAGE = org.jdesktop.synthdesigner.generator +PRODUCT = tools +PROGRAM = nimbus_generator +include $(BUILDDIR)/common/Defs.gmk + +BUILDTOOL_SOURCE_ROOT = classes +BUILDTOOL_MAIN = $(PKGDIR)/Generator.java + +# +# Files +# + +MAIN_CLASS_FILE = $(BUILDTOOLCLASSDIR)/$(BUILDTOOL_MAIN:%.java=%.class) +SOURCE_FILES = $(shell $(FIND) $(BUILDTOOL_SOURCE_ROOT) -name '*.java' -print) + +TEMPLATE_FILES = $(SHARE_SRC)/classes/javax/swing/plaf/nimbus/Defaults.template \ + $(SHARE_SRC)/classes/javax/swing/plaf/nimbus/PainterImpl.template \ + $(SHARE_SRC)/classes/javax/swing/plaf/nimbus/StateImpl.template +TEMPLATE_DEST = $(BUILDTOOLCLASSDIR)/org/jdesktop/synthdesigner/generator/resources + +JIBX_FILES = $(BUILDTOOL_SOURCE_ROOT)/org/jdesktop/swingx/designer/Designer.jibx.xml \ + $(BUILDTOOL_SOURCE_ROOT)/org/jdesktop/synthdesigner/synthmodel/SynthModel.jibx.xml +JIBX_LIBS_CP = $(JIBX_LIBS_PATH)/bcel.jar$(CLASSPATH_SEPARATOR)$(JIBX_LIBS_PATH)/xpp3.jar$(CLASSPATH_SEPARATOR)$(JIBX_LIBS_PATH)/jibx-bind.jar$(CLASSPATH_SEPARATOR)$(JIBX_LIBS_PATH)/jibx-run.jar +JIBX_LIBS_LIST = $(subst $(CLASSPATH_SEPARATOR), ,$(JIBX_LIBS_CP)) + + +# +# Rules +# + +include $(BUILDDIR)/common/BuildToolJar.gmk + +$(MAIN_CLASS_FILE): $(SOURCE_FILES) $(JIBX_LIBS_LIST) + @$(MKDIR) -p $(BUILDTOOLCLASSDIR) + $(BOOT_JAVAC_CMD) -classpath "$(JIBX_LIBS_CP)" \ + -d $(BUILDTOOLCLASSDIR) -sourcepath $(BUILDTOOL_SOURCE_ROOT) \ + $(SOURCE_FILES) + +$(TEMPLATE_DEST): $(TEMPLATE_FILES) + $(MKDIR) -p $(TEMPLATE_DEST) + $(RM) $(TEMPLATE_DEST)/*.template + $(CP) $(TEMPLATE_FILES) $(TEMPLATE_DEST) + +$(BUILDTOOL_MANIFEST_FILE): $(MAIN_CLASS_FILE) + $(ECHO) "Main-Class: $(BUILTTOOL_MAINCLASS)" > $@ + $(ECHO) "Class-Path: $(JIBX_LIBS_LIST:$(JIBX_LIBS_PATH)/%=%)" >> $@ + $(CP) $(JIBX_LIBS_LIST) $(BUILDTOOLJARDIR) + +$(BUILDTOOL_JAR_FILE): $(MAIN_CLASS_FILE) $(TEMPLATE_DEST) \ + $(JIBX_FILES) $(BUILDTOOL_MANIFEST_FILE) + @$(prep-target) + $(BOOT_JAVA_CMD) \ + -classpath "$(JIBX_LIBS_CP)$(CLASSPATH_SEPARATOR)$(BUILDTOOLCLASSDIR)" \ + org.jibx.binding.Compile $(JIBX_FILES) + $(BOOT_JAR_CMD) cfm $@ $(BUILDTOOL_MANIFEST_FILE) \ + -C $(BUILDTOOLCLASSDIR) org \ + $(BOOT_JAR_JFLAGS) || $(RM) $@ + @$(java-vm-cleanup) + +clean clobber:: + $(RM) -r $(TEMPLATE_DEST) diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/beans/AbstractBean.java b/make/tools/swing-nimbus/classes/org/jdesktop/beans/AbstractBean.java new file mode 100644 index 0000000000000000000000000000000000000000..91325319b1ac01edaa86954e5f4cb56e92e1ee23 --- /dev/null +++ b/make/tools/swing-nimbus/classes/org/jdesktop/beans/AbstractBean.java @@ -0,0 +1,475 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package org.jdesktop.beans; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; + +/** + *
A convenience class from which to extend all non-visual AbstractBeans. It + * manages the PropertyChange notification system, making it relatively trivial + * to add support for property change events in getters/setters.
+ * + *A non-visual java bean is a Java class that conforms to the AbstractBean + * patterns to allow visual manipulation of the bean's properties and event + * handlers at design-time.
+ * + *Here is a simple example bean that contains one property, foo, and the + * proper pattern for implementing property change notification: + *
+ * public class ABean extends AbstractBean {
+ * private String foo;
+ *
+ * public void setFoo(String newFoo) {
+ * String old = getFoo();
+ * this.foo = newFoo;
+ * firePropertyChange("foo", old, getFoo());
+ * }
+ *
+ * public String getFoo() {
+ * return foo;
+ * }
+ * }
+ *
+ *
+ * You will notice that "getFoo()" is used in the setFoo method rather than + * accessing "foo" directly for the gets. This is done intentionally so that if + * a subclass overrides getFoo() to return, for instance, a constant value the + * property change notification system will continue to work properly.
+ * + *The firePropertyChange method takes into account the old value and the new + * value. Only if the two differ will it fire a property change event. So you can + * be assured from the above code fragment that a property change event will only + * occur if old is indeed different from getFoo()
+ * + *AbstractBean
also supports {@link VetoablePropertyChange} events.
+ * These events are similar to PropertyChange
events, except a special
+ * exception can be used to veto changing the property. For example, perhaps the
+ * property is changing from "fred" to "red", but a listener deems that "red" is
+ * unexceptable. In this case, the listener can fire a veto exception and the property must
+ * remain "fred". For example:
+ *
+ * public class ABean extends AbstractBean {
+ * private String foo;
+ *
+ * public void setFoo(String newFoo) throws PropertyVetoException {
+ * String old = getFoo();
+ * this.foo = newFoo;
+ * fireVetoableChange("foo", old, getFoo());
+ * }
+ *
+ * public String getFoo() {
+ * return foo;
+ * }
+ * }
+ *
+ * public class Tester {
+ * public static void main(String... args) {
+ * try {
+ * ABean a = new ABean();
+ * a.setFoo("fred");
+ * a.addVetoableChangeListener(new VetoableChangeListener() {
+ * public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
+ * if ("red".equals(evt.getNewValue()) {
+ * throw new PropertyVetoException("Cannot be red!", evt);
+ * }
+ * }
+ * }
+ * a.setFoo("red");
+ * } catch (Exception e) {
+ * e.printStackTrace(); // this will be executed
+ * }
+ * }
+ * }
+ *
+ *
+ * @status REVIEWED
+ * @author rbair
+ */
+public abstract class AbstractBean {
+ /**
+ * Helper class that manages all the property change notification machinery.
+ * PropertyChangeSupport cannot be extended directly because it requires
+ * a bean in the constructor, and the "this" argument is not valid until
+ * after super construction. Hence, delegation instead of extension
+ */
+ private transient PropertyChangeSupport pcs;
+
+ /**
+ * Helper class that manages all the veto property change notification machinery.
+ */
+ private transient VetoableChangeSupport vcs;
+
+ /** Creates a new instance of AbstractBean */
+ protected AbstractBean() {
+ pcs = new PropertyChangeSupport(this);
+ vcs = new VetoableChangeSupport(this);
+ }
+
+ /**
+ * Creates a new instance of AbstractBean, using the supplied PropertyChangeSupport and
+ * VetoableChangeSupport delegates. Neither of these may be null.
+ */
+ protected AbstractBean(PropertyChangeSupport pcs, VetoableChangeSupport vcs) {
+ if (pcs == null) {
+ throw new NullPointerException("PropertyChangeSupport must not be null");
+ }
+ if (vcs == null) {
+ throw new NullPointerException("VetoableChangeSupport must not be null");
+ }
+
+ this.pcs = pcs;
+ this.vcs = vcs;
+ }
+
+ /**
+ * Add a PropertyChangeListener to the listener list.
+ * The listener is registered for all properties.
+ * The same listener object may be added more than once, and will be called
+ * as many times as it is added.
+ * If listener
is null, no exception is thrown and no action
+ * is taken.
+ *
+ * @param listener The PropertyChangeListener to be added
+ */
+ public final void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Remove a PropertyChangeListener from the listener list.
+ * This removes a PropertyChangeListener that was registered
+ * for all properties.
+ * If listener
was added more than once to the same event
+ * source, it will be notified one less time after being removed.
+ * If listener
is null, or was never added, no exception is
+ * thrown and no action is taken.
+ *
+ * @param listener The PropertyChangeListener to be removed
+ */
+ public final void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Returns an array of all the listeners that were added to the
+ * PropertyChangeSupport object with addPropertyChangeListener().
+ *
+ * If some listeners have been added with a named property, then
+ * the returned array will be a mixture of PropertyChangeListeners
+ * and PropertyChangeListenerProxy
s. If the calling
+ * method is interested in distinguishing the listeners then it must
+ * test each element to see if it's a
+ * PropertyChangeListenerProxy
, perform the cast, and examine
+ * the parameter.
+ *
+ *
+ * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners(); + * for (int i = 0; i < listeners.length; i++) { + * if (listeners[i] instanceof PropertyChangeListenerProxy) { + * PropertyChangeListenerProxy proxy = + * (PropertyChangeListenerProxy)listeners[i]; + * if (proxy.getPropertyName().equals("foo")) { + * // proxy is a PropertyChangeListener which was associated + * // with the property named "foo" + * } + * } + * } + *+ * + * @see java.beans.PropertyChangeListenerProxy + * @return all of the
PropertyChangeListeners
added or an
+ * empty array if no listeners have been added
+ */
+ public final PropertyChangeListener[] getPropertyChangeListeners() {
+ return pcs.getPropertyChangeListeners();
+ }
+
+ /**
+ * Add a PropertyChangeListener for a specific property. The listener
+ * will be invoked only when a call on firePropertyChange names that
+ * specific property.
+ * The same listener object may be added more than once. For each
+ * property, the listener will be invoked the number of times it was added
+ * for that property.
+ * If propertyName
or listener
is null, no
+ * exception is thrown and no action is taken.
+ *
+ * @param propertyName The name of the property to listen on.
+ * @param listener The PropertyChangeListener to be added
+ */
+ public final void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Remove a PropertyChangeListener for a specific property.
+ * If listener
was added more than once to the same event
+ * source for the specified property, it will be notified one less time
+ * after being removed.
+ * If propertyName
is null, no exception is thrown and no
+ * action is taken.
+ * If listener
is null, or was never added for the specified
+ * property, no exception is thrown and no action is taken.
+ *
+ * @param propertyName The name of the property that was listened on.
+ * @param listener The PropertyChangeListener to be removed
+ */
+ public final void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Returns an array of all the listeners which have been associated
+ * with the named property.
+ *
+ * @param propertyName The name of the property being listened to
+ * @return all of the PropertyChangeListeners
associated with
+ * the named property. If no such listeners have been added,
+ * or if propertyName
is null, an empty array is
+ * returned.
+ */
+ public final PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+ return pcs.getPropertyChangeListeners(propertyName);
+ }
+
+ /**
+ * Report a bound property update to any registered listeners.
+ * No event is fired if old and new are equal and non-null.
+ *
+ * + * This is merely a convenience wrapper around the more general + * firePropertyChange method that takes {@code + * PropertyChangeEvent} value. + * + * @param propertyName The programmatic name of the property + * that was changed. + * @param oldValue The old value of the property. + * @param newValue The new value of the property. + */ + protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + pcs.firePropertyChange(propertyName, oldValue, newValue); + } + + /** + * Fire an existing PropertyChangeEvent to any registered listeners. + * No event is fired if the given event's old and new values are + * equal and non-null. + * @param evt The PropertyChangeEvent object. + */ + protected final void firePropertyChange(PropertyChangeEvent evt) { + pcs.firePropertyChange(evt); + } + + + /** + * Report a bound indexed property update to any registered + * listeners. + *
+ * No event is fired if old and new values are equal + * and non-null. + * + *
+ * This is merely a convenience wrapper around the more general
+ * firePropertyChange method that takes {@code PropertyChangeEvent} value.
+ *
+ * @param propertyName The programmatic name of the property that
+ * was changed.
+ * @param index index of the property element that was changed.
+ * @param oldValue The old value of the property.
+ * @param newValue The new value of the property.
+ */
+ protected final void fireIndexedPropertyChange(String propertyName,
+ int index, Object oldValue, Object newValue) {
+ pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
+ }
+
+ /**
+ * Check if there are any listeners for a specific property, including
+ * those registered on all properties. If propertyName
+ * is null, only check for listeners registered on all properties.
+ *
+ * @param propertyName the property name.
+ * @return true if there are one or more listeners for the given property
+ */
+ protected final boolean hasPropertyChangeListeners(String propertyName) {
+ return pcs.hasListeners(propertyName);
+ }
+
+ /**
+ * Check if there are any listeners for a specific property, including
+ * those registered on all properties. If propertyName
+ * is null, only check for listeners registered on all properties.
+ *
+ * @param propertyName the property name.
+ * @return true if there are one or more listeners for the given property
+ */
+ protected final boolean hasVetoableChangeListeners(String propertyName) {
+ return vcs.hasListeners(propertyName);
+ }
+
+ /**
+ * Add a VetoableListener to the listener list.
+ * The listener is registered for all properties.
+ * The same listener object may be added more than once, and will be called
+ * as many times as it is added.
+ * If listener
is null, no exception is thrown and no action
+ * is taken.
+ *
+ * @param listener The VetoableChangeListener to be added
+ */
+
+ public final void addVetoableChangeListener(VetoableChangeListener listener) {
+ vcs.addVetoableChangeListener(listener);
+ }
+
+ /**
+ * Remove a VetoableChangeListener from the listener list.
+ * This removes a VetoableChangeListener that was registered
+ * for all properties.
+ * If listener
was added more than once to the same event
+ * source, it will be notified one less time after being removed.
+ * If listener
is null, or was never added, no exception is
+ * thrown and no action is taken.
+ *
+ * @param listener The VetoableChangeListener to be removed
+ */
+ public final void removeVetoableChangeListener(VetoableChangeListener listener) {
+ vcs.removeVetoableChangeListener(listener);
+ }
+
+ /**
+ * Returns the list of VetoableChangeListeners. If named vetoable change listeners
+ * were added, then VetoableChangeListenerProxy wrappers will returned
+ *
+ * @return List of VetoableChangeListeners and VetoableChangeListenerProxys
+ * if named property change listeners were added.
+ */
+ public final VetoableChangeListener[] getVetoableChangeListeners(){
+ return vcs.getVetoableChangeListeners();
+ }
+
+ /**
+ * Add a VetoableChangeListener for a specific property. The listener
+ * will be invoked only when a call on fireVetoableChange names that
+ * specific property.
+ * The same listener object may be added more than once. For each
+ * property, the listener will be invoked the number of times it was added
+ * for that property.
+ * If propertyName
or listener
is null, no
+ * exception is thrown and no action is taken.
+ *
+ * @param propertyName The name of the property to listen on.
+ * @param listener The VetoableChangeListener to be added
+ */
+
+ public final void addVetoableChangeListener(String propertyName,
+ VetoableChangeListener listener) {
+ vcs.addVetoableChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Remove a VetoableChangeListener for a specific property.
+ * If listener
was added more than once to the same event
+ * source for the specified property, it will be notified one less time
+ * after being removed.
+ * If propertyName
is null, no exception is thrown and no
+ * action is taken.
+ * If listener
is null, or was never added for the specified
+ * property, no exception is thrown and no action is taken.
+ *
+ * @param propertyName The name of the property that was listened on.
+ * @param listener The VetoableChangeListener to be removed
+ */
+
+ public final void removeVetoableChangeListener(String propertyName,
+ VetoableChangeListener listener) {
+ vcs.removeVetoableChangeListener(propertyName, listener);
+ }
+
+ /**
+ * Returns an array of all the listeners which have been associated
+ * with the named property.
+ *
+ * @param propertyName The name of the property being listened to
+ * @return all the VetoableChangeListeners
associated with
+ * the named property. If no such listeners have been added,
+ * or if propertyName
is null, an empty array is
+ * returned.
+ */
+ public final VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
+ return vcs.getVetoableChangeListeners(propertyName);
+ }
+
+ /**
+ * Report a vetoable property update to any registered listeners. If
+ * anyone vetos the change, then fire a new event reverting everyone to
+ * the old value and then rethrow the PropertyVetoException.
+ *
+ * No event is fired if old and new are equal and non-null. + * + * @param propertyName The programmatic name of the property + * that is about to change.. + * @param oldValue The old value of the property. + * @param newValue The new value of the property. + * @exception PropertyVetoException if the recipient wishes the property + * change to be rolled back. + */ + protected final void fireVetoableChange(String propertyName, + Object oldValue, Object newValue) + throws PropertyVetoException { + vcs.fireVetoableChange(propertyName, oldValue, newValue); + } + + /** + * Fire a vetoable property update to any registered listeners. If + * anyone vetos the change, then fire a new event reverting everyone to + * the old value and then rethrow the PropertyVetoException. + *
+ * No event is fired if old and new are equal and non-null.
+ *
+ * @param evt The PropertyChangeEvent to be fired.
+ * @exception PropertyVetoException if the recipient wishes the property
+ * change to be rolled back.
+ */
+ protected final void fireVetoableChange(PropertyChangeEvent evt)
+ throws PropertyVetoException {
+ vcs.fireVetoableChange(evt);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public Object clone() throws CloneNotSupportedException {
+ AbstractBean result = (AbstractBean) super.clone();
+ result.pcs = new PropertyChangeSupport(result);
+ result.vcs = new VetoableChangeSupport(result);
+ return result;
+ }
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BezierControlPoint.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BezierControlPoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..be2bc4efbd9ca675436b1a3d1313ff24a665ecfb
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BezierControlPoint.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * BezierControlPoint
+ *
+ * @author Created by Jasper Potts (May 29, 2007)
+ */
+public class BezierControlPoint extends ControlPoint {
+ private HandleControlPoint cp1 = new HandleControlPoint();
+ private HandleControlPoint cp2 = new HandleControlPoint();
+ private transient boolean makingChange = false;
+ private transient PropertyChangeListener cpListener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent evt) {
+// if (!makingChange) {
+// makingChange = true;
+// if (evt.getSource() == cp1) {
+// double angle = Math.tan((cp1.getY() - getY())/(cp1.getX() - getX()));
+// double cp2len = Math.sqrt(
+// Math.pow(cp2.getX() - getX(),2) +
+// Math.pow(cp2.getY() - getY(),2)
+// );
+// double offsetX = cp2len * Math.sin(angle);
+// double offsetY = cp2len * Math.cos(angle);
+// cp2.setPosition(getX() - offsetX, getY() - offsetY);
+// } else {
+// double angle = Math.tan((cp2.getY() - getY())/(cp2.getX() - getX()));
+// double cp1len = Math.sqrt(
+// Math.pow(cp1.getX() - getX(),2) +
+// Math.pow(cp1.getY() - getY(),2)
+// );
+// double offsetX = cp1len * Math.sin(angle);
+// double offsetY = cp1len * Math.cos(angle);
+// cp1.setPosition(getX() - offsetX, getY() - offsetY);
+// }
+//// if (evt.getSource() == cp1) {
+//// double offsetX = cp1.getX() - getX();
+//// double offsetY = cp1.getY() - getY();
+//// cp2.setPosition(getX() - offsetX, getY() - offsetY);
+//// } else {
+//// double offsetX = cp2.getX() - getX();
+//// double offsetY = cp2.getY() - getY();
+//// cp1.setPosition(getX() - offsetX, getY() - offsetY);
+//// }
+// makingChange = false;
+// firePropertyChange("cp1", null, cp1);
+// firePropertyChange("cp2", null, cp1);
+// }
+ firePropertyChange("shape",null,getShape());
+ }
+ };
+
+ public BezierControlPoint() {
+ cp1.addPropertyChangeListener(cpListener);
+ cp2.addPropertyChangeListener(cpListener);
+ }
+
+ public BezierControlPoint(double x, double y) {
+ super(x, y);
+ cp1.addPropertyChangeListener(cpListener);
+ cp2.addPropertyChangeListener(cpListener);
+ cp1.setPosition(x, y);
+ cp2.setPosition(x, y);
+ }
+
+ public boolean isSharpCorner() {
+ return
+ (cp1.getX() == x.getValue()) &&
+ (cp1.getY() == y.getValue()) &&
+ (cp2.getX() == x.getValue()) &&
+ (cp2.getY() == y.getValue());
+ }
+
+ public void flip(int width, int height){
+ makingChange = true;
+ if (width > 0){
+ x.setValue(width - x.getValue());
+ cp1.x.setValue(width - cp1.x.getValue());
+ cp2.x.setValue(width - cp2.x.getValue());
+ }
+ if (height > 0){
+ y.setValue(height - y.getValue());
+ cp1.y.setValue(height - cp1.y.getValue());
+ cp2.y.setValue(height - cp2.y.getValue());
+ }
+ makingChange = false;
+ }
+
+ public void convertToSharpCorner() {
+ cp1.setPosition(x.getValue(), y.getValue());
+ cp2.setPosition(x.getValue(), y.getValue());
+ }
+
+ public List Blurs the source pixels into the destination pixels. The force of the blur is specified by the radius which
+ * must be greater than 0. The source and destination pixels arrays are expected to be in the BYTE_GREY
+ * format. After this method is executed, dstPixels contains a transposed and filtered copy of
+ * srcPixels. Sets the size of the font. THis method call will work whether
+ * For example, if the parent font's size was 12, and the sizeOffset was
+ * -2 (thus yielding as size on this typeface of 10), and you call setSize
+ * passing in "14" as the size, then the sizeOffset will be updated to be
+ * equal to "2".
+ * The full set of mixer info objects that represent the mixers supported
+ * by this {@code MixerProvider} may be obtained
+ * through the {@code getMixerInfo} method.
+ *
* @param info an info object that describes the mixer for which support is queried
- * @return
+ * The {@code isMixerSupported} method returns {@code true}
+ * for all the info objects returned by this method.
+ * The corresponding mixer instances for the info objects
+ * are returned by the {@code getMixer} method.
+ *
+ * @return a set of mixer info objects
+ * @see #getMixer(javax.sound.sampled.Mixer.Info) getMixer(Mixer.Info)
+ * @see #isMixerSupported(javax.sound.sampled.Mixer.Info) isMixerSupported(Mixer.Info)
*/
public abstract Mixer.Info[] getMixerInfo();
/**
* Obtains an instance of the mixer represented by the info object.
+ *
+ * The full set of the mixer info objects that represent the mixers
+ * supported by this {@code MixerProvider} may be obtained
+ * through the {@code getMixerInfo} method.
+ * Use the {@code isMixerSupported} method to test whether
+ * this {@code MixerProvider} supports a particular mixer.
+ *
* @param info an info object that describes the desired mixer
* @return mixer instance
* @throws IllegalArgumentException if the info object specified does not
- * match the info object for a mixer supported by this MixerProvider.
+ * match the info object for a mixer supported by this MixerProvider.
+ * @see #getMixerInfo()
+ * @see #isMixerSupported(javax.sound.sampled.Mixer.Info) isMixerSupported(Mixer.Info)
*/
public abstract Mixer getMixer(Mixer.Info info);
}
diff --git a/src/share/classes/javax/swing/DefaultCellEditor.java b/src/share/classes/javax/swing/DefaultCellEditor.java
index da1bbcc53d8df488efc956fb6bb9b6ee4c2b253e..3320d379d3582717112a6d6c27f6466bbd2119d8 100644
--- a/src/share/classes/javax/swing/DefaultCellEditor.java
+++ b/src/share/classes/javax/swing/DefaultCellEditor.java
@@ -266,6 +266,26 @@ public class DefaultCellEditor extends AbstractCellEditor
boolean isSelected,
int row, int column) {
delegate.setValue(value);
+ if (editorComponent instanceof JCheckBox) {
+ //in order to avoid a "flashing" effect when clicking a checkbox
+ //in a table, it is important for the editor to have as a border
+ //the same border that the renderer has, and have as the background
+ //the same color as the renderer has. This is primarily only
+ //needed for JCheckBox since this editor doesn't fill all the
+ //visual space of the table cell, unlike a text field.
+ TableCellRenderer renderer = table.getCellRenderer(row, column);
+ Component c = renderer.getTableCellRendererComponent(table, value,
+ isSelected, true, row, column);
+ if (c != null) {
+ editorComponent.setOpaque(true);
+ editorComponent.setBackground(c.getBackground());
+ if (c instanceof JComponent) {
+ editorComponent.setBorder(((JComponent)c).getBorder());
+ }
+ } else {
+ editorComponent.setOpaque(false);
+ }
+ }
return editorComponent;
}
diff --git a/src/share/classes/javax/swing/DefaultListCellRenderer.java b/src/share/classes/javax/swing/DefaultListCellRenderer.java
index 4d523e0f78af067599a8a21cdd8cd8755b34ef8d..2cb42272ae8bba0b6c79f43b5b8be8719abccd3f 100644
--- a/src/share/classes/javax/swing/DefaultListCellRenderer.java
+++ b/src/share/classes/javax/swing/DefaultListCellRenderer.java
@@ -34,6 +34,7 @@ import java.awt.Color;
import java.awt.Rectangle;
import java.io.Serializable;
+import sun.swing.DefaultLookup;
/**
@@ -79,8 +80,9 @@ public class DefaultListCellRenderer extends JLabel
* This interface makes no guarantees of threadsafety. Renders to the given {@link java.awt.Graphics2D} object. Implementations
+ * of this method may modify state on the State on the graphics object may be honored by the The supplied object parameter acts as an optional configuration argument.
+ * For example, it could be of type Generally, to enhance reusability, most standard Finally, the For example, suppose I have a Gets the PaintContext for this painting operation. This method is called on every
+ * paint, and so should be fast and produce no garbage. The PaintContext contains
+ * information such as cache hints. It also contains data necessary for decoding
+ * points at runtime, such as the stretching insets, the canvas size at which the
+ * encoded points were defined, and whether the stretching insets are inverted. This method allows for subclasses to package the painting of different states
+ * with possibly different canvas sizes, etc, into one AbstractRegionPainter implementation. Configures the given Graphics2D. Often, rendering hints or compositiing rules are
+ * applied to a Graphics2D object prior to painting, which should affect all of the
+ * subsequent painting operations. This method provides a convenient hook for configuring
+ * the Graphics object prior to rendering, regardless of whether the render operation is
+ * performed to an intermediate buffer or directly to the display. Registers the given region and prefix. The prefix, if it contains
+ * quoted sections, refers to certain named components. If there are not
+ * quoted sections, then the prefix refers to a generic component type. If the given region/prefix combo has already been registered, then
+ * it will not be registered twice. The second registration attempt will
+ * fail silently. Locate the style associated with the given region, and component.
+ * This is called from ${LAF_NAME}LookAndFeel in the SynthStyleFactory
+ * implementation. Lookup occurs as follows: Derives its font value based on a parent font and a set of offsets and
+ * attributes. This class is an ActiveValue, meaning that it will recompute
+ * its value each time it is requested from UIDefaults. It is therefore
+ * recommended to read this value once and cache it in the UI delegate class
+ * until asked to reinitialize. To use this class, create an instance with the key of the font in the
+ * UI defaults table from which to derive this font, along with a size
+ * offset (if any), and whether it is to be bold, italic, or left in its
+ * default form. Blurs the source pixels into the destination pixels. The force of the blur is specified by the radius which
+ * must be greater than 0. The source and destination pixels arrays are expected to be in the INT_ARGB
+ * format. After this method is executed, dstPixels contains a transposed and filtered copy of
+ * srcPixels. Blurs the source pixels into the destination pixels. The force of the blur is specified by the radius which
+ * must be greater than 0. The source and destination pixels arrays are expected to be in the BYTE_GREY
+ * format. After this method is executed, dstPixels contains a transposed and filtered copy of
+ * srcPixels. Returns an array of pixels, stored as integers, from a Writes a rectangular area of pixels in the destination Returns an array of pixels, stored as integers, from a
+ * Writes a rectangular area of pixels in the destination
+ * Returns a new Returns a new translucent compatible image of the specified width and
+ * height. That is, the returned Gets the PaintContext for this painting operation. This method is
+ * called on every paint, and so should be fast and produce no garbage. The
+ * PaintContext contains information such as cache hints. It also contains
+ * data necessary for decoding points at runtime, such as the stretching
+ * insets, the canvas size at which the encoded points were defined, and
+ * whether the stretching insets are inverted. This method allows for subclasses to package the painting of
+ * different states with possibly different canvas sizes, etc, into one
+ * AbstractRegionPainter implementation. The NimbusLookAndFeel class. Registers a third party component with the NimbusLookAndFeel. Regions represent Components and areas within Components that act as
+ * independent painting areas. Once registered with the NimbusLookAndFeel,
+ * NimbusStyles for these Regions can be retrieved via the
+ * The NimbusLookAndFeel uses a standard naming scheme for entries in the
+ * UIDefaults table. The key for each property, state, painter, and other
+ * default registered in UIDefaults for a specific Region will begin with
+ * the specified For example, suppose I had a component named JFoo. Suppose I then registered
+ * this component with the NimbusLookAndFeel in this manner: In this case, I could then register properties for this component with
+ * UIDefaults in the following manner: It is also possible to register a named component with Nimbus.
+ * For example, suppose you wanted to style the background of a JPanel
+ * named "MyPanel" differently from other JPanels. You could accomplish this
+ * by doing the following: A SynthStyle implementation used by Nimbus. Each Region that has been
+ * registered with the NimbusLookAndFeel will have an associated NimbusStyle.
+ * Third party components that are registered with the NimbusLookAndFeel will
+ * therefore be handed a NimbusStyle from the look and feel from the
+ * #getStyle(JComponent, Region) method. This class properly reads and retrieves values placed in the UIDefaults
+ * according to the standard Nimbus naming conventions. It will create and
+ * retrieve painters, fonts, colors, and other data stored there. NimbusStyle also supports the ability to override settings on a per
+ * component basis. NimbusStyle checks the component's client property map for
+ * "Nimbus.Overrides". If the value associated with this key is an instance of
+ * UIDefaults, then the values in that defaults table will override the standard
+ * Nimbus defaults in UIManager, but for that component instance only. Optionally, you may specify the client property
+ * "Nimbus.Overrides.InheritDefaults". If true, this client property indicates
+ * that the defaults located in UIManager should first be read, and then
+ * replaced with defaults located in the component client properties. If false,
+ * then only the defaults located in the component client property map will
+ * be used. If not specified, it is assumed to be true. You must specify "Nimbus.Overrides" for "Nimbus.Overrides.InheritDefaults"
+ * to have any effect. "Nimbus.Overrides" indicates whether there are any
+ * overrides, while "Nimbus.Overrides.InheritDefaults" indicates whether those
+ * overrides should first be initialized with the defaults from UIManager. The NimbusStyle is reloaded whenever a property change event is fired
+ * for a component for "Nimbus.Overrides" or "Nimbus.Overrides.InheritDefaults".
+ * So for example, setting a new UIDefaults on a component would cause the
+ * style to be reloaded. The values are only read out of UIManager once, and then cached. If
+ * you need to read the values again (for example, if the UI is being reloaded),
+ * then discard this NimbusStyle and read a new one from NimbusLookAndFeel
+ * using NimbusLookAndFeel.getStyle. The primary API of interest in this class for 3rd party component authors
+ * are the three methods which retrieve painters: #getBackgroundPainter,
+ * #getForegroundPainter, and #getBorderPainter. NimbusStyle allows you to specify custom states, or modify the order of
+ * states. Synth (and thus Nimbus) has the concept of a "state". For example,
+ * a JButton might be in the "MOUSE_OVER" state, or the "ENABLED" state, or the
+ * "DISABLED" state. These are all "standard" states which are defined in synth,
+ * and which apply to all synth Regions. Sometimes, however, you need to have a custom state. For example, you
+ * want JButton to render differently if it's parent is a JToolbar. In Nimbus,
+ * you specify these custom states by including a special key in UIDefaults.
+ * The following UIDefaults entries define three states for this button: As you can see, the The Color to return from getColorForState if it would otherwise have
+ * returned null. Returning null from getColorForState is a very bad thing, as it causes
+ * the AWT peer for the component to install a SystemColor, which is not a
+ * UIResource. As a result, if Overridden to cause this style to populate itself with data from
+ * UIDefaults, if necessary. In addition, NimbusStyle handles ColorTypes slightly differently from
+ * Synth. Overridden to cause this style to populate itself with data from
+ * UIDefaults, if necessary. Properties in UIDefaults may be specified in a chained manner. For
+ * example:
+ * true
If this is the exact same point as the parent BezierControlPoint.
+ */
+ public boolean isSharp(){
+ return x.getValue() == BezierControlPoint.this.x.getValue() &&
+ y.getValue() == BezierControlPoint.this.y.getValue();
+ }
+
+ public void convertToSharp(){
+ setPosition(BezierControlPoint.this.x.getValue(),BezierControlPoint.this.y.getValue());
+ }
+
+ public BezierControlPoint getParentControlPoint(){
+ return BezierControlPoint.this;
+ }
+ }
+
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BlendingMode.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BlendingMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ade7d08c39e652bad7d238e2b1cf6a4554b0fea9
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BlendingMode.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer;
+
+
+/**
+ * BlendingMode - Enum of composite blending modes, setup to match photoshop as closely as possible
+ *
+ * @author Created by Jasper Potts (May 31, 2007)
+ */
+public enum BlendingMode {
+ NORMAL,
+ // DISSOLVE, missing
+ // -----------------------------
+ DARKEN,
+ MULTIPLY,
+ COLOR_BURN,
+ LINEAR_BURN, // (SUBTRACT)
+ // -----------------------------
+ LIGHTEN,
+ SCREEN,
+ COLOR_DODGE,
+ LINEAR_DODGE, // (ADD)
+ // -----------------------------
+ OVERLAY,
+ SOFT_LIGHT,
+ HARD_LIGHT,
+ VIVID_LIGHT, // (HEAT) is close
+ LINEAR_LIGHT, // (GLOW) is close
+ //PIN_LIGHT, missing
+ //HARD_MIX, missing
+ // -----------------------------
+ DIFFERENCE,
+ EXCLUSION,
+ // -----------------------------
+ HUE, // nowhere close
+ SATURATION,
+ COLOR,
+ LUMINOSITY, // close but not exact
+ //LIGHTER_COLOR, missing
+ //DARKER_COLOR, missing
+ ;
+
+
+ // =================================================================================================================
+ // Helper methods for creating Blending Mode Combo Box
+
+ public static final Object[] BLENDING_MODES = new Object[]{
+ BlendingMode.NORMAL,
+ // DISSOLVE, missing
+ "-",
+ BlendingMode.DARKEN,
+ BlendingMode.MULTIPLY,
+ BlendingMode.COLOR_BURN,
+ BlendingMode.LINEAR_BURN, // (SUBTRACT)
+ "-",
+ BlendingMode.LIGHTEN,
+ BlendingMode.SCREEN,
+ BlendingMode.COLOR_DODGE,
+ BlendingMode.LINEAR_DODGE, // (ADD)
+ "-",
+ BlendingMode.OVERLAY,
+ BlendingMode.SOFT_LIGHT,
+ BlendingMode.HARD_LIGHT,
+ BlendingMode.VIVID_LIGHT, // (HEAT) is close
+ BlendingMode.LINEAR_LIGHT, // (GLOW) is close
+ //PIN_LIGHT, missing
+ //HARD_MIX, missing
+ "-",
+ BlendingMode.DIFFERENCE,
+ BlendingMode.EXCLUSION,
+ "-",
+ BlendingMode.HUE, // nowhere close
+ BlendingMode.SATURATION,
+ BlendingMode.COLOR,
+ BlendingMode.LUMINOSITY, // close but not exact
+ };
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Canvas.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Canvas.java
new file mode 100644
index 0000000000000000000000000000000000000000..43f9cc621792a025eab9be8e31714bb2ce18b011
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Canvas.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer;
+
+import org.jdesktop.beans.AbstractBean;
+import org.jdesktop.swingx.designer.utils.HasResources;
+import org.jdesktop.swingx.designer.utils.HasUIDefaults;
+import org.jibx.runtime.IUnmarshallingContext;
+
+import javax.swing.UIDefaults;
+import java.awt.AlphaComposite;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * ComponentRegion
+ *
+ * @author Created by Jasper Potts (May 22, 2007)
+ */
+public class Canvas extends AbstractBean implements LayerContainer, HasUIDefaults, HasResources {
+ private Dimension size;
+ /** list of all layers in the canvas, the first layer is painted on top */
+ private Listtrue
+ */
+ public boolean isLocked() {
+ return true;
+ }
+
+ public void add(SimpleShape shape) {
+ throw new IllegalStateException("Template layers can't contain shapes");
+ }
+
+ public void addEffect(Effect effect) {
+ throw new IllegalStateException("Template layers can't contain effects");
+ }
+
+ public void addLayer(int i, Layer layer) {
+ throw new IllegalStateException("Template layers can't contain sub layers");
+ }
+
+ public void addLayer(Layer layer) {
+ throw new IllegalStateException("Template layers can't contain sub layers");
+ }
+
+ public void paint(Graphics2D g2, double pixelSize) {
+ if (isVisible()) {
+ BufferedImage img = getTemplateImage();
+ if (img != null) g2.drawImage(img, 0, 0, null);
+ }
+ }
+
+
+ public Image getBuffer(GraphicsConfiguration graphicsConfiguration) {
+ return getTemplateImage();
+ }
+
+ public BufferedImage getTemplateImage() {
+ BufferedImage img = null;
+ if (imgRef == null || (img = imgRef.get()) == null) {
+
+ // can not access canvas
+ final File templateImgFile = new File(getCanvas().getTemplatesDir(), fileName);
+ System.out.println("templateImgFile = " + templateImgFile.getAbsolutePath());
+ System.out.println("templateImgFile.exists = " + templateImgFile.exists());
+ try {
+ img = ImageIO.read(templateImgFile);
+ imgRef = new SoftReferencetrue
if this is a absolute not uidefault derived font
+ */
+ public boolean isAbsolute() {
+ return uiDefaultParentName == null;
+ }
+
+ /**
+ * Set all properties of this Typeface to be the same as src
and fire all the change events
+ *
+ * @param src the Typeface to copy properties from
+ */
+ public void copy(Typeface src) {
+ // keep old values
+ Font oldFont = getFont();
+ String oldParentName = uiDefaultParentName;
+ String oldName = name;
+ int oldSize = size;
+ float oldSizeOffset = sizeOffset;
+ DeriveStyle oldBold = bold, oldItalic = italic;
+
+ style = src.style;
+
+ //Note, I don't just call the setters here, because I want to make
+ //sure the "font" PCE is only fired once, at the end.
+ name = src.name;
+ firePropertyChange("name", oldName, name);
+ size = src.size;
+ firePropertyChange("size", oldSize, size);
+ bold = src.bold;
+ firePropertyChange("bold", oldBold, bold);
+ italic = src.italic;
+ firePropertyChange("italic", oldItalic, italic);
+ sizeOffset = src.sizeOffset;
+ firePropertyChange("sizeOffset", oldSizeOffset, sizeOffset);
+ uiDefaultParentName = src.uiDefaultParentName;
+ firePropertyChange("uiDefaultParentName", oldParentName, uiDefaultParentName);
+ setUiDefaults(src.uiDefaults);
+ firePropertyChange("font", oldFont, getFont());
+ }
+
+ // =================================================================================================================
+ // Bean Methods
+
+ /**
+ * Get the local UIDefaults that contains all the UIDefaults in the Model.
+ *
+ * @return The UIDefaults for the model that contains this Typeface, can be null if this Typeface is not part of a bigger
+ * model
+ */
+ public UIDefaults getUiDefaults() {
+ return uiDefaults;
+ }
+
+ /**
+ * Set the local UIDefaults that contains all the UIDefaults in the Model.
+ *
+ * @param uiDefaults The UIDefaults for the model that contains this Typeface, can be null if this Typeface is not part of
+ * a bigger model
+ */
+ public void setUiDefaults(UIDefaults uiDefaults) {
+ if (uiDefaults != this.uiDefaults) {
+ UIDefaults old = getUiDefaults();
+ if (old != null) old.removePropertyChangeListener(uiDefaultsChangeListener);
+ this.uiDefaults = uiDefaults;
+ if (uiDefaults != null) this.uiDefaults.addPropertyChangeListener(uiDefaultsChangeListener);
+ firePropertyChange("uiDefaults", old, getUiDefaults());
+ }
+ }
+
+ /**
+ * Get the name if the uidefault font that is the parent that this Typeface is derived from. If null then this is a
+ * absolute font.
+ *
+ * @return Parent font ui default name
+ */
+ public String getUiDefaultParentName() {
+ return uiDefaultParentName;
+ }
+
+ /**
+ * Set the name if the uidefault font that is the parent that this Typeface is derived from. If null then this is a
+ * absolute font.
+ *
+ * @param uiDefaultParentName Parent font ui default name
+ */
+ public void setUiDefaultParentName(String uiDefaultParentName) {
+ String old = getUiDefaultParentName();
+ this.uiDefaultParentName = uiDefaultParentName;
+ firePropertyChange("uiDefaultParentName", old, getUiDefaultParentName());
+ if (isAbsolute()) {
+ // reset offsets
+ float oldSizeOffset = sizeOffset;
+ sizeOffset = 0;
+ firePropertyChange("sizeOffset", oldSizeOffset, sizeOffset);
+ } else {
+ updateFontFromOffsets();
+ }
+ }
+
+ /**
+ * @return Gets the name of the font
+ */
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the font. This method call only works if
+ * isAbsolute
returns true. Otherwise, it is ignored.
+ * @param name the name of the font
+ */
+ public void setName(String name) {
+ if (isAbsolute()) {
+ String old = this.name;
+ Font oldF = getFont();
+ this.name = name;
+ firePropertyChange("name", old, this.name);
+ firePropertyChange("font", oldF, getFont());
+ }
+ }
+
+ /**
+ * @return gets the size of the font.
+ */
+ public final int getSize() {
+ return size;
+ }
+
+ /**
+ * isAbsolute
returns true or false. If this is an absolute
+ * typeface, then the size is set directly. Otherwise, if this is a
+ * derived typeface, then the sizeOffset will be updated to reflect the
+ * proper offset based on this size, and the size of the parent font.true
if this is a absolute not uidefault derived color
+ */
+ public boolean isAbsolute() {
+ return uiDefaultParentName == null;
+ }
+
+ /**
+ * Set all properties of this matte to be the same as srcMatte
and fire all the change events
+ *
+ * @param srcMatte the matte to copy properties from
+ */
+ public void copy(Matte srcMatte) {
+ // keep old values
+ Color oldColor = getColor();
+ String oldParentName = uiDefaultParentName;
+ String oldComponentPropertyName = componentPropertyName;
+ boolean oldUiResource = uiResource;
+ int oldR = red, oldG = green, oldB = blue, oldA = alpha;
+ float oldH = hueOffset, oldS = saturationOffset, oldBr = brightnessOffset;
+ // set properties
+ if (uiResource != srcMatte.uiResource) {
+ uiResource = srcMatte.uiResource;
+ firePropertyChange("uiResource", oldUiResource, isUiResource());
+ }
+ if (red != srcMatte.red) {
+ red = srcMatte.red;
+ firePropertyChange("red", oldR, getRed());
+ }
+ if (green != srcMatte.green) {
+ green = srcMatte.green;
+ firePropertyChange("green", oldG, getGreen());
+ }
+ if (blue != srcMatte.blue) {
+ blue = srcMatte.blue;
+ firePropertyChange("blue", oldB, getBlue());
+ }
+ if (alpha != srcMatte.alpha) {
+ alpha = srcMatte.alpha;
+ firePropertyChange("alpha", oldA, getAlpha());
+ }
+ if (hueOffset != srcMatte.hueOffset) {
+ hueOffset = srcMatte.hueOffset;
+ firePropertyChange("hueOffset", oldH, getHueOffset());
+ }
+ if (saturationOffset != srcMatte.saturationOffset) {
+ saturationOffset = srcMatte.saturationOffset;
+ firePropertyChange("saturationOffset", oldS, getSaturationOffset());
+ }
+ if (brightnessOffset != srcMatte.brightnessOffset) {
+ brightnessOffset = srcMatte.brightnessOffset;
+ firePropertyChange("brightnessOffset", oldBr, getBrightnessOffset());
+ }
+ if (alphaOffset != srcMatte.alphaOffset) {
+ alphaOffset = srcMatte.alphaOffset;
+ firePropertyChange("alphaOffset", oldA, getAlphaOffset());
+ }
+ if (uiDefaultParentName != srcMatte.uiDefaultParentName) {
+ uiDefaultParentName = srcMatte.uiDefaultParentName;
+ firePropertyChange("uiDefaultParentName", oldParentName, getUiDefaultParentName());
+ }
+ if (componentPropertyName != srcMatte.componentPropertyName) {
+ componentPropertyName = srcMatte.componentPropertyName;
+ firePropertyChange("componentPropertyName", oldComponentPropertyName, getComponentPropertyName());
+ }
+ if (uiDefaults != srcMatte.uiDefaults) {
+ setUiDefaults(srcMatte.uiDefaults);
+ }
+ if (!oldColor.equals(srcMatte.getColor())) {
+ firePropertyChange("paint", oldColor, getColor());
+ firePropertyChange("color", oldColor, getColor());
+ fireHSBChange(oldR, oldG, oldB);
+ }
+ }
+
+ // =================================================================================================================
+ // PaintModel methods
+
+ public PaintControlType getPaintControlType() {
+ return PaintControlType.none;
+ }
+
+ // =================================================================================================================
+ // Bean Methods
+
+ /**
+ * Get the local UIDefaults that contains all the UIDefaults in the Model.
+ *
+ * @return The UIDefaults for the model that contains this Matte, can be null if this Matte is not part of a bigger
+ * model
+ */
+ public UIDefaults getUiDefaults() {
+ return uiDefaults;
+ }
+
+ /**
+ * Set the local UIDefaults that contains all the UIDefaults in the Model.
+ *
+ * @param uiDefaults The UIDefaults for the model that contains this Matte, can be null if this Matte is not part of
+ * a bigger model
+ */
+ public void setUiDefaults(UIDefaults uiDefaults) {
+ if (uiDefaults != this.uiDefaults) {
+ UIDefaults old = getUiDefaults();
+ if (old != null) old.removePropertyChangeListener(uiDefaultsChangeListener);
+ this.uiDefaults = uiDefaults;
+ if (uiDefaults != null) this.uiDefaults.addPropertyChangeListener(uiDefaultsChangeListener);
+ firePropertyChange("uiDefaults", old, getUiDefaults());
+ }
+ }
+
+ /**
+ * Get the name if the uidefault color that is the parent that this matte is derived from. If null then this is a
+ * absolute color.
+ *
+ * @return Parent color ui default name
+ */
+ public String getUiDefaultParentName() {
+ return uiDefaultParentName;
+ }
+
+ /**
+ * Set the name if the uidefault color that is the parent that this matte is derived from. If null then this is a
+ * absolute color.
+ *
+ * @param uiDefaultParentName Parent color ui default name
+ */
+ public void setUiDefaultParentName(String uiDefaultParentName) {
+ String old = getUiDefaultParentName();
+ this.uiDefaultParentName = uiDefaultParentName;
+ firePropertyChange("uiDefaultParentName", old, getUiDefaultParentName());
+ if (isAbsolute()) {
+ // reset offsets
+ float oldH = hueOffset, oldS = saturationOffset, oldB = brightnessOffset;
+ int oldA = alphaOffset;
+ hueOffset = 0;
+ saturationOffset = 0;
+ brightnessOffset = 0;
+ alphaOffset = 0;
+ firePropertyChange("hueOffset", oldH, getHueOffset());
+ firePropertyChange("saturationOffset", oldS, getSaturationOffset());
+ firePropertyChange("brightnessOffset", oldB, getBrightnessOffset());
+ firePropertyChange("alphaOffset", oldA, getAlphaOffset());
+ }
+ updateARGBFromOffsets();
+ }
+
+ /**
+ * Sets the property to use for extracting the color for whatever component
+ * is passed to the painter. Can be a key in client properties. Can be null.
+ * @param name
+ */
+ public void setComponentPropertyName(String name) {
+ String old = componentPropertyName;
+ firePropertyChange("componentPropertyName", old, componentPropertyName = name);
+ }
+
+ /**
+ * Gets the name of the bean property, or client property, on this component
+ * from which to extract a color used for painting. So for example the color
+ * used in a painter could be the background of the component.
+ *
+ * @return
+ */
+ public String getComponentPropertyName() {
+ return componentPropertyName;
+ }
+
+ /**
+ * Sets whether this color should be represented as a UIResource in UIDefaults
+ * @param b true if the color should be a ui resource
+ */
+ public void setUiResource(boolean b) {
+ boolean old = uiResource;
+ firePropertyChange("uiResource", old, uiResource = b);
+ }
+
+ /**
+ * When false this color will become a non-UIResource in the UIManager defaults
+ * table. This is sometimes required to force swing to use the given color,
+ * such as with renderers.
+ * @return false if the color should not be a uiresource
+ */
+ public boolean isUiResource() {
+ return uiResource;
+ }
+
+ public float getHueOffset() {
+ return hueOffset;
+ }
+
+ public void setHueOffset(float hueOffset) {
+ float old = getHueOffset();
+ this.hueOffset = hueOffset;
+ firePropertyChange("hueOffset", old, getHueOffset());
+ updateARGBFromOffsets();
+ }
+
+ public float getSaturationOffset() {
+ return saturationOffset;
+ }
+
+ public void setSaturationOffset(float satOffset) {
+ float old = getSaturationOffset();
+ this.saturationOffset = satOffset;
+ firePropertyChange("saturationOffset", old, getSaturationOffset());
+ updateARGBFromOffsets();
+ }
+
+ public float getBrightnessOffset() {
+ return brightnessOffset;
+ }
+
+ public void setBrightnessOffset(float brightOffset) {
+ float old = getBrightnessOffset();
+ this.brightnessOffset = brightOffset;
+ firePropertyChange("brightnessOffset", old, getBrightnessOffset());
+ updateARGBFromOffsets();
+ }
+
+ public int getAlphaOffset() {
+ return alphaOffset;
+ }
+
+ public void setAlphaOffset(int alphaOffset) {
+ int old = getAlphaOffset();
+ this.alphaOffset = alphaOffset;
+ firePropertyChange("alphaOffset", old, alphaOffset);
+ updateARGBFromOffsets();
+ }
+
+
+ public void setRed(int red) {
+ red = clamp(red);
+ if (this.red != red) {
+ Color old = getColor();
+ int oldr = this.red;
+ this.red = red;
+ firePropertyChange("paint", old, getColor());
+ firePropertyChange("color", old, getColor());
+ firePropertyChange("red", oldr, red);
+ fireHSBChange(oldr, green, blue);
+ updateOffsetsFromARGB();
+ }
+ }
+
+ public final int getRed() {
+ return red;
+ }
+
+ public void setGreen(int green) {
+ green = clamp(green);
+ if (this.green != green) {
+ Color old = getColor();
+ int oldg = this.green;
+ this.green = green;
+ firePropertyChange("paint", old, getColor());
+ firePropertyChange("color", old, getColor());
+ firePropertyChange("green", oldg, green);
+ fireHSBChange(red, oldg, blue);
+ updateOffsetsFromARGB();
+ }
+ }
+
+ public final int getGreen() {
+ return green;
+ }
+
+ public void setBlue(int blue) {
+ blue = clamp(blue);
+ if (this.blue != blue) {
+ Color old = getColor();
+ int oldb = this.blue;
+ this.blue = blue;
+ firePropertyChange("paint", old, getColor());
+ firePropertyChange("color", old, getColor());
+ firePropertyChange("blue", oldb, blue);
+ fireHSBChange(red, green, oldb);
+ updateOffsetsFromARGB();
+ }
+ }
+
+ public final int getBlue() {
+ return blue;
+ }
+
+ public void setAlpha(int alpha) {
+ alpha = clamp(alpha);
+ if (this.alpha != alpha) {
+ int old = getAlpha();
+ this.alpha = alpha;
+ firePropertyChange("alpha", old, alpha);
+ firePropertyChange("paint", old, getColor());
+ firePropertyChange("color", old, getColor());
+ updateOffsetsFromARGB();
+ }
+ }
+
+ public final int getAlpha() {
+ return alpha;
+ }
+
+ public Color getColor() {
+ if (cached == null || red != cached.getRed() || green != cached.getGreen() ||
+ blue != cached.getBlue() || alpha != cached.getAlpha()) {
+ cached = new Color(red, green, blue, alpha);
+ }
+ return cached;
+ }
+
+ public void setColor(Color c) {
+ setColor(c, false);
+ }
+
+ public void setColor(Color c, boolean dontSetAlpha) {
+ Color oldColor = getColor();
+ int oldR = red, oldG = green, oldB = blue, oldA = alpha;
+ cached = c;
+ red = c.getRed();
+ green = c.getGreen();
+ blue = c.getBlue();
+ if (!dontSetAlpha) alpha = c.getAlpha();
+ updateOffsetsFromARGB();
+ firePropertyChange("red", oldR, getRed());
+ firePropertyChange("green", oldG, getGreen());
+ firePropertyChange("blue", oldB, getBlue());
+ fireHSBChange(oldR, oldG, oldB);
+ if (!dontSetAlpha) firePropertyChange("alpha", oldA, getAlpha());
+ firePropertyChange("paint", oldColor, getColor());
+ firePropertyChange("color", oldColor, getColor());
+ }
+
+ @Override public Paint getPaint() {
+ return getColor();
+ }
+
+
+ @Override public String toString() {
+ if (isAbsolute()) {
+ return Matte.class.getName() + "[r=" + red + ", g=" + green + ", b=" + blue + ", a=" + alpha + "]";
+ } else {
+ return Matte.class.getName() + "[base=" + uiDefaultParentName + ", H+" + hueOffset +
+ ", S+" + saturationOffset + ", B+" + brightnessOffset + ", A+" + alphaOffset + "]";
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Matte matte = (Matte) o;
+ if (alpha != matte.alpha) return false;
+ if (alphaOffset != matte.alphaOffset) return false;
+ if (Float.compare(matte.alpha, alpha) != 0) return false;
+ if (blue != matte.blue) return false;
+ if (Float.compare(matte.brightnessOffset, brightnessOffset) != 0)
+ return false;
+ if (green != matte.green) return false;
+ if (Float.compare(matte.hueOffset, hueOffset) != 0) return false;
+ if (red != matte.red) return false;
+ if (uiResource != matte.uiResource) return false;
+ if (Float.compare(matte.saturationOffset, saturationOffset) != 0)
+ return false;
+ if (componentPropertyName != null ?
+ !componentPropertyName.equals(componentPropertyName) :
+ matte.componentPropertyName != null) return false;
+
+ if (uiDefaultParentName != null ?
+ !uiDefaultParentName.equals(matte.uiDefaultParentName) :
+ matte.uiDefaultParentName != null) return false;
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = red;
+ result = 31 * result + green;
+ result = 31 * result + blue;
+ result = 31 * result + alpha;
+ result = 31 * result + (uiDefaultParentName != null ?
+ uiDefaultParentName.hashCode() : 0);
+ result = 31 * result + (componentPropertyName != null ?
+ componentPropertyName.hashCode() : 0);
+ result = 31 * result + hueOffset != +0.0f ?
+ Float.floatToIntBits(hueOffset) : 0;
+ result = 31 * result + saturationOffset != +0.0f ?
+ Float.floatToIntBits(saturationOffset) : 0;
+ result = 31 * result + brightnessOffset != +0.0f ?
+ Float.floatToIntBits(brightnessOffset) : 0;
+ result = 31 * result + (uiResource ? 1 : 0);
+ return result;
+ }
+
+ @Override public Matte clone() {
+ Matte m = new Matte();
+ m.red = red;
+ m.green = green;
+ m.blue = blue;
+ m.alpha = alpha;
+ m.brightnessOffset = brightnessOffset;
+ m.hueOffset = hueOffset;
+ m.saturationOffset = saturationOffset;
+ m.alphaOffset = alphaOffset;
+ m.uiDefaultParentName = uiDefaultParentName;
+ m.componentPropertyName = componentPropertyName;
+ m.uiResource = uiResource;
+ m.setUiDefaults(uiDefaults);
+ return m;
+ }
+
+ // =================================================================================================================
+ // Private Helper Methods
+
+ private void updateOffsetsFromARGB() {
+ if (!isAbsolute()) {
+ tmpf1 = Color.RGBtoHSB(red, green, blue, tmpf1);
+ Color parentColor = uiDefaults.getColor(uiDefaultParentName);
+ tmpf2 = Color.RGBtoHSB(parentColor.getRed(), parentColor.getGreen(), parentColor.getBlue(), tmpf2);
+ // update offset properties and fire events
+ float oldH = hueOffset, oldS = saturationOffset, oldB = brightnessOffset;
+ int oldA = alphaOffset;
+ hueOffset = tmpf1[0] - tmpf2[0];
+ saturationOffset = tmpf1[1] - tmpf2[1];
+ brightnessOffset = tmpf1[2] - tmpf2[2];
+ alphaOffset = alpha - parentColor.getAlpha();
+ firePropertyChange("hueOffset", oldH, getHueOffset());
+ firePropertyChange("saturationOffset", oldS, getSaturationOffset());
+ firePropertyChange("brightnessOffset", oldB, getBrightnessOffset());
+ firePropertyChange("alphaOffset", oldA, getAlphaOffset());
+ }
+ }
+
+ private void updateARGBFromOffsets() {
+ if (!isAbsolute()) {
+ Color oldColor = getColor();
+ // get parent color HSB
+ Color parentColor = uiDefaults.getColor(uiDefaultParentName);
+ tmpf1 = Color.RGBtoHSB(parentColor.getRed(), parentColor.getGreen(), parentColor.getBlue(), tmpf1);
+ // apply offsets
+ tmpf1[0] = clamp(tmpf1[0] + hueOffset);
+ tmpf1[1] = clamp(tmpf1[1] + saturationOffset);
+ tmpf1[2] = clamp(tmpf1[2] + brightnessOffset);
+ int oldA = getAlpha();
+ alpha = clamp(parentColor.getAlpha() + alphaOffset);
+ updateRGB(tmpf1);
+ // update fire events
+ firePropertyChange("alpha", oldA, getAlpha());
+ firePropertyChange("paint", oldColor, getColor());
+ firePropertyChange("color", oldColor, getColor());
+ }
+ }
+
+ private void updateRGB(float[] hsb) {
+ int oldR = red, oldG = green, oldB = blue;
+ int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
+ red = (rgb >> 16) & 0xFF;
+ green = (rgb >> 8) & 0xFF;
+ blue = rgb & 0xFF;
+ firePropertyChange("red", oldR, getRed());
+ firePropertyChange("green", oldG, getGreen());
+ firePropertyChange("blue", oldB, getBlue());
+ }
+
+ private void fireHSBChange(int oldR, int oldG, int oldB) {
+ tmpf1 = Color.RGBtoHSB(oldR, oldG, oldB, tmpf1);
+ tmpf2 = Color.RGBtoHSB(red, green, blue, tmpf2);
+ firePropertyChange("hue", tmpf1[0], tmpf2[0]);
+ firePropertyChange("saturation", tmpf1[1], tmpf2[1]);
+ firePropertyChange("brightness", tmpf1[2], tmpf2[2]);
+ }
+
+ private float clamp(float value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 1) {
+ value = 1;
+ }
+ return value;
+ }
+
+ private int clamp(int value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 255) {
+ value = 255;
+ }
+ return value;
+ }
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/PaintModel.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/PaintModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..15b67f55a2eefab37c30d6fa87797822c482e859
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/PaintModel.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.paint;
+
+import org.jdesktop.beans.AbstractBean;
+
+import java.awt.Paint;
+
+/**
+ * I'd have just called it Paint, but sadly, that name was already taken, and would have been too confusing.
+ *
+ * Whenever size or position values are required (for example with Texture or Gradient), they are specified in the unit
+ * square: that is, between 0 and 1 inclusive. They can then later be scaled as necessary by any painting code.
+ *
+ * @author rbair
+ */
+public abstract class PaintModel extends AbstractBean implements Cloneable {
+ public static enum PaintControlType {
+ none, control_line, control_rect
+ }
+
+ protected PaintModel() { }
+
+ /**
+ * @return an instance of Paint that is represented by this PaintModel. This is often not a reversable operation,
+ * and hence there is no "setPaint" method. Rather, tweaking the exposed properties of the PaintModel fires,
+ * when necessary, property change events for the "paint" property, and results in different values returned
+ * from this method.
+ */
+ public abstract Paint getPaint();
+
+ /**
+ * Get the type of controls for this paint model
+ *
+ * @return The type of paint controls, one of PaintControlType.none, PaintControlType.control_line or
+ * PaintControlType.control_rect
+ */
+ public abstract PaintControlType getPaintControlType();
+
+
+ public abstract PaintModel clone();
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/RadialGradient.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/RadialGradient.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e66092320b60d7d99af08ca81b96ee88bcebc58
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/RadialGradient.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.paint;
+
+import java.awt.Color;
+import java.awt.MultipleGradientPaint.CycleMethod;
+import java.awt.Paint;
+import java.awt.RadialGradientPaint;
+
+/**
+ * Represents a RadialGradientPaint.
+ *
+ * @author rbair
+ */
+public class RadialGradient extends AbstractGradient {
+ protected Paint createPaint(float[] fractions, Matte[] mattes, CycleMethod method) {
+ Color[] colors = new Color[mattes.length];
+ for (int i = 0; i < colors.length; i++) {
+ colors[i] = mattes[i].getColor();
+ }
+ return new RadialGradientPaint(.5f, .5f, 1, fractions, colors, method);
+ }
+
+ @Override public RadialGradient clone() {
+ RadialGradient gradient = new RadialGradient();
+ copyTo(gradient);
+ return gradient;
+ }
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Texture.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Texture.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fd4b2a7b3935830588923f02e9f7a80700f6a2a
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Texture.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.paint;
+
+import java.awt.Paint;
+import java.awt.TexturePaint;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+
+/**
+ * Represents a TexturePaint.
+ *
+ * @author rbair
+ */
+public class Texture extends PaintModel {
+ private static final Rectangle2D RECT = new Rectangle2D.Double(0, 0, 1, 1);
+ private BufferedImage img;
+
+ public Texture() {
+ }
+
+ public PaintControlType getPaintControlType() {
+ return PaintControlType.control_rect;
+ }
+
+ public void setImage(BufferedImage img) {
+ BufferedImage old = this.img;
+ this.img = img;
+ firePropertyChange("paint", old, this.img);
+ firePropertyChange("image", old, this.img);
+ }
+
+ public final BufferedImage getImage() {
+ return img;
+ }
+
+ public Paint getPaint() {
+ return new TexturePaint(img, RECT);
+ }
+
+
+ public Texture clone() {
+ Texture newTexture = new Texture();
+ newTexture.img = this.img;
+ return newTexture;
+ }
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasPath.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasPath.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5459e1dcdbd7c72edab94f0535ea8817c08c6e7
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasPath.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.utils;
+
+/**
+ * HasPath - interface for model nodes that can provide there path in the tree
+ *
+ * @author Created by Jasper Potts (Jul 2, 2007)
+ */
+public interface HasPath {
+ public String getPath();
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasResources.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasResources.java
new file mode 100644
index 0000000000000000000000000000000000000000..82f9c0dd8a93c0f9e9b645207d37463a8e25175f
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasResources.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.utils;
+
+import java.io.File;
+
+/**
+ * HasResources - interface for model nodes that have resources
+ *
+ * @author Created by Jasper Potts (Jul 2, 2007)
+ */
+public interface HasResources {
+
+ public File getResourcesDir();
+
+ public File getImagesDir();
+
+ public File getTemplatesDir();
+
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasUIDefaults.java b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasUIDefaults.java
new file mode 100644
index 0000000000000000000000000000000000000000..c774d796c1c1008094e457c5866ef43970e00db2
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasUIDefaults.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.swingx.designer.utils;
+
+import javax.swing.UIDefaults;
+
+/**
+ * HasUIDefaults - A tagging interface for any class that has UIDefaults
+ *
+ * @author Created by Jasper Potts (Jun 22, 2007)
+ */
+public interface HasUIDefaults {
+ public UIDefaults getUiDefaults();
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..948686cb0244dd465ebb895a0aaaf617545ac212
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java
@@ -0,0 +1,726 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.synthdesigner.generator;
+
+import org.jdesktop.swingx.designer.Canvas;
+import org.jdesktop.swingx.designer.font.Typeface;
+import org.jdesktop.swingx.designer.paint.Matte;
+import org.jdesktop.swingx.designer.paint.PaintModel;
+import static org.jdesktop.synthdesigner.generator.GeneratorUtils.makePretty;
+import static org.jdesktop.synthdesigner.generator.GeneratorUtils.toConstantName;
+import static org.jdesktop.synthdesigner.generator.ObjectCodeConvertors.convert;
+import static org.jdesktop.synthdesigner.generator.TemplateWriter.read;
+import static org.jdesktop.synthdesigner.generator.TemplateWriter.writeSrcFile;
+import org.jdesktop.synthdesigner.synthmodel.SynthModel;
+import org.jdesktop.synthdesigner.synthmodel.UIComponent;
+import org.jdesktop.synthdesigner.synthmodel.UIFont;
+import org.jdesktop.synthdesigner.synthmodel.UIIconRegion;
+import org.jdesktop.synthdesigner.synthmodel.UIPaint;
+import org.jdesktop.synthdesigner.synthmodel.UIProperty;
+import org.jdesktop.synthdesigner.synthmodel.UIRegion;
+import org.jdesktop.synthdesigner.synthmodel.UIState;
+import org.jdesktop.synthdesigner.synthmodel.UIStateType;
+import org.jdesktop.synthdesigner.synthmodel.UIStyle;
+
+import javax.swing.border.BevelBorder;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.border.MatteBorder;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Insets;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import org.jdesktop.synthdesigner.synthmodel.PainterBorder;
+
+/**
+ * DefaultsGenerator
+ *
+ * There are two main sets of defaults that must be configured. The first is
+ * the actual UI defaults tree. The second is a map of components + regions, which
+ * are used to decide what SynthStyle to use.
+ *
+ * @author Jasper Potts
+ * @author Richard Bair
+ */
+public class DefaultsGenerator {
+ private static String stateTypeImplTemplate;
+
+ private static String getStateTypeTemplate() {
+ if (stateTypeImplTemplate == null) {
+ //load the painter template file into an in-memory string to improve performance
+ //when generating a lot of classes
+ try {
+ stateTypeImplTemplate = read("resources/StateImpl.template");
+ } catch (IOException e) {
+ System.err.println("Failed to read template files.");
+ throw new RuntimeException(e);
+ }
+ }
+ return stateTypeImplTemplate;
+ }
+
+ /**
+ * Generate the defaults file and all painter files for a SynthModel. This method
+ * is the main entry point, called by the Generator class.
+ *
+ * @param uiDefaultInit The buffer to write ui default put methods of the form d.put("activeCaption", new
+ * ColorUIResource(123, 45, 200));
+ * @param styleInit The buffer to write out code to generate Synth Style populating the styles map m
+ * = new HashMap
+ * @param model The Synth Model we are writing out defaults class for
+ * @param variables The variables map pre populated with "PACKAGE" and "LAF_NAME"
+ * @param packageNamePrefix The package name associated with this synth look and feel. For example,
+ * org.mypackage.mylaf
+ * @param painterPackageRoot The directory to write painters out to
+ */
+ public static void generateDefaults(StringBuilder uiDefaultInit, StringBuilder styleInit, SynthModel model,
+ Mapd.put("activeCaption", new
+ * ColorUIResource(123, 45, 200));
+ * @param prefix The prefix for the style property names, for the model path where the style is from, should
+ * end with a "."
+ */
+ private static void writeStyle(UIStyle style, StringBuilder uiDefaultInit, String prefix) {
+ if (!style.isTextForegroundInherited()) writeMatte(prefix + "textForeground", style.getTextForeground(), uiDefaultInit);
+ if (!style.isTextBackgroundInherited()) writeMatte(prefix + "textBackground", style.getTextBackground(), uiDefaultInit);
+ if (!style.isBackgroundInherited()) writeMatte(prefix + "background", style.getBackground(), uiDefaultInit);
+ if (!style.isFontInherited()) writeTypeFace(prefix + "font", style.getFont(), uiDefaultInit);
+ for (UIProperty property : style.getUiProperties()) {
+ switch (property.getType()) {
+ case BOOLEAN:
+ Boolean b = ((Boolean)property.getValue());
+ if (b != null) {
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", ")
+ .append(b ? "Boolean.TRUE" : "Boolean.FALSE")
+ .append(");\n");
+ }
+ break;
+ case STRING:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", \"")
+ .append(property.getValue().toString())
+ .append("\");\n");
+ break;
+ case INT:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new Integer(")
+ .append(((Integer) property.getValue()).intValue())
+ .append("));\n");
+ break;
+ case FLOAT:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new Float(")
+ .append(((Float) property.getValue()).floatValue())
+ .append("f));\n");
+ break;
+ case DOUBLE:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new Double(")
+ .append(((Double) property.getValue()).doubleValue())
+ .append("));\n");
+ break;
+ case COLOR:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", ")
+ .append(convertPaint((Matte)property.getValue()))
+ .append(");\n");
+ break;
+ case FONT:
+ writeTypeFace(prefix.replace("\"", "\\\"") + property.getName(),
+ (Typeface) property.getValue(), uiDefaultInit);
+ break;
+ case INSETS:
+ Insets i = (Insets) property.getValue();
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new InsetsUIResource(")
+ .append(i.top).append(", ").append(i.left).append(", ").append(i.bottom).append(", ")
+ .append(i.right)
+ .append("));\n");
+ break;
+ case DIMENSION:
+ Dimension d = (Dimension) property.getValue();
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new DimensionUIResource(")
+ .append(d.width).append(", ").append(d.height)
+ .append("));\n");
+ break;
+ case BORDER:
+ uiDefaultInit.append(" d.put(\"")
+ .append(prefix)
+ .append(property.getName())
+ .append("\", new BorderUIResource(");
+ uiDefaultInit.append(convertBorder(
+ (Border)property.getValue()));
+ uiDefaultInit.append("));\n");
+ break;
+ }
+ }
+ }
+
+ private static void writeMatte(String propertyName, Matte matte, StringBuilder uiDefaultInit) {
+ if (matte==null) System.err.println("Error matte is NULL for ["+propertyName+"]");
+ uiDefaultInit.append(" d.put(\"")
+ .append(propertyName)
+ .append("\", ")
+ .append(convertPaint(matte))
+ .append(");\n");
+ }
+
+ private static void writeTypeFace(String propertyName, Typeface typeface, StringBuilder uiDefaultInit) {
+ uiDefaultInit.append(" d.put(\"")
+ .append(propertyName)
+ .append("\", new DerivedFont(\"")
+ .append(typeface.getUiDefaultParentName())
+ .append("\", ")
+ .append(typeface.getSizeOffset())
+ .append("f, ");
+ switch (typeface.getBold()) {
+ case Default:
+ uiDefaultInit.append("null,");
+ break;
+ case Off:
+ uiDefaultInit.append("Boolean.FALSE,");
+ break;
+ case On:
+ uiDefaultInit.append("Boolean.TRUE,");
+ break;
+ }
+ switch (typeface.getItalic()) {
+ case Default:
+ uiDefaultInit.append("null");
+ break;
+ case Off:
+ uiDefaultInit.append("Boolean.FALSE");
+ break;
+ case On:
+ uiDefaultInit.append("Boolean.TRUE");
+ break;
+ }
+ uiDefaultInit.append("));\n");
+ }
+
+
+ /**
+ * Write out code for a Component or Region
+ *
+ * @param comp This may be the same as the region reg
or is the parent component
+ * containing the region
+ * @param region The region we are writing out
+ * @param prefix This is dot sperated path of component and sub regions to and including the region
+ * reg
of the form [Comp].[Region]......[Region] path
+ * @param uiDefaultInit This is for inserting into org.mypackage.mylaf.MyDefaults#getDefaults() method
+ * @param styleInit This is for inserting into org.mypackage.mylaf.MyDefaults#initialize() method
+ * @param variables The variables map pre populated with "PACKAGE" and "LAF_NAME"
+ * @param packageNamePrefix The package name associated with this synth look and feel. For example,
+ * org.mypackage.mylaf
+ * @param painterPackageRoot The directory to write painters out to
+ */
+ private static void writeRegion(UIComponent comp, UIRegion region, String prefix, StringBuilder uiDefaultInit,
+ StringBuilder styleInit, Mapregion
or is the parent component
+ * containing the region
+ * @param region The region we are writing out
+ * @param prefix This is [Comp][Region]......[Region] path
+ * @param key The key for this icon.
+ * @param uiDefaultInit This is for inserting into org.mypackage.mylaf.MyDefaults#getDefaults() method
+ * @param variables The variables map pre populated with "PACKAGE" and "LAF_NAME"
+ * @param packageNamePrefix The package name associated with this synth look and feel. For example,
+ * org.mypackage.mylaf
+ * @param painterPackageRoot The directory to write painters out to
+ */
+ private static void writeIconRegion(UIComponent comp, UIIconRegion region, String prefix,
+ StringBuilder uiDefaultInit, Map> implements Cloneable {
+
+ private void updateUIDefaults() {
+ if (getUiDefaults() != null) {
+ for (Typeface t : getFonts()) {
+ if (t.isFontSupported()) {
+ getUiDefaults().put(getName(), t.getFont());
+ return;
+ }
+ }
+ }
+
+ //TODO must not have found any. Default to the Default platform font
+ getUiDefaults().put(getName(), new Font("Arial", Font.PLAIN, 12));
+ }
+
+ public UIFont() {
+ setValue(new ArrayList
c
is the component. You end with a return statement returning boolean true/false for the current
+ * value of this state for this component. This can be null if the key is one of that standard synth states defined
+ * in constants in this class.
+ */
+ private String codeSnippet;
+
+ /** JIBX no-args contructor */
+ private UIStateType() {}
+
+ private UIStateType(String key) {
+ this.key = key;
+ this.codeSnippet = null;
+ }
+
+ public UIStateType(String key, String codeSnippet) {
+ this.key = key;
+ this.codeSnippet = codeSnippet;
+ }
+
+ // =================================================================================================================
+ // Bean Methods
+
+ /**
+ * Get the ui defaults key for this state type. Unique string for the ui key for this state, must be unique within a
+ * components set of UiStateTypes.
+ *
+ * @return Unique ui default key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Get the snippet of java code that defines calculates the value of this state for a particular component. The
+ * varaiable c
is the component. You end with a return statement returning boolean true/false for the
+ * current value of this state for this component. This can be null if the key is one of that standard synth states
+ * defined in constants in this class.
+ *
+ * @return Snippet of java code or null if this is a synth standard state
+ */
+ public String getCodeSnippet() {
+ return codeSnippet;
+ }
+
+ /**
+ * Set the snippet of java code that defines calculates the value of this state for a particular component. The
+ * varaiable c
is the component. You end with a return statement returning boolean true/false for the
+ * current value of this state for this component. This can be null if the key is one of that standard synth states
+ * defined in constants in this class.
+ *
+ * @param codeSnippet Snippet of java code or null if this is a synth standard state
+ */
+ public void setCodeSnippet(String codeSnippet) {
+ this.codeSnippet = codeSnippet;
+ }
+
+ /**
+ * Returns if this state type is a standard synth type and has no code snippet or a custom type that has a code
+ * snippet. It is used by JIBX to determin if the code snippet should be written to XML.
+ *
+ * @return true
if codeSnippet is non null
+ */
+ public boolean hasCodeSnippet() {
+ return codeSnippet != null;
+ }
+
+
+}
diff --git a/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIStyle.java b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIStyle.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e926bf8e4a077101d93952735e55a2384ceafe0
--- /dev/null
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIStyle.java
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package org.jdesktop.synthdesigner.synthmodel;
+
+import org.jdesktop.beans.AbstractBean;
+import org.jdesktop.swingx.designer.font.Typeface;
+import org.jdesktop.swingx.designer.paint.Matte;
+import org.jibx.runtime.IUnmarshallingContext;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * UIStyle
+ *
+ * @author Richard Bair
+ * @author Jasper Potts
+ */
+public class UIStyle extends AbstractBean {
+ public static enum CacheMode {NO_CACHING,FIXED_SIZES,NINE_SQUARE_SCALE}
+ public static enum HintAlphaInterpolation {
+ DEFAULT, QUALITY, SPEED
+ }
+
+ public static enum HintAntialiasing {
+ DEFAULT, ON, OFF
+ }
+
+ public static enum HintColorRendering {
+ DEFAULT, QUALITY, SPEED
+ }
+
+ public static enum HintDithering {
+ DEFAULT, DISABLE, ENABLE
+ }
+
+ public static enum HintFractionalMetrics {
+ DEFAULT, ON, OFF
+ }
+
+ public static enum HintInterpolation {
+ NEAREST_NEIGHBOR, BILINEAR, BICUBIC
+ }
+
+ public static enum HintRendering {
+ DEFAULT, QUALITY, SPEED
+ }
+
+ public static enum HintStrokeControl {
+ DEFAULT, NORMALIZE, PURE
+ }
+
+ public static enum HintTextAntialiasing {
+ DEFAULT, ON, OFF, GASP, LCD_HBGR, LCD_HRGB, LCD_VBGR, LCD_VRGB
+ }
+
+ private Typeface font = null;
+ private boolean fontInherited = true;
+ private Matte textForeground = null;
+ private boolean textForegroundInherited = true;
+ private Matte textBackground = null;
+ private boolean textBackgroundInherited = true;
+ private Matte background = null;
+ private boolean backgroundInherited = true;
+
+ private boolean cacheSettingsInherited = true;
+ private CacheMode cacheMode = CacheMode.FIXED_SIZES;
+ private double maxHozCachedImgScaling = 1;
+ private double maxVertCachedImgScaling = 1;
+
+ private HintAlphaInterpolation hintAlphaInterpolation = null;
+ private HintAntialiasing hintAntialiasing = null;
+ private HintColorRendering hintColorRendering = null;
+ private HintDithering hintDithering = null;
+ private HintFractionalMetrics hintFractionalMetrics = null;
+ private HintInterpolation hintInterpolation = null;
+ private HintRendering hintRendering = null;
+ private HintStrokeControl hintStrokeControl = null;
+ private HintTextAntialiasing hintTextAntialiasing = null;
+ private ListMetaMessage
.
diff --git a/src/share/classes/javax/sound/midi/ShortMessage.java b/src/share/classes/javax/sound/midi/ShortMessage.java
index 716d7b0ef4ff4b750f7ed8088c35612fec853fe7..2dddc3c7a8536672a28247d8a3d7ddcefc9facc7 100644
--- a/src/share/classes/javax/sound/midi/ShortMessage.java
+++ b/src/share/classes/javax/sound/midi/ShortMessage.java
@@ -187,6 +187,83 @@ public class ShortMessage extends MidiMessage {
length = 3;
}
+ /**
+ * Constructs a new {@code ShortMessage} which represents a MIDI
+ * message that takes no data bytes.
+ * The contents of the message can be changed by using one of
+ * the {@code setMessage} methods.
+ *
+ * @param status the MIDI status byte
+ * @throws InvalidMidiDataException if {@code status} does not specify
+ * a valid MIDI status byte for a message that requires no data bytes
+ * @see #setMessage(int)
+ * @see #setMessage(int, int, int)
+ * @see #setMessage(int, int, int, int)
+ * @see #getStatus()
+ * @since 1.7
+ */
+ public ShortMessage(int status) throws InvalidMidiDataException {
+ super(null);
+ setMessage(status); // can throw InvalidMidiDataException
+ }
+
+ /**
+ * Constructs a new {@code ShortMessage} which represents a MIDI message
+ * that takes up to two data bytes. If the message only takes one data byte,
+ * the second data byte is ignored. If the message does not take
+ * any data bytes, both data bytes are ignored.
+ * The contents of the message can be changed by using one of
+ * the {@code setMessage} methods.
+ *
+ * @param status the MIDI status byte
+ * @param data1 the first data byte
+ * @param data2 the second data byte
+ * @throws InvalidMidiDataException if the status byte or all data bytes
+ * belonging to the message do not specify a valid MIDI message
+ * @see #setMessage(int)
+ * @see #setMessage(int, int, int)
+ * @see #setMessage(int, int, int, int)
+ * @see #getStatus()
+ * @see #getData1()
+ * @see #getData2()
+ * @since 1.7
+ */
+ public ShortMessage(int status, int data1, int data2)
+ throws InvalidMidiDataException {
+ super(null);
+ setMessage(status, data1, data2); // can throw InvalidMidiDataException
+ }
+
+ /**
+ * Constructs a new {@code ShortMessage} which represents a channel
+ * MIDI message that takes up to two data bytes. If the message only takes
+ * one data byte, the second data byte is ignored. If the message does not
+ * take any data bytes, both data bytes are ignored.
+ * The contents of the message can be changed by using one of
+ * the {@code setMessage} methods.
+ *
+ * @param command the MIDI command represented by this message
+ * @param channel the channel associated with the message
+ * @param data1 the first data byte
+ * @param data2 the second data byte
+ * @throws InvalidMidiDataException if the command value, channel value
+ * or all data bytes belonging to the message do not specify
+ * a valid MIDI message
+ * @see #setMessage(int)
+ * @see #setMessage(int, int, int)
+ * @see #setMessage(int, int, int, int)
+ * @see #getCommand()
+ * @see #getChannel()
+ * @see #getData1()
+ * @see #getData2()
+ * @since 1.7
+ */
+ public ShortMessage(int command, int channel, int data1, int data2)
+ throws InvalidMidiDataException {
+ super(null);
+ setMessage(command, channel, data1, data2);
+ }
+
/**
* Constructs a new ShortMessage
.
diff --git a/src/share/classes/javax/sound/midi/SysexMessage.java b/src/share/classes/javax/sound/midi/SysexMessage.java
index a3833fffdbe0e5eaaa3c95cbe294ba34936887e2..387d066033952f7e33c678c849ba99c51d0f8aa5 100644
--- a/src/share/classes/javax/sound/midi/SysexMessage.java
+++ b/src/share/classes/javax/sound/midi/SysexMessage.java
@@ -120,6 +120,54 @@ public class SysexMessage extends MidiMessage {
data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
}
+ /**
+ * Constructs a new {@code SysexMessage} and sets the data for
+ * the message. The first byte of the data array must be a valid system
+ * exclusive status byte (0xF0 or 0xF7).
+ * The contents of the message can be changed by using one of
+ * the {@code setMessage} methods.
+ *
+ * @param data the system exclusive message data including the status byte
+ * @param length the length of the valid message data in the array,
+ * including the status byte; it should be non-negative and less than
+ * or equal to {@code data.length}
+ * @throws InvalidMidiDataException if the parameter values
+ * do not specify a valid MIDI meta message.
+ * @see #setMessage(byte[], int)
+ * @see #setMessage(int, byte[], int)
+ * @see #getData()
+ * @since 1.7
+ */
+ public SysexMessage(byte[] data, int length)
+ throws InvalidMidiDataException {
+ super(null);
+ setMessage(data, length);
+ }
+
+ /**
+ * Constructs a new {@code SysexMessage} and sets the data for the message.
+ * The contents of the message can be changed by using one of
+ * the {@code setMessage} methods.
+ *
+ * @param status the status byte for the message; it must be a valid system
+ * exclusive status byte (0xF0 or 0xF7)
+ * @param data the system exclusive message data (without the status byte)
+ * @param length the length of the valid message data in the array;
+ * it should be non-negative and less than or equal to
+ * {@code data.length}
+ * @throws InvalidMidiDataException if the parameter values
+ * do not specify a valid MIDI meta message.
+ * @see #setMessage(byte[], int)
+ * @see #setMessage(int, byte[], int)
+ * @see #getData()
+ * @since 1.7
+ */
+ public SysexMessage(int status, byte[] data, int length)
+ throws InvalidMidiDataException {
+ super(null);
+ setMessage(status, data, length);
+ }
+
/**
* Constructs a new SysexMessage
.
diff --git a/src/share/classes/javax/sound/sampled/FloatControl.java b/src/share/classes/javax/sound/sampled/FloatControl.java
index 650ec4901c3dab584ca8f5782eb55bb9454cb6c7..12a31402bc28507a046ed1827d0a794311a7bfe8 100644
--- a/src/share/classes/javax/sound/sampled/FloatControl.java
+++ b/src/share/classes/javax/sound/sampled/FloatControl.java
@@ -131,13 +131,31 @@ public abstract class FloatControl extends Control {
* @param minLabel the label for the minimum value, such as "Left" or "Off"
* @param midLabel the label for the midpoint value, such as "Center" or "Default"
* @param maxLabel the label for the maximum value, such as "Right" or "Full"
+ *
+ * @throws IllegalArgumentException if {@code minimum} is greater
+ * than {@code maximum} or {@code initialValue} does not fall
+ * within the allowable range
*/
protected FloatControl(Type type, float minimum, float maximum,
- float precision, int updatePeriod, float initialValue,
- String units, String minLabel, String midLabel, String maxLabel) {
+ float precision, int updatePeriod, float initialValue,
+ String units, String minLabel, String midLabel, String maxLabel) {
super(type);
+ if (minimum > maximum) {
+ throw new IllegalArgumentException("Minimum value " + minimum
+ + " exceeds maximum value " + maximum + ".");
+ }
+ if (initialValue < minimum) {
+ throw new IllegalArgumentException("Initial value " + initialValue
+ + " smaller than allowable minimum value " + minimum + ".");
+ }
+ if (initialValue > maximum) {
+ throw new IllegalArgumentException("Initial value " + initialValue
+ + " exceeds allowable maximum value " + maximum + ".");
+ }
+
+
this.minimum = minimum;
this.maximum = maximum;
@@ -167,10 +185,15 @@ public abstract class FloatControl extends Control {
* @param initialValue the value that the control starts with when constructed
* @param units the label for the units in which the control's values are expressed,
* such as "dB" or "frames per second"
+ *
+ * @throws IllegalArgumentException if {@code minimum} is greater
+ * than {@code maximum} or {@code initialValue} does not fall
+ * within the allowable range
*/
protected FloatControl(Type type, float minimum, float maximum,
- float precision, int updatePeriod, float initialValue, String units) {
- this(type, minimum, maximum, precision, updatePeriod, initialValue, units, "", "", "");
+ float precision, int updatePeriod, float initialValue, String units) {
+ this(type, minimum, maximum, precision, updatePeriod,
+ initialValue, units, "", "", "");
}
@@ -306,9 +329,21 @@ public abstract class FloatControl extends Control {
* @param to final value after the shift
* @param microseconds maximum duration of the shift in microseconds
*
+ * @throws IllegalArgumentException if either {@code from} or {@code to}
+ * value does not fall within the allowable range
+ *
* @see #getUpdatePeriod
*/
public void shift(float from, float to, int microseconds) {
+ // test "from" value, "to" value will be tested by setValue()
+ if (from < minimum) {
+ throw new IllegalArgumentException("Requested value " + from
+ + " smaller than allowable minimum value " + minimum + ".");
+ }
+ if (from > maximum) {
+ throw new IllegalArgumentException("Requested value " + from
+ + " exceeds allowable maximum value " + maximum + ".");
+ }
setValue(to);
}
diff --git a/src/share/classes/javax/sound/sampled/spi/MixerProvider.java b/src/share/classes/javax/sound/sampled/spi/MixerProvider.java
index d5c161ea34d6c362656d667163b660991a9268aa..c79bb1114a6b87fe6f1ab65eb89d73a3a0b5c2fa 100644
--- a/src/share/classes/javax/sound/sampled/spi/MixerProvider.java
+++ b/src/share/classes/javax/sound/sampled/spi/MixerProvider.java
@@ -42,9 +42,15 @@ public abstract class MixerProvider {
/**
* Indicates whether the mixer provider supports the mixer represented by
* the specified mixer info object.
+ * true
if the specified mixer is supported,
- * otherwise false
+ * @return {@code true} if the specified mixer is supported,
+ * otherwise {@code false}
+ * @see #getMixerInfo()
*/
public boolean isMixerSupported(Mixer.Info info) {
@@ -62,17 +68,34 @@ public abstract class MixerProvider {
/**
* Obtains the set of info objects representing the mixer
* or mixers provided by this MixerProvider.
- * @return set of mixer info objects
+ * getListCellRendererComponent
method and set the border
* of the returned component directly.
*/
- protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
+ private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
+ protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
/**
* Constructs a default renderer object for an item
@@ -90,14 +92,21 @@ public class DefaultListCellRenderer extends JLabel
super();
setOpaque(true);
setBorder(getNoFocusBorder());
+ setName("List.cellRenderer");
}
-
- private static Border getNoFocusBorder() {
+ private Border getNoFocusBorder() {
+ Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder");
if (System.getSecurityManager() != null) {
+ if (border != null) return border;
return SAFE_NO_FOCUS_BORDER;
} else {
- return UIManager.getBorder("List.noFocusBorder");
+ if (border != null &&
+ (noFocusBorder == null ||
+ noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) {
+ return border;
+ }
+ return noFocusBorder;
}
}
@@ -118,8 +127,8 @@ public class DefaultListCellRenderer extends JLabel
&& !dropLocation.isInsert()
&& dropLocation.getIndex() == index) {
- bg = UIManager.getColor("List.dropCellBackground");
- fg = UIManager.getColor("List.dropCellForeground");
+ bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground");
+ fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground");
isSelected = true;
}
@@ -148,10 +157,10 @@ public class DefaultListCellRenderer extends JLabel
Border border = null;
if (cellHasFocus) {
if (isSelected) {
- border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
+ border = DefaultLookup.getBorder(this, ui, "List.focusSelectedCellHighlightBorder");
}
if (border == null) {
- border = UIManager.getBorder("List.focusCellHighlightBorder");
+ border = DefaultLookup.getBorder(this, ui, "List.focusCellHighlightBorder");
}
} else {
border = getNoFocusBorder();
@@ -161,7 +170,6 @@ public class DefaultListCellRenderer extends JLabel
return this;
}
-
/**
* Overridden for performance reasons.
* See the Implementation Note
@@ -172,6 +180,7 @@ public class DefaultListCellRenderer extends JLabel
* and differs from the JList's background;
* false
otherwise
*/
+ @Override
public boolean isOpaque() {
Color back = getBackground();
Component p = getParent();
@@ -190,6 +199,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void validate() {}
/**
@@ -199,6 +209,7 @@ public class DefaultListCellRenderer extends JLabel
*
* @since 1.5
*/
+ @Override
public void invalidate() {}
/**
@@ -208,6 +219,7 @@ public class DefaultListCellRenderer extends JLabel
*
* @since 1.5
*/
+ @Override
public void repaint() {}
/**
@@ -215,12 +227,14 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void revalidate() {}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
+ @Override
public void repaint(long tm, int x, int y, int width, int height) {}
/**
@@ -228,6 +242,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void repaint(Rectangle r) {}
/**
@@ -235,6 +250,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned...
if (propertyName == "text"
@@ -251,6 +267,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}
/**
@@ -258,6 +275,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, char oldValue, char newValue) {}
/**
@@ -265,6 +283,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, short oldValue, short newValue) {}
/**
@@ -272,6 +291,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, int oldValue, int newValue) {}
/**
@@ -279,6 +299,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, long oldValue, long newValue) {}
/**
@@ -286,6 +307,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, float oldValue, float newValue) {}
/**
@@ -293,6 +315,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, double oldValue, double newValue) {}
/**
@@ -300,6 +323,7 @@ public class DefaultListCellRenderer extends JLabel
* See the Implementation Note
* for more information.
*/
+ @Override
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
/**
@@ -321,5 +345,4 @@ public class DefaultListCellRenderer extends JLabel
implements javax.swing.plaf.UIResource
{
}
-
}
diff --git a/src/share/classes/javax/swing/JComboBox.java b/src/share/classes/javax/swing/JComboBox.java
index 42ef6466979461e08bb6e5fdd26bfee63f8fcf1c..838ce5d7d295ba747d78cb45d786e6ab488bc364 100644
--- a/src/share/classes/javax/swing/JComboBox.java
+++ b/src/share/classes/javax/swing/JComboBox.java
@@ -34,12 +34,10 @@ import java.awt.event.*;
import java.io.Serializable;
import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.IOException;
import javax.swing.event.*;
import javax.swing.plaf.*;
-import javax.swing.border.*;
import javax.accessibility.*;
@@ -227,7 +225,7 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
private void init() {
installAncestorListener();
- setOpaque(true);
+ setUIProperty("opaque",true);
updateUI();
}
diff --git a/src/share/classes/javax/swing/JScrollPane.java b/src/share/classes/javax/swing/JScrollPane.java
index 13c1365c025e7f485823adbe943f4dc4f84f4d39..b2be43cd15fc8fed68cff816399266e945f28828 100644
--- a/src/share/classes/javax/swing/JScrollPane.java
+++ b/src/share/classes/javax/swing/JScrollPane.java
@@ -32,15 +32,12 @@ import javax.accessibility.*;
import java.awt.Component;
import java.awt.ComponentOrientation;
-import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Insets;
-import java.awt.Color;
import java.awt.LayoutManager;
import java.awt.Point;
import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.IOException;
import java.beans.PropertyChangeEvent;
@@ -304,7 +301,7 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce
if (view != null) {
setViewportView(view);
}
- setOpaque(true);
+ setUIProperty("opaque",true);
updateUI();
if (!this.getComponentOrientation().isLeftToRight()) {
diff --git a/src/share/classes/javax/swing/JSpinner.java b/src/share/classes/javax/swing/JSpinner.java
index ddd92b9b4e48f1da85cf1f3acabbad48dcabefe3..ed7bfc80ceda7a77caed229460f5ed2396169cff 100644
--- a/src/share/classes/javax/swing/JSpinner.java
+++ b/src/share/classes/javax/swing/JSpinner.java
@@ -28,7 +28,6 @@ package javax.swing;
import java.awt.*;
import java.awt.event.*;
-import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.plaf.SpinnerUI;
@@ -154,7 +153,7 @@ public class JSpinner extends JComponent implements Accessible
}
this.model = model;
this.editor = createEditor(model);
- setOpaque(true);
+ setUIProperty("opaque",true);
updateUI();
}
diff --git a/src/share/classes/javax/swing/JSplitPane.java b/src/share/classes/javax/swing/JSplitPane.java
index 1e38b9f8b63bd8c000c753b2c0e2a424718199b1..b5d8ec7d2b513997df020fb823acf83e2c2c85f4 100644
--- a/src/share/classes/javax/swing/JSplitPane.java
+++ b/src/share/classes/javax/swing/JSplitPane.java
@@ -246,7 +246,8 @@ public class JSplitPane extends JComponent implements Accessible
* layout, using two buttons for the components.
*/
public JSplitPane() {
- this(JSplitPane.HORIZONTAL_SPLIT, false,
+ this(JSplitPane.HORIZONTAL_SPLIT,
+ UIManager.getBoolean("SplitPane.continuousLayout"),
new JButton(UIManager.getString("SplitPane.leftButtonText")),
new JButton(UIManager.getString("SplitPane.rightButtonText")));
}
@@ -263,7 +264,8 @@ public class JSplitPane extends JComponent implements Accessible
*/
@ConstructorProperties({"orientation"})
public JSplitPane(int newOrientation) {
- this(newOrientation, false);
+ this(newOrientation,
+ UIManager.getBoolean("SplitPane.continuousLayout"));
}
@@ -307,7 +309,9 @@ public class JSplitPane extends JComponent implements Accessible
public JSplitPane(int newOrientation,
Component newLeftComponent,
Component newRightComponent){
- this(newOrientation, false, newLeftComponent, newRightComponent);
+ this(newOrientation,
+ UIManager.getBoolean("SplitPane.continuousLayout"),
+ newLeftComponent, newRightComponent);
}
diff --git a/src/share/classes/javax/swing/JTable.java b/src/share/classes/javax/swing/JTable.java
index 1b770d89153affe5ed6ca4b75cef929b0596bbbc..dc9adebc4d47947eb2e445552d2176f8370df7cb 100644
--- a/src/share/classes/javax/swing/JTable.java
+++ b/src/share/classes/javax/swing/JTable.java
@@ -731,6 +731,37 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
return;
}
scrollPane.setColumnHeaderView(getTableHeader());
+ // configure the scrollpane for any LAF dependent settings
+ configureEnclosingScrollPaneUI();
+ }
+ }
+ }
+
+ /**
+ * This is a sub-part of configureEnclosingScrollPane() that configures
+ * anything on the scrollpane that may change when the look and feel
+ * changes. It needed to be split out from configureEnclosingScrollPane() so
+ * that it can be called from updateUI() when the LAF changes without
+ * causing the regression found in bug 6687962. This was because updateUI()
+ * is called from the constructor which then caused
+ * configureEnclosingScrollPane() to be called by the constructor which
+ * changes its contract for any subclass that overrides it. So by splitting
+ * it out in this way configureEnclosingScrollPaneUI() can be called both
+ * from configureEnclosingScrollPane() and updateUI() in a safe manor.
+ */
+ private void configureEnclosingScrollPaneUI() {
+ Container p = getParent();
+ if (p instanceof JViewport) {
+ Container gp = p.getParent();
+ if (gp instanceof JScrollPane) {
+ JScrollPane scrollPane = (JScrollPane)gp;
+ // Make certain we are the viewPort's view and not, for
+ // example, the rowHeaderView of the scrollPane -
+ // an implementor of fixed columns might do this.
+ JViewport viewport = scrollPane.getViewport();
+ if (viewport == null || viewport.getView() != this) {
+ return;
+ }
// scrollPane.getViewport().setBackingStoreEnabled(true);
Border border = scrollPane.getBorder();
if (border == null || border instanceof UIResource) {
@@ -740,6 +771,24 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
scrollPane.setBorder(scrollPaneBorder);
}
}
+ // add JScrollBar corner component if available from LAF and not already set by the user
+ Component corner =
+ scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
+ if (corner == null || corner instanceof UIResource){
+ corner = null;
+ Object componentClass = UIManager.get(
+ "Table.scrollPaneCornerComponent");
+ if (componentClass instanceof Class){
+ try {
+ corner = (Component)
+ ((Class)componentClass).newInstance();
+ } catch (Exception e) {
+ // just ignore and don't set corner
+ }
+ }
+ scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
+ corner);
+ }
}
}
}
@@ -783,6 +832,13 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
return;
}
scrollPane.setColumnHeaderView(null);
+ // remove ScrollPane corner if one was added by the LAF
+ Component corner =
+ scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
+ if (corner instanceof UIResource){
+ scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
+ null);
+ }
}
}
}
@@ -3592,6 +3648,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
tableHeader.updateUI();
}
+ // Update UI applied to parent ScrollPane
+ configureEnclosingScrollPaneUI();
+
setUI((TableUI)UIManager.getUI(this));
}
diff --git a/src/share/classes/javax/swing/MultiUIDefaults.java b/src/share/classes/javax/swing/MultiUIDefaults.java
index d5904d05ca2da401d1eda4175498f93a349c842c..20eeeafa24a4513ff7953d88138dc71e2e608449 100644
--- a/src/share/classes/javax/swing/MultiUIDefaults.java
+++ b/src/share/classes/javax/swing/MultiUIDefaults.java
@@ -26,7 +26,10 @@
package javax.swing;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Map.Entry;
+import java.util.Set;
@@ -48,7 +51,7 @@ class MultiUIDefaults extends UIDefaults
tables = new UIDefaults[0];
}
-
+ @Override
public Object get(Object key)
{
Object value = super.get(key);
@@ -66,7 +69,7 @@ class MultiUIDefaults extends UIDefaults
return null;
}
-
+ @Override
public Object get(Object key, Locale l)
{
Object value = super.get(key,l);
@@ -84,7 +87,7 @@ class MultiUIDefaults extends UIDefaults
return null;
}
-
+ @Override
public int size() {
int n = super.size();
for (UIDefaults table : tables) {
@@ -93,12 +96,12 @@ class MultiUIDefaults extends UIDefaults
return n;
}
-
+ @Override
public boolean isEmpty() {
return size() == 0;
}
-
+ @Override
public EnumerationGraphics2D
, and are not
+ * required to restore that state upon completion. In most cases, it is recommended
+ * that the caller pass in a scratch graphics object. The Graphics2D
+ * must never be null.paint
method,
+ * but may not be. For instance, setting the antialiasing rendering hint on the
+ * graphics may or may not be respected by the Painter
implementation.Component
. A Painter
+ * that expected it could then read state from that Component
and
+ * use the state for painting. For example, an implementation may read the
+ * backgroundColor and use that.Painter
s ignore
+ * this parameter. They can thus be reused in any context. The object
+ * may be null. Implementations must not throw a NullPointerException if the object
+ * parameter is null.width
and height
arguments specify the
+ * width and height that the Painter
should paint into. More
+ * specifically, the specified width and height instruct the painter that it should
+ * paint fully within this width and height. Any specified clip on the
+ * g
param will further constrain the region.Painter
implementation that draws
+ * a gradient. The gradient goes from white to black. It "stretches" to fill the
+ * painted region. Thus, if I use this Painter
to paint a 500 x 500
+ * region, the far left would be black, the far right would be white, and a smooth
+ * gradient would be painted between. I could then, without modification, reuse the
+ * Painter
to paint a region that is 20x20 in size. This region would
+ * also be black on the left, white on the right, and a smooth gradient painted
+ * between.BasicComboBoxUI
.
*/
public class KeyHandler extends KeyAdapter {
+ @Override
public void keyPressed( KeyEvent e ) {
getHandler().keyPressed(e);
}
@@ -761,6 +786,8 @@ public class BasicComboBoxUI extends ComboBoxUI {
}
comboBox.configureEditor(comboBox.getEditor(),comboBox.getSelectedItem());
+
+ editor.addPropertyChangeListener(propertyChangeListener);
}
/**
@@ -774,6 +801,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
editor.removeFocusListener(focusListener);
}
+ editor.removePropertyChangeListener(propertyChangeListener);
editor.removeFocusListener(getHandler());
comboBox.getEditor().removeActionListener(getHandler());
}
@@ -868,7 +896,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
//=================================
// begin ComponentUI Implementation
-
+ @Override
public void paint( Graphics g, JComponent c ) {
hasFocus = comboBox.hasFocus();
if ( !comboBox.isEditable() ) {
@@ -878,6 +906,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
}
}
+ @Override
public Dimension getPreferredSize( JComponent c ) {
return getMinimumSize(c);
}
@@ -885,15 +914,19 @@ public class BasicComboBoxUI extends ComboBoxUI {
/**
* The minumum size is the size of the display area plus insets plus the button.
*/
+ @Override
public Dimension getMinimumSize( JComponent c ) {
if ( !isMinimumSizeDirty ) {
return new Dimension(cachedMinimumSize);
}
Dimension size = getDisplaySize();
Insets insets = getInsets();
+ //calculate the width and height of the button
+ int buttonHeight = size.height;
+ int buttonWidth = squareButton ? buttonHeight : arrowButton.getPreferredSize().width;
+ //adjust the size based on the button width
size.height += insets.top + insets.bottom;
- int buttonSize = size.height - (insets.top + insets.bottom);
- size.width += insets.left + insets.right + buttonSize;
+ size.width += insets.left + insets.right + buttonWidth;
cachedMinimumSize.setSize( size.width, size.height );
isMinimumSizeDirty = false;
@@ -901,6 +934,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
return new Dimension(size);
}
+ @Override
public Dimension getMaximumSize( JComponent c ) {
return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}
@@ -913,6 +947,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
+ @Override
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
int baseline = -1;
@@ -967,6 +1002,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
+ @Override
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
@@ -1001,6 +1037,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
}
// This is currently hacky...
+ @Override
public int getAccessibleChildrenCount(JComponent c) {
if ( comboBox.isEditable() ) {
return 2;
@@ -1011,6 +1048,7 @@ public class BasicComboBoxUI extends ComboBoxUI {
}
// This is currently hacky...
+ @Override
public Accessible getAccessibleChild(JComponent c, int i) {
// 0 = the popup
// 1 = the editor
@@ -1204,8 +1242,15 @@ public class BasicComboBoxUI extends ComboBoxUI {
shouldValidate = true;
}
- currentValuePane.paintComponent(g,c,comboBox,bounds.x,bounds.y,
- bounds.width,bounds.height, shouldValidate);
+ int x = bounds.x, y = bounds.y, w = bounds.width, h = bounds.height;
+ if (padding != null) {
+ x = bounds.x + padding.left;
+ y = bounds.y + padding.top;
+ w = bounds.width - (padding.left + padding.right);
+ h = bounds.height - (padding.top + padding.bottom);
+ }
+
+ currentValuePane.paintComponent(g,c,comboBox,x,y,w,h,shouldValidate);
}
/**
@@ -1333,6 +1378,12 @@ public class BasicComboBoxUI extends ComboBoxUI {
result.height = Math.max(result.height,d.height);
}
+ // calculate in the padding
+ if (padding != null) {
+ result.width += padding.left + padding.right;
+ result.height += padding.top + padding.bottom;
+ }
+
// Set the cached value
cachedDisplaySize.setSize(result.width, result.height);
isDisplaySizeDirty = false;
@@ -1591,91 +1642,99 @@ public class BasicComboBoxUI extends ComboBoxUI {
//
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
- JComboBox comboBox = (JComboBox)e.getSource();
-
- if ( propertyName == "model" ) {
- ComboBoxModel newModel = (ComboBoxModel)e.getNewValue();
- ComboBoxModel oldModel = (ComboBoxModel)e.getOldValue();
-
- if ( oldModel != null && listDataListener != null ) {
- oldModel.removeListDataListener( listDataListener );
+ if (e.getSource() == editor){
+ // If the border of the editor changes then this can effect
+ // the size of the editor which can cause the combo's size to
+ // become invalid so we need to clear size caches
+ if ("border".equals(propertyName)){
+ isMinimumSizeDirty = true;
+ isDisplaySizeDirty = true;
+ comboBox.revalidate();
}
+ } else {
+ JComboBox comboBox = (JComboBox)e.getSource();
+ if ( propertyName == "model" ) {
+ ComboBoxModel newModel = (ComboBoxModel)e.getNewValue();
+ ComboBoxModel oldModel = (ComboBoxModel)e.getOldValue();
- if ( newModel != null && listDataListener != null ) {
- newModel.addListDataListener( listDataListener );
- }
+ if ( oldModel != null && listDataListener != null ) {
+ oldModel.removeListDataListener( listDataListener );
+ }
- if ( editor != null ) {
- comboBox.configureEditor( comboBox.getEditor(), comboBox.getSelectedItem() );
+ if ( newModel != null && listDataListener != null ) {
+ newModel.addListDataListener( listDataListener );
+ }
+
+ if ( editor != null ) {
+ comboBox.configureEditor( comboBox.getEditor(), comboBox.getSelectedItem() );
+ }
+ isMinimumSizeDirty = true;
+ isDisplaySizeDirty = true;
+ comboBox.revalidate();
+ comboBox.repaint();
}
- isMinimumSizeDirty = true;
- isDisplaySizeDirty = true;
- comboBox.revalidate();
- comboBox.repaint();
- }
- else if ( propertyName == "editor" && comboBox.isEditable() ) {
- addEditor();
- comboBox.revalidate();
- }
- else if ( propertyName == "editable" ) {
- if ( comboBox.isEditable() ) {
- comboBox.setRequestFocusEnabled( false );
+ else if ( propertyName == "editor" && comboBox.isEditable() ) {
addEditor();
- } else {
- comboBox.setRequestFocusEnabled( true );
- removeEditor();
+ comboBox.revalidate();
}
-
- updateToolTipTextForChildren();
-
- comboBox.revalidate();
- }
- else if ( propertyName == "enabled" ) {
- boolean enabled = comboBox.isEnabled();
- if ( editor != null )
- editor.setEnabled(enabled);
- if ( arrowButton != null )
- arrowButton.setEnabled(enabled);
- comboBox.repaint();
- }
- else if ( propertyName == "focusable" ) {
- boolean focusable = comboBox.isFocusable();
- if ( editor != null )
- editor.setFocusable(focusable);
- if ( arrowButton != null )
- arrowButton.setFocusable(focusable);
- comboBox.repaint();
- }
- else if ( propertyName == "maximumRowCount" ) {
- if ( isPopupVisible( comboBox ) ) {
- setPopupVisible(comboBox, false);
- setPopupVisible(comboBox, true);
+ else if ( propertyName == "editable" ) {
+ if ( comboBox.isEditable() ) {
+ comboBox.setRequestFocusEnabled( false );
+ addEditor();
+ } else {
+ comboBox.setRequestFocusEnabled( true );
+ removeEditor();
+ }
+ updateToolTipTextForChildren();
+ comboBox.revalidate();
}
- }
- else if ( propertyName == "font" ) {
- listBox.setFont( comboBox.getFont() );
- if ( editor != null ) {
- editor.setFont( comboBox.getFont() );
+ else if ( propertyName == "enabled" ) {
+ boolean enabled = comboBox.isEnabled();
+ if ( editor != null )
+ editor.setEnabled(enabled);
+ if ( arrowButton != null )
+ arrowButton.setEnabled(enabled);
+ comboBox.repaint();
+ }
+ else if ( propertyName == "focusable" ) {
+ boolean focusable = comboBox.isFocusable();
+ if ( editor != null )
+ editor.setFocusable(focusable);
+ if ( arrowButton != null )
+ arrowButton.setFocusable(focusable);
+ comboBox.repaint();
+ }
+ else if ( propertyName == "maximumRowCount" ) {
+ if ( isPopupVisible( comboBox ) ) {
+ setPopupVisible(comboBox, false);
+ setPopupVisible(comboBox, true);
+ }
+ }
+ else if ( propertyName == "font" ) {
+ listBox.setFont( comboBox.getFont() );
+ if ( editor != null ) {
+ editor.setFont( comboBox.getFont() );
+ }
+ isMinimumSizeDirty = true;
+ comboBox.validate();
+ }
+ else if ( propertyName == JComponent.TOOL_TIP_TEXT_KEY ) {
+ updateToolTipTextForChildren();
+ }
+ else if ( propertyName == BasicComboBoxUI.IS_TABLE_CELL_EDITOR ) {
+ Boolean inTable = (Boolean)e.getNewValue();
+ isTableCellEditor = inTable.equals(Boolean.TRUE) ? true : false;
+ }
+ else if (propertyName == "prototypeDisplayValue") {
+ isMinimumSizeDirty = true;
+ isDisplaySizeDirty = true;
+ comboBox.revalidate();
+ }
+ else if (propertyName == "renderer") {
+ isMinimumSizeDirty = true;
+ isDisplaySizeDirty = true;
+ comboBox.revalidate();
}
- isMinimumSizeDirty = true;
- comboBox.validate();
- }
- else if ( propertyName == JComponent.TOOL_TIP_TEXT_KEY ) {
- updateToolTipTextForChildren();
- }
- else if ( propertyName == BasicComboBoxUI.IS_TABLE_CELL_EDITOR ) {
- Boolean inTable = (Boolean)e.getNewValue();
- isTableCellEditor = inTable.equals(Boolean.TRUE) ? true : false;
- }
- else if (propertyName == "prototypeDisplayValue") {
- isMinimumSizeDirty = true;
- isDisplaySizeDirty = true;
- comboBox.revalidate();
- }
- else if (propertyName == "renderer") {
- isMinimumSizeDirty = true;
- isDisplaySizeDirty = true;
- comboBox.revalidate();
}
}
@@ -1809,18 +1868,23 @@ public class BasicComboBoxUI extends ComboBoxUI {
int height = cb.getHeight();
Insets insets = getInsets();
- int buttonSize = height - (insets.top + insets.bottom);
+ int buttonHeight = height - (insets.top + insets.bottom);
+ int buttonWidth = buttonHeight;
+ if (arrowButton != null) {
+ Insets arrowInsets = arrowButton.getInsets();
+ buttonWidth = squareButton ?
+ buttonHeight :
+ arrowButton.getPreferredSize().width + arrowInsets.left + arrowInsets.right;
+ }
Rectangle cvb;
- if ( arrowButton != null ) {
- if(BasicGraphicsUtils.isLeftToRight(cb)) {
- arrowButton.setBounds( width - (insets.right + buttonSize),
- insets.top,
- buttonSize, buttonSize);
- }
- else {
- arrowButton.setBounds( insets.left, insets.top,
- buttonSize, buttonSize);
+ if (arrowButton != null) {
+ if (BasicGraphicsUtils.isLeftToRight(cb)) {
+ arrowButton.setBounds(width - (insets.right + buttonWidth),
+ insets.top, buttonWidth, buttonHeight);
+ } else {
+ arrowButton.setBounds(insets.left, insets.top,
+ buttonWidth, buttonHeight);
}
}
if ( editor != null ) {
@@ -1829,7 +1893,6 @@ public class BasicComboBoxUI extends ComboBoxUI {
}
}
-
//
// ActionListener
//
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicListUI.java b/src/share/classes/javax/swing/plaf/basic/BasicListUI.java
index a7ec88835b84b09dac0f07529ef1a5ed21224860..7704d10e102fce2072279c044842b7f3e48d6031 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicListUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicListUI.java
@@ -480,6 +480,12 @@ public class BasicListUI extends ListUI
if (renderer == null) {
ListCellRenderer lcr = (ListCellRenderer)UIManager.get(
"List.cellRenderer");
+
+ // fix for 6711072 some LAFs like Nimbus do not provide this
+ // UIManager key and we should not through a NPE here because of it
+ if (lcr == null) {
+ lcr = new DefaultListCellRenderer();
+ }
renderer = lcr.getListCellRendererComponent(
list, "a", -1, false, false);
lafDefaults.put(BASELINE_COMPONENT_KEY, renderer);
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java
index a58cc467c5f58601e6776532ce6ed3c1e09e02ad..61c70c9bb0b9ed5edcbdd944bc09ea2db0a60ab5 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -111,6 +111,11 @@ public class BasicMenuItemUI extends MenuItemUI
String prefix = getPropertyPrefix();
acceleratorFont = UIManager.getFont("MenuItem.acceleratorFont");
+ // use default if missing so that BasicMenuItemUI can be used in other
+ // LAFs like Nimbus
+ if (acceleratorFont == null) {
+ acceleratorFont = UIManager.getFont("MenuItem.font");
+ }
Object opaque = UIManager.get(getPropertyPrefix() + ".opaque");
if (opaque != null) {
@@ -130,7 +135,7 @@ public class BasicMenuItemUI extends MenuItemUI
LookAndFeel.installBorder(menuItem, prefix + ".border");
oldBorderPainted = menuItem.isBorderPainted();
LookAndFeel.installProperty(menuItem, "borderPainted",
- UIManager.get(prefix + ".borderPainted"));
+ UIManager.getBoolean(prefix + ".borderPainted"));
LookAndFeel.installColorsAndFont(menuItem,
prefix + ".background",
prefix + ".foreground",
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicProgressBarUI.java b/src/share/classes/javax/swing/plaf/basic/BasicProgressBarUI.java
index e743602c73d0df6c5a426a471e762f4ab28f7ebf..0d31dc30cf55b55f18a5d407dfb128672cfc7953 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicProgressBarUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicProgressBarUI.java
@@ -158,6 +158,7 @@ public class BasicProgressBarUI extends ProgressBarUI {
"ProgressBar.foreground",
"ProgressBar.font");
cellLength = UIManager.getInt("ProgressBar.cellLength");
+ if (cellLength == 0) cellLength = 1;
cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
index 7db1e11e62ec3ce6f4da5a0a5c581546a2ad51d5..b22a58795e673a5268fef91d6c627fec91588e0b 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -112,6 +112,24 @@ public class BasicScrollBarUI
*/
private int scrollBarValue;
+ /**
+ * Distance between the increment button and the track. This may be a negative
+ * number. If negative, then an overlap between the button and track will occur,
+ * which is useful for shaped buttons.
+ *
+ * TODO This should be made protected in a feature release
+ */
+ private int incrGap;
+
+ /**
+ * Distance between the decrement button and the track. This may be a negative
+ * number. If negative, then an overlap between the button and track will occur,
+ * which is useful for shaped buttons.
+ *
+ * TODO This should be made protected in a feature release
+ */
+ private int decrGap;
+
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));
map.put(new Actions(Actions.POSITIVE_BLOCK_INCREMENT));
@@ -186,6 +204,31 @@ public class BasicScrollBarUI
LookAndFeel.installProperty(scrollbar, "opaque", Boolean.TRUE);
scrollBarValue = scrollbar.getValue();
+
+ incrGap = UIManager.getInt("ScrollBar.incrementButtonGap");
+ decrGap = UIManager.getInt("ScrollBar.decrementButtonGap");
+
+ // TODO this can be removed when incrGap/decrGap become protected
+ // handle scaling for sizeVarients for special case components. The
+ // key "JComponent.sizeVariant" scales for large/small/mini
+ // components are based on Apples LAF
+ String scaleKey = (String)scrollbar.getClientProperty(
+ "JComponent.sizeVariant");
+ if (scaleKey != null){
+ if ("large".equals(scaleKey)){
+ scrollBarWidth *= 1.15;
+ incrGap *= 1.15;
+ decrGap *= 1.15;
+ } else if ("small".equals(scaleKey)){
+ scrollBarWidth *= 0.857;
+ incrGap *= 0.857;
+ decrGap *= 0.714;
+ } else if ("mini".equals(scaleKey)){
+ scrollBarWidth *= 0.714;
+ incrGap *= 0.714;
+ decrGap *= 0.714;
+ }
+ }
}
@@ -442,20 +485,23 @@ public class BasicScrollBarUI
g.setColor(trackHighlightColor);
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
+ //paint the distance between the start of the track and top of the thumb
int x = insets.left;
- int y = decrButton.getY() + decrButton.getHeight();
+ int y = trackRect.y;
int w = scrollbar.getWidth() - (insets.left + insets.right);
int h = thumbR.y - y;
g.fillRect(x, y, w, h);
- }
- else {
+ } else {
+ //if left-to-right, fill the area between the start of the track and
+ //the left edge of the thumb. If right-to-left, fill the area between
+ //the end of the thumb and end of the track.
int x, w;
if (scrollbar.getComponentOrientation().isLeftToRight()) {
- x = decrButton.getX() + decrButton.getWidth();
+ x = trackRect.x;
w = thumbR.x - x;
} else {
x = thumbR.x + thumbR.width;
- w = decrButton.getX() - x;
+ w = trackRect.x + trackRect.width - x;
}
int y = insets.top;
int h = scrollbar.getHeight() - (insets.top + insets.bottom);
@@ -471,19 +517,23 @@ public class BasicScrollBarUI
g.setColor(trackHighlightColor);
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
+ //fill the area between the bottom of the thumb and the end of the track.
int x = insets.left;
int y = thumbR.y + thumbR.height;
int w = scrollbar.getWidth() - (insets.left + insets.right);
- int h = incrButton.getY() - y;
+ int h = trackRect.y + trackRect.height - y;
g.fillRect(x, y, w, h);
}
else {
+ //if left-to-right, fill the area between the right of the thumb and the
+ //end of the track. If right-to-left, then fill the area to the left of
+ //the thumb and the start of the track.
int x, w;
if (scrollbar.getComponentOrientation().isLeftToRight()) {
x = thumbR.x + thumbR.width;
- w = incrButton.getX() - x;
+ w = trackRect.x + trackRect.width - x;
} else {
- x = incrButton.getX() + incrButton.getWidth();
+ x = trackRect.x;
w = thumbR.x - x;
}
int y = insets.top;
@@ -610,11 +660,13 @@ public class BasicScrollBarUI
int incrButtonY = sbSize.height - (sbInsets.bottom + incrButtonH);
/* The thumb must fit within the height left over after we
- * subtract the preferredSize of the buttons and the insets.
+ * subtract the preferredSize of the buttons and the insets
+ * and the gaps
*/
int sbInsetsH = sbInsets.top + sbInsets.bottom;
int sbButtonsH = decrButtonH + incrButtonH;
- float trackH = sbSize.height - (sbInsetsH + sbButtonsH);
+ int gaps = decrGap + incrGap;
+ float trackH = sbSize.height - (sbInsetsH + sbButtonsH) - gaps;
/* Compute the height and origin of the thumb. The case
* where the thumb is at the bottom edge is handled specially
@@ -632,11 +684,11 @@ public class BasicScrollBarUI
thumbH = Math.max(thumbH, getMinimumThumbSize().height);
thumbH = Math.min(thumbH, getMaximumThumbSize().height);
- int thumbY = incrButtonY - thumbH;
+ int thumbY = incrButtonY - incrGap - thumbH;
if (value < (sb.getMaximum() - sb.getVisibleAmount())) {
float thumbRange = trackH - thumbH;
thumbY = (int)(0.5f + (thumbRange * ((value - min) / (range - extent))));
- thumbY += decrButtonY + decrButtonH;
+ thumbY += decrButtonY + decrButtonH + decrGap;
}
/* If the buttons don't fit, allocate half of the available
@@ -652,8 +704,8 @@ public class BasicScrollBarUI
/* Update the trackRect field.
*/
- int itrackY = decrButtonY + decrButtonH;
- int itrackH = incrButtonY - itrackY;
+ int itrackY = decrButtonY + decrButtonH + decrGap;
+ int itrackH = incrButtonY - incrGap - itrackY;
trackRect.setBounds(itemX, itrackY, itemW, itrackH);
/* If the thumb isn't going to fit, zero it's bounds. Otherwise
@@ -671,11 +723,11 @@ public class BasicScrollBarUI
}
}
else {
- if ((thumbY + thumbH) > incrButtonY) {
- thumbY = incrButtonY - thumbH;
+ if ((thumbY + thumbH) > incrButtonY - incrGap) {
+ thumbY = incrButtonY - incrGap - thumbH;
}
- if (thumbY < (decrButtonY + decrButtonH)) {
- thumbY = decrButtonY + decrButtonH + 1;
+ if (thumbY < (decrButtonY + decrButtonH + decrGap)) {
+ thumbY = decrButtonY + decrButtonH + decrGap + 1;
}
setThumbBounds(itemX, thumbY, itemW, thumbH);
}
@@ -710,13 +762,16 @@ public class BasicScrollBarUI
}
int leftButtonX = sbInsets.left;
int rightButtonX = sbSize.width - (sbInsets.right + rightButtonW);
+ int leftGap = ltr ? decrGap : incrGap;
+ int rightGap = ltr ? incrGap : decrGap;
/* The thumb must fit within the width left over after we
- * subtract the preferredSize of the buttons and the insets.
+ * subtract the preferredSize of the buttons and the insets
+ * and the gaps
*/
int sbInsetsW = sbInsets.left + sbInsets.right;
int sbButtonsW = leftButtonW + rightButtonW;
- float trackW = sbSize.width - (sbInsetsW + sbButtonsW);
+ float trackW = sbSize.width - (sbInsetsW + sbButtonsW) - (leftGap + rightGap);
/* Compute the width and origin of the thumb. Enforce
* the thumbs min/max dimensions. The case where the thumb
@@ -735,7 +790,7 @@ public class BasicScrollBarUI
thumbW = Math.max(thumbW, getMinimumThumbSize().width);
thumbW = Math.min(thumbW, getMaximumThumbSize().width);
- int thumbX = ltr ? rightButtonX - thumbW : leftButtonX + leftButtonW;
+ int thumbX = ltr ? rightButtonX - rightGap - thumbW : leftButtonX + leftButtonW + leftGap;
if (value < (max - sb.getVisibleAmount())) {
float thumbRange = trackW - thumbW;
if( ltr ) {
@@ -743,7 +798,7 @@ public class BasicScrollBarUI
} else {
thumbX = (int)(0.5f + (thumbRange * ((max - extent - value) / (range - extent))));
}
- thumbX += leftButtonX + leftButtonW;
+ thumbX += leftButtonX + leftButtonW + leftGap;
}
/* If the buttons don't fit, allocate half of the available
@@ -752,7 +807,7 @@ public class BasicScrollBarUI
int sbAvailButtonW = (sbSize.width - sbInsetsW);
if (sbAvailButtonW < sbButtonsW) {
rightButtonW = leftButtonW = sbAvailButtonW / 2;
- rightButtonX = sbSize.width - (sbInsets.right + rightButtonW);
+ rightButtonX = sbSize.width - (sbInsets.right + rightButtonW + rightGap);
}
(ltr ? decrButton : incrButton).setBounds(leftButtonX, itemY, leftButtonW, itemH);
@@ -760,8 +815,8 @@ public class BasicScrollBarUI
/* Update the trackRect field.
*/
- int itrackX = leftButtonX + leftButtonW;
- int itrackW = rightButtonX - itrackX;
+ int itrackX = leftButtonX + leftButtonW + leftGap;
+ int itrackW = rightButtonX - rightGap - itrackX;
trackRect.setBounds(itrackX, itemY, itrackW, itemH);
/* Make sure the thumb fits between the buttons. Note
@@ -778,11 +833,11 @@ public class BasicScrollBarUI
}
}
else {
- if (thumbX + thumbW > rightButtonX) {
- thumbX = rightButtonX - thumbW;
+ if (thumbX + thumbW > rightButtonX - rightGap) {
+ thumbX = rightButtonX - rightGap - thumbW;
}
- if (thumbX < leftButtonX + leftButtonW) {
- thumbX = leftButtonX + leftButtonW + 1;
+ if (thumbX < leftButtonX + leftButtonW + leftGap) {
+ thumbX = leftButtonX + leftButtonW + leftGap + 1;
}
setThumbBounds(thumbX, itemY, thumbW, itemH);
}
@@ -1151,20 +1206,15 @@ public class BasicScrollBarUI
int thumbMin, thumbMax, thumbPos;
if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
- thumbMin = decrButton.getY() + decrButton.getHeight();
- thumbMax = incrButton.getY() - thumbR.height;
+ thumbMin = trackRect.y;
+ thumbMax = trackRect.y + trackRect.height - thumbR.height;
thumbPos = Math.min(thumbMax, Math.max(thumbMin, (e.getY() - offset)));
setThumbBounds(thumbR.x, thumbPos, thumbR.width, thumbR.height);
trackLength = getTrackBounds().height;
}
else {
- if (scrollbar.getComponentOrientation().isLeftToRight()) {
- thumbMin = decrButton.getX() + decrButton.getWidth();
- thumbMax = incrButton.getX() - thumbR.width;
- } else {
- thumbMin = incrButton.getX() + incrButton.getWidth();
- thumbMax = decrButton.getX() - thumbR.width;
- }
+ thumbMin = trackRect.x;
+ thumbMax = trackRect.x + trackRect.width - thumbR.width;
thumbPos = Math.min(thumbMax, Math.max(thumbMin, (e.getX() - offset)));
setThumbBounds(thumbPos, thumbR.y, thumbR.width, thumbR.height);
trackLength = getTrackBounds().width;
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java b/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java
index 0a858d41c18b33f37740fcbebcb14f07b15b0031..97e2f60f52b2b8ac6949e40fef910b47795786a4 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java
@@ -205,6 +205,9 @@ public class BasicSliderUI extends SliderUI{
focusColor = UIManager.getColor("Slider.focus");
focusInsets = (Insets)UIManager.get( "Slider.focusInsets" );
+ // use default if missing so that BasicSliderUI can be used in other
+ // LAFs like Nimbus
+ if (focusInsets == null) focusInsets = new InsetsUIResource(2,2,2,2);
}
protected TrackListener createTrackListener(JSlider slider) {
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java
index 2f0bffae8ab896df9192a647925f3a24dc88b0ec..b35a75ed700e7d330426b1f92c643b38ab4d7a04 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -347,8 +347,9 @@ public class BasicSplitPaneUI extends SplitPaneUI
// This plus 2 here is to provide backwards consistancy. Previously,
// the old size did not include the 2 pixel border around the divider,
// it now does.
- LookAndFeel.installProperty(splitPane, "dividerSize",
- UIManager.get("SplitPane.dividerSize"));
+ Integer dividerSize = (Integer)UIManager.get("SplitPane.dividerSize");
+ if (divider == null) dividerSize = 10;
+ LookAndFeel.installProperty(splitPane, "dividerSize", dividerSize);
divider.setDividerSize(splitPane.getDividerSize());
dividerSize = divider.getDividerSize();
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index a266b77141e9f50091cc177cf4cff00880402267..5a94a3631959b63c1856d02d9e9dd352b6cef16b 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -379,6 +379,14 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
opaque = Boolean.FALSE;
}
LookAndFeel.installProperty(tabPane, "opaque", opaque);
+
+ // Fix for 6711145 BasicTabbedPanuUI should not throw a NPE if these
+ // keys are missing. So we are setting them to there default values here
+ // if the keys are missing.
+ if (tabInsets == null) tabInsets = new Insets(0,4,1,4);
+ if (selectedTabPadInsets == null) selectedTabPadInsets = new Insets(2,2,2,1);
+ if (tabAreaInsets == null) tabAreaInsets = new Insets(3,2,0,2);
+ if (contentBorderInsets == null) contentBorderInsets = new Insets(2,2,3,3);
}
protected void uninstallDefaults() {
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicTableUI.java b/src/share/classes/javax/swing/plaf/basic/BasicTableUI.java
index 585e01dc26b3a80205c1179f3f0cbf57b8a8b7cc..16ceab73ee2a8f8f9e954bd5234ff7fc6ac9ce45 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicTableUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicTableUI.java
@@ -1414,17 +1414,20 @@ public class BasicTableUI extends TableUI
Color sbg = table.getSelectionBackground();
if (sbg == null || sbg instanceof UIResource) {
- table.setSelectionBackground(UIManager.getColor("Table.selectionBackground"));
+ sbg = UIManager.getColor("Table.selectionBackground");
+ table.setSelectionBackground(sbg != null ? sbg : UIManager.getColor("textHighlight"));
}
Color sfg = table.getSelectionForeground();
if (sfg == null || sfg instanceof UIResource) {
- table.setSelectionForeground(UIManager.getColor("Table.selectionForeground"));
+ sfg = UIManager.getColor("Table.selectionForeground");
+ table.setSelectionForeground(sfg != null ? sfg : UIManager.getColor("textHighlightText"));
}
Color gridColor = table.getGridColor();
if (gridColor == null || gridColor instanceof UIResource) {
- table.setGridColor(UIManager.getColor("Table.gridColor"));
+ gridColor = UIManager.getColor("Table.gridColor");
+ table.setGridColor(gridColor != null ? gridColor : Color.GRAY);
}
// install the scrollpane border
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java b/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java
index 166c6fc8a8674cfe21f356fcc8211834f707ee4d..cef9166355f58b7dd1f3c603440db0ff5e9d5dc4 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicTextUI.java
@@ -27,13 +27,10 @@ package javax.swing.plaf.basic;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
-import java.awt.font.*;
import java.awt.datatransfer.*;
-import java.awt.dnd.*;
import java.awt.im.InputContext;
import java.beans.*;
import java.io.*;
-import java.net.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.text.*;
@@ -785,11 +782,15 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
installDefaults();
installDefaults2();
- // common case is background painted... this can
- // easily be changed by subclasses or from outside
- // of the component.
- LookAndFeel.installProperty(editor, "opaque", Boolean.TRUE);
- LookAndFeel.installProperty(editor, "autoscrolls", Boolean.TRUE);
+ // This is a workaround as these should not override what synth has
+ // set them to
+ if (!(this instanceof sun.swing.plaf.synth.SynthUI)){
+ // common case is background painted... this can
+ // easily be changed by subclasses or from outside
+ // of the component.
+ LookAndFeel.installProperty(editor, "opaque", Boolean.TRUE);
+ LookAndFeel.installProperty(editor, "autoscrolls", Boolean.TRUE);
+ }
// attach to the model and editor
editor.addPropertyChangeListener(updateHandler);
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
index 05e3183b52467698e5671bd863c622139133d278..8fdc88d946f673ae822dfc8d7cd41ed9dd9b6716 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
@@ -2402,15 +2402,25 @@ public class BasicTreeUI extends TreeUI
}
leadRow = getRowForPath(tree, newPath);
- if(repaint) {
- if(bounds != null)
- tree.repaint(bounds);
+ if (repaint) {
+ if (bounds != null) {
+ tree.repaint(getRepaintPathBounds(bounds));
+ }
bounds = getPathBounds(tree, newPath);
- if(bounds != null)
- tree.repaint(bounds);
+ if (bounds != null) {
+ tree.repaint(getRepaintPathBounds(bounds));
+ }
}
}
+ private Rectangle getRepaintPathBounds(Rectangle bounds) {
+ if (UIManager.getBoolean("Tree.repaintWholeRow")) {
+ bounds.x = 0;
+ bounds.width = tree.getWidth();
+ }
+ return bounds;
+ }
+
private TreePath getLeadSelectionPath() {
return tree.getLeadSelectionPath();
}
@@ -3643,14 +3653,6 @@ public class BasicTreeUI extends TreeUI
focusGained(e);
}
- private Rectangle getRepaintPathBounds(Rectangle bounds) {
- if(UIManager.getBoolean("Tree.repaintWholeRow")) {
- bounds.x = 0;
- bounds.width = tree.getWidth();
- }
- return bounds;
- }
-
//
// CellEditorListener
//
diff --git a/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java b/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java
new file mode 100644
index 0000000000000000000000000000000000000000..55fb19599c777b979e2ca16eccac566e22fbad6b
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java
@@ -0,0 +1,735 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.lang.reflect.Method;
+import javax.swing.*;
+import javax.swing.plaf.UIResource;
+import javax.swing.Painter;
+import java.awt.print.PrinterGraphics;
+import static javax.swing.plaf.nimbus.NimbusLookAndFeel.deriveARGB;
+
+/**
+ * Convenient base class for defining Painter instances for rendering a
+ * region or component in Nimbus.
+ *
+ * @author Jasper Potts
+ * @author Richard Bair
+ */
+public abstract class AbstractRegionPainter implements Painterwidth
+ * and a height of height
. For performance reasons, you may want to read
+ * the clip from the Graphics2D object and only render within that space.
+ *
+ * @param g The Graphics2D surface to paint to
+ * @param c The JComponent related to the drawing event. For example, if the
+ * region being rendered is Button, then c
will be a
+ * JButton. If the region being drawn is ScrollBarSlider, then the
+ * component will be JScrollBar. This value may be null.
+ * @param width The width of the region to paint. Note that in the case of
+ * painting the foreground, this value may differ from c.getWidth().
+ * @param height The height of the region to paint. Note that in the case of
+ * painting the foreground, this value may differ from c.getHeight().
+ * @param extendedCacheKeys The result of the call to getExtendedCacheKeys()
+ */
+ protected abstract void doPaint(Graphics2D g, JComponent c, int width,
+ int height, Object[] extendedCacheKeys);
+
+ /**
+ * Decodes and returns a float value representing the actual pixel location for
+ * the given encoded X value.
+ *
+ * @param x an encoded x value (0...1, or 1...2, or 2...3)
+ * @return the decoded x value
+ */
+ protected final float decodeX(float x) {
+ if (ctx.canvasSize == null) return x;
+
+ if (x >= 0 && x <= 1) {
+ return x * leftWidth;
+ } else if (x > 1 && x < 2) {
+ return ((x-1) * centerWidth) + leftWidth;
+ } else if (x >= 2 && x <= 3) {
+ return ((x-2) * rightWidth) + leftWidth + centerWidth;
+ } else {
+ throw new AssertionError("Invalid x");
+ }
+ }
+
+ /**
+ * Decodes and returns a float value representing the actual pixel location for
+ * the given encoded y value.
+ *
+ * @param y an encoded y value (0...1, or 1...2, or 2...3)
+ * @return the decoded y value
+ */
+ protected final float decodeY(float y) {
+ if (ctx.canvasSize == null) return y;
+
+ if (y >= 0 && y <= 1) {
+ return y * topHeight;
+ } else if (y > 1 && y < 2) {
+ return ((y-1) * centerHeight) + topHeight;
+ } else if (y >= 2 && y <= 3) {
+ return ((y-2) * bottomHeight) + topHeight + centerHeight;
+ } else {
+ throw new AssertionError("Invalid y");
+ }
+ }
+
+ /**
+ * Decodes and returns a float value representing the actual pixel location for
+ * the anchor point given the encoded X value of the control point, and the offset
+ * distance to the anchor from that control point.
+ *
+ * @param x an encoded x value of the bezier control point (0...1, or 1...2, or 2...3)
+ * @param dx the offset distance to the anchor from the control point x
+ * @return the decoded x location of the control point
+ */
+ protected final float decodeAnchorX(float x, float dx) {
+ if (ctx.canvasSize == null) return x + dx;
+
+ if (x >= 0 && x <= 1) {
+ return decodeX(x) + (dx * leftScale);
+ } else if (x > 1 && x < 2) {
+ return decodeX(x) + (dx * centerHScale);
+ } else if (x >= 2 && x <= 3) {
+ return decodeX(x) + (dx * rightScale);
+ } else {
+ throw new AssertionError("Invalid x");
+ }
+ }
+
+ /**
+ * Decodes and returns a float value representing the actual pixel location for
+ * the anchor point given the encoded Y value of the control point, and the offset
+ * distance to the anchor from that control point.
+ *
+ * @param y an encoded y value of the bezier control point (0...1, or 1...2, or 2...3)
+ * @param dy the offset distance to the anchor from the control point y
+ * @return the decoded y position of the control point
+ */
+ protected final float decodeAnchorY(float y, float dy) {
+ if (ctx.canvasSize == null) return y + dy;
+
+ if (y >= 0 && y <= 1) {
+ return decodeY(y) + (dy * topScale);
+ } else if (y > 1 && y < 2) {
+ return decodeY(y) + (dy * centerVScale);
+ } else if (y >= 2 && y <= 3) {
+ return decodeY(y) + (dy * bottomScale);
+ } else {
+ throw new AssertionError("Invalid y");
+ }
+ }
+
+ /**
+ * Decodes and returns a color, which is derived from a base color in UI
+ * defaults.
+ *
+ * @param key A key corrosponding to the value in the UI Defaults table
+ * of UIManager where the base color is defined
+ * @param hOffset The hue offset used for derivation.
+ * @param sOffset The saturation offset used for derivation.
+ * @param bOffset The brightness offset used for derivation.
+ * @param aOffset The alpha offset used for derivation. Between 0...255
+ * @return The derived color, whos color value will change if the parent
+ * uiDefault color changes.
+ */
+ protected final Color decodeColor(String key, float hOffset, float sOffset,
+ float bOffset, int aOffset) {
+ if (UIManager.getLookAndFeel() instanceof NimbusLookAndFeel){
+ NimbusLookAndFeel laf = (NimbusLookAndFeel) UIManager.getLookAndFeel();
+ return laf.getDerivedColor(key, hOffset, sOffset, bOffset, aOffset, true);
+ } else {
+ // can not give a right answer as painter sould not be used outside
+ // of nimbus laf but do the best we can
+ return Color.getHSBColor(hOffset,sOffset,bOffset);
+ }
+ }
+
+ /**
+ * Decodes and returns a color, which is derived from a offset between two
+ * other colors.
+ *
+ * @param color1 The first color
+ * @param color2 The second color
+ * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
+ * color 1 and 1.0 is color 2;
+ * @return The derived color
+ */
+ protected final Color decodeColor(Color color1, Color color2,
+ float midPoint) {
+ return new Color(deriveARGB(color1, color2, midPoint));
+ }
+
+ /**
+ * Given parameters for creating a LinearGradientPaint, this method will
+ * create and return a linear gradient paint. One primary purpose for this
+ * method is to avoid creating a LinearGradientPaint where the start and
+ * end points are equal. In such a case, the end y point is slightly
+ * increased to avoid the overlap.
+ *
+ * @param x1
+ * @param y1
+ * @param x2
+ * @param y2
+ * @param midpoints
+ * @param colors
+ * @return a valid LinearGradientPaint. This method never returns null.
+ */
+ protected final LinearGradientPaint decodeGradient(float x1, float y1, float x2, float y2, float[] midpoints, Color[] colors) {
+ if (x1 == x2 && y1 == y2) {
+ y2 += .00001f;
+ }
+ return new LinearGradientPaint(x1, y1, x2, y2, midpoints, colors);
+ }
+
+ /**
+ * Given parameters for creating a RadialGradientPaint, this method will
+ * create and return a radial gradient paint. One primary purpose for this
+ * method is to avoid creating a RadialGradientPaint where the radius
+ * is non-positive. In such a case, the radius is just slightly
+ * increased to avoid 0.
+ *
+ * @param x
+ * @param y
+ * @param r
+ * @param midpoints
+ * @param colors
+ * @return a valid RadialGradientPaint. This method never returns null.
+ */
+ protected final RadialGradientPaint decodeRadialGradient(float x, float y, float r, float[] midpoints, Color[] colors) {
+ if (r == 0f) {
+ r = .00001f;
+ }
+ return new RadialGradientPaint(x, y, r, midpoints, colors);
+ }
+
+ /**
+ * Get a color property from the given JComponent. First checks for a
+ * getXXX()
method and if that fails checks for a client
+ * property with key property
. If that still fails to return
+ * a Color then defaultColor
is returned.
+ *
+ * @param c The component to get the color property from
+ * @param property The name of a bean style property or client property
+ * @param defaultColor The color to return if no color was obtained from
+ * the component.
+ * @return The color that was obtained from the component or defaultColor
+ */
+ protected final Color getComponentColor(JComponent c, String property,
+ Color defaultColor,
+ float saturationOffset,
+ float brightnessOffset,
+ int alphaOffset) {
+ Color color = null;
+ if (c != null) {
+ // handle some special cases for performance
+ if ("background".equals(property)) {
+ color = c.getBackground();
+ } else if ("foreground".equals(property)) {
+ color = c.getForeground();
+ } else if (c instanceof JList && "selectionForeground".equals(property)) {
+ color = ((JList) c).getSelectionForeground();
+ } else if (c instanceof JList && "selectionBackground".equals(property)) {
+ color = ((JList) c).getSelectionBackground();
+ } else if (c instanceof JTable && "selectionForeground".equals(property)) {
+ color = ((JTable) c).getSelectionForeground();
+ } else if (c instanceof JTable && "selectionBackground".equals(property)) {
+ color = ((JTable) c).getSelectionBackground();
+ } else {
+ String s = "get" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
+ try {
+ Method method = c.getClass().getMethod(s);
+ color = (Color) method.invoke(c);
+ } catch (Exception e) {
+ //don't do anything, it just didn't work, that's all.
+ //This could be a normal occurance if you use a property
+ //name referring to a key in clientProperties instead of
+ //a real property
+ }
+ if (color == null) {
+ Object value = c.getClientProperty(property);
+ if (value instanceof Color) {
+ color = (Color) value;
+ }
+ }
+ }
+ }
+ // we return the defaultColor if the color found is null, or if
+ // it is a UIResource. This is done because the color for the
+ // ENABLED state is set on the component, but you don't want to use
+ // that color for the over state. So we only respect the color
+ // specified for the property if it was set by the user, as opposed
+ // to set by us.
+ if (color == null || color instanceof UIResource) {
+ return defaultColor;
+ } else if (saturationOffset != 0 || brightnessOffset != 0 || alphaOffset != 0) {
+ float[] tmp = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+ tmp[1] = clamp(tmp[1] + saturationOffset);
+ tmp[2] = clamp(tmp[2] + brightnessOffset);
+ int alpha = clamp(color.getAlpha() + alphaOffset);
+ return new Color((Color.HSBtoRGB(tmp[0], tmp[1], tmp[2]) & 0xFFFFFF) | (alpha <<24));
+ } else {
+ return color;
+ }
+ }
+
+ /**
+ * A class encapsulating state useful when painting. Generally, instances of this
+ * class are created once, and reused for each paint request without modification.
+ * This class contains values useful when hinting the cache engine, and when decoding
+ * control points and bezier curve anchors.
+ */
+ protected static class PaintContext {
+ protected static enum CacheMode {
+ NO_CACHING, FIXED_SIZES, NINE_SQUARE_SCALE
+ }
+
+ private static Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
+
+ private Insets stretchingInsets;
+ private Dimension canvasSize;
+ private boolean inverted;
+ private CacheMode cacheMode;
+ private double maxHorizontalScaleFactor;
+ private double maxVerticalScaleFactor;
+
+ private float a; // insets.left
+ private float b; // canvasSize.width - insets.right
+ private float c; // insets.top
+ private float d; // canvasSize.height - insets.bottom;
+ private float aPercent; // only used if inverted == true
+ private float bPercent; // only used if inverted == true
+ private float cPercent; // only used if inverted == true
+ private float dPercent; // only used if inverted == true
+
+ /**
+ * Creates a new PaintContext which does not attempt to cache or scale any cached
+ * images.
+ *
+ * @param insets The stretching insets. May be null. If null, then assumed to be 0, 0, 0, 0.
+ * @param canvasSize The size of the canvas used when encoding the various x/y values. May be null.
+ * If null, then it is assumed that there are no encoded values, and any calls
+ * to one of the "decode" methods will return the passed in value.
+ * @param inverted Whether to "invert" the meaning of the 9-square grid and stretching insets
+ */
+ public PaintContext(Insets insets, Dimension canvasSize, boolean inverted) {
+ this(insets, canvasSize, inverted, null, 1, 1);
+ }
+
+ /**
+ * Creates a new PaintContext.
+ *
+ * @param insets The stretching insets. May be null. If null, then assumed to be 0, 0, 0, 0.
+ * @param canvasSize The size of the canvas used when encoding the various x/y values. May be null.
+ * If null, then it is assumed that there are no encoded values, and any calls
+ * to one of the "decode" methods will return the passed in value.
+ * @param inverted Whether to "invert" the meaning of the 9-square grid and stretching insets
+ * @param cacheMode A hint as to which caching mode to use. If null, then set to no caching.
+ * @param maxH The maximium scale in the horizontal direction to use before punting and redrawing from scratch.
+ * For example, if maxH is 2, then we will attempt to scale any cached images up to 2x the canvas
+ * width before redrawing from scratch. Reasonable maxH values may improve painting performance.
+ * If set too high, then you may get poor looking graphics at higher zoom levels. Must be >= 1.
+ * @param maxV The maximium scale in the vertical direction to use before punting and redrawing from scratch.
+ * For example, if maxV is 2, then we will attempt to scale any cached images up to 2x the canvas
+ * height before redrawing from scratch. Reasonable maxV values may improve painting performance.
+ * If set too high, then you may get poor looking graphics at higher zoom levels. Must be >= 1.
+ */
+ public PaintContext(Insets insets, Dimension canvasSize, boolean inverted,
+ CacheMode cacheMode, double maxH, double maxV) {
+ if (maxH < 1 || maxH < 1) {
+ throw new IllegalArgumentException("Both maxH and maxV must be >= 1");
+ }
+
+ this.stretchingInsets = insets == null ? EMPTY_INSETS : insets;
+ this.canvasSize = canvasSize;
+ this.inverted = inverted;
+ this.cacheMode = cacheMode == null ? CacheMode.NO_CACHING : cacheMode;
+ this.maxHorizontalScaleFactor = maxH;
+ this.maxVerticalScaleFactor = maxV;
+
+ if (canvasSize != null) {
+ a = insets.left;
+ b = canvasSize.width - insets.right;
+ c = insets.top;
+ d = canvasSize.height - insets.bottom;
+ this.canvasSize = canvasSize;
+ this.inverted = inverted;
+ if (inverted) {
+ float available = canvasSize.width - (b - a);
+ aPercent = available > 0f ? a / available : 0f;
+ bPercent = available > 0f ? b / available : 0f;
+ available = canvasSize.height - (d - c);
+ cPercent = available > 0f ? c / available : 0f;
+ dPercent = available > 0f ? d / available : 0f;
+ }
+ }
+ }
+ }
+
+ //---------------------- private methods
+
+ //initializes the class to prepare it for being able to decode points
+ private void prepare(float w, float h) {
+ //if no PaintContext has been specified, reset the values and bail
+ //also bail if the canvasSize was not set (since decoding will not work)
+ if (ctx == null || ctx.canvasSize == null) {
+ f = 1f;
+ leftWidth = centerWidth = rightWidth = 0f;
+ topHeight = centerHeight = bottomHeight = 0f;
+ leftScale = centerHScale = rightScale = 0f;
+ topScale = centerVScale = bottomScale = 0f;
+ return;
+ }
+
+ //calculate the scaling factor, and the sizes for the various 9-square sections
+ Number scale = (Number)UIManager.get("scale");
+ f = scale == null ? 1f : scale.floatValue();
+
+ if (ctx.inverted) {
+ centerWidth = (ctx.b - ctx.a) * f;
+ float availableSpace = w - centerWidth;
+ leftWidth = availableSpace * ctx.aPercent;
+ rightWidth = availableSpace * ctx.bPercent;
+ centerHeight = (ctx.d - ctx.c) * f;
+ availableSpace = h - centerHeight;
+ topHeight = availableSpace * ctx.cPercent;
+ bottomHeight = availableSpace * ctx.dPercent;
+ } else {
+ leftWidth = ctx.a * f;
+ rightWidth = (float)(ctx.canvasSize.getWidth() - ctx.b) * f;
+ centerWidth = w - leftWidth - rightWidth;
+ topHeight = ctx.c * f;
+ bottomHeight = (float)(ctx.canvasSize.getHeight() - ctx.d) * f;
+ centerHeight = h - topHeight - bottomHeight;
+ }
+
+ leftScale = ctx.a == 0f ? 0f : leftWidth / ctx.a;
+ centerHScale = (ctx.b - ctx.a) == 0f ? 0f : centerWidth / (ctx.b - ctx.a);
+ rightScale = (ctx.canvasSize.width - ctx.b) == 0f ? 0f : rightWidth / (ctx.canvasSize.width - ctx.b);
+ topScale = ctx.c == 0f ? 0f : topHeight / ctx.c;
+ centerVScale = (ctx.d - ctx.c) == 0f ? 0f : centerHeight / (ctx.d - ctx.c);
+ bottomScale = (ctx.canvasSize.height - ctx.d) == 0f ? 0f : bottomHeight / (ctx.canvasSize.height - ctx.d);
+ }
+
+ private void paintWith9SquareCaching(Graphics2D g, PaintContext ctx,
+ JComponent c, int w, int h,
+ Object[] extendedCacheKeys) {
+ // check if we can scale to the requested size
+ Dimension canvas = ctx.canvasSize;
+ Insets insets = ctx.stretchingInsets;
+
+ if (w <= (canvas.width * ctx.maxHorizontalScaleFactor) && h <= (canvas.height * ctx.maxVerticalScaleFactor)) {
+ // get image at canvas size
+ VolatileImage img = getImage(g.getDeviceConfiguration(), c, canvas.width, canvas.height, extendedCacheKeys);
+ if (img != null) {
+ // calculate dst inserts
+ // todo: destination inserts need to take into acount scale factor for high dpi. Note: You can use f for this, I think
+ Insets dstInsets;
+ if (ctx.inverted){
+ int leftRight = (w-(canvas.width-(insets.left+insets.right)))/2;
+ int topBottom = (h-(canvas.height-(insets.top+insets.bottom)))/2;
+ dstInsets = new Insets(topBottom,leftRight,topBottom,leftRight);
+ } else {
+ dstInsets = insets;
+ }
+ // paint 9 square scaled
+ Object oldScaleingHints = g.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ ImageScalingHelper.paint(g, 0, 0, w, h, img, insets, dstInsets,
+ ImageScalingHelper.PaintType.PAINT9_STRETCH, ImageScalingHelper.PAINT_ALL);
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+ oldScaleingHints!=null?oldScaleingHints:RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+ } else {
+ // render directly
+ paint0(g, c, w, h, extendedCacheKeys);
+ }
+ } else {
+ // paint directly
+ paint0(g, c, w, h, extendedCacheKeys);
+ }
+ }
+
+ private void paintWithFixedSizeCaching(Graphics2D g, JComponent c, int w,
+ int h, Object[] extendedCacheKeys) {
+ VolatileImage img = getImage(g.getDeviceConfiguration(), c, w, h, extendedCacheKeys);
+ if (img != null) {
+ //render cached image
+ g.drawImage(img, 0, 0, null);
+ } else {
+ // render directly
+ paint0(g, c, w, h, extendedCacheKeys);
+ }
+ }
+
+ /** Gets the rendered image for this painter at the requested size, either from cache or create a new one */
+ private VolatileImage getImage(GraphicsConfiguration config, JComponent c,
+ int w, int h, Object[] extendedCacheKeys) {
+ ImageCache imageCache = ImageCache.getInstance();
+ //get the buffer for this component
+ VolatileImage buffer = (VolatileImage) imageCache.getImage(config, w, h, this, extendedCacheKeys);
+
+ int renderCounter = 0; //to avoid any potential, though unlikely, infinite loop
+ do {
+ //validate the buffer so we can check for surface loss
+ int bufferStatus = VolatileImage.IMAGE_INCOMPATIBLE;
+ if (buffer != null) {
+ bufferStatus = buffer.validate(config);
+ }
+
+ //If the buffer status is incompatible or restored, then we need to re-render to the volatile image
+ if (bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE || bufferStatus == VolatileImage.IMAGE_RESTORED) {
+ //if the buffer is null (hasn't been created), or isn't the right size, or has lost its contents,
+ //then recreate the buffer
+ if (buffer == null || buffer.getWidth() != w || buffer.getHeight() != h ||
+ bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE) {
+ //clear any resources related to the old back buffer
+ if (buffer != null) {
+ buffer.flush();
+ buffer = null;
+ }
+ //recreate the buffer
+ buffer = config.createCompatibleVolatileImage(w, h,
+ Transparency.TRANSLUCENT);
+ // put in cache for future
+ imageCache.setImage(buffer, config, w, h, this, extendedCacheKeys);
+ }
+ //create the graphics context with which to paint to the buffer
+ Graphics2D bg = buffer.createGraphics();
+ //clear the background before configuring the graphics
+ bg.setComposite(AlphaComposite.Clear);
+ bg.fillRect(0, 0, w, h);
+ bg.setComposite(AlphaComposite.SrcOver);
+ configureGraphics(bg);
+ // paint the painter into buffer
+ paint0(bg, c, w, h, extendedCacheKeys);
+ //close buffer graphics
+ bg.dispose();
+ }
+ } while (buffer.contentsLost() && renderCounter++ < 3);
+ // check if we failed
+ if (renderCounter == 3) return null;
+ // return image
+ return buffer;
+ }
+
+ //convenience method which creates a temporary graphics object by creating a
+ //clone of the passed in one, configuring it, drawing with it, disposing it.
+ //These steps have to be taken to ensure that any hints set on the graphics
+ //are removed subsequent to painting.
+ private void paint0(Graphics2D g, JComponent c, int width, int height,
+ Object[] extendedCacheKeys) {
+ prepare(width, height);
+ g = (Graphics2D)g.create();
+ configureGraphics(g);
+ doPaint(g, c, width, height, extendedCacheKeys);
+ g.dispose();
+ }
+
+ private float clamp(float value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 1) {
+ value = 1;
+ }
+ return value;
+ }
+
+ private int clamp(int value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 255) {
+ value = 255;
+ }
+ return value;
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/Defaults.template b/src/share/classes/javax/swing/plaf/nimbus/Defaults.template
new file mode 100644
index 0000000000000000000000000000000000000000..a0f5afc22c878c58ab07ce5d626a1d16e6817f1c
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/Defaults.template
@@ -0,0 +1,878 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package ${PACKAGE};
+
+import javax.swing.Painter;
+import java.awt.Graphics;
+import sun.font.FontManager;
+import sun.swing.plaf.synth.DefaultSynthStyle;
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.BorderUIResource;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.DimensionUIResource;
+import javax.swing.plaf.FontUIResource;
+import javax.swing.plaf.InsetsUIResource;
+import javax.swing.plaf.synth.Region;
+import javax.swing.plaf.synth.SynthStyle;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.image.BufferedImage;
+import static java.awt.image.BufferedImage.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import javax.swing.border.Border;
+import javax.swing.plaf.UIResource;
+
+/**
+ * This class contains all the implementation details related to
+ * ${LAF_NAME}. It contains all the code for initializing the UIDefaults table,
+ * as well as for selecting
+ * a SynthStyle based on a JComponent/Region pair.
+ *
+ * @author Richard Bair
+ */
+final class ${LAF_NAME}Defaults {
+ /**
+ * The map of SynthStyles. This map is keyed by Region. Each Region maps
+ * to a List of LazyStyles. Each LazyStyle has a reference to the prefix
+ * that was registered with it. This reference can then be inspected to see
+ * if it is the proper lazy style.
+ *
+ * There can be more than one LazyStyle for a single Region if there is more
+ * than one prefix defined for a given region. For example, both Button and
+ * "MyButton" might be prefixes assigned to the Region.Button region.
+ */
+ private Mapd
, then you will
+ * only receive notification of LookAndFeel level defaults, not
+ * all defaults on the UIManager.
+ */
+ void initializeDefaults(UIDefaults d) {
+${UI_DEFAULT_INIT}
+ }
+
+ /**
+ *
+ * Check the map of styles m
. If the map contains no styles at
+ * all, then simply return the defaultStyle. If the map contains styles,
+ * then iterate over all of the styles for the Region r
looking
+ * for the best match, based on prefix. If a match was made, then return
+ * that SynthStyle. Otherwise, return the defaultStyle.
+ *
+ */
+ private final class LazyStyle {
+ /**
+ * The prefix this LazyStyle was registered with. Something like
+ * Button or ComboBox:"ComboBox.arrowButton"
+ */
+ private String prefix;
+ /**
+ * Whether or not this LazyStyle represents an unnamed component
+ */
+ private boolean simple = true;
+ /**
+ * The various parts, or sections, of the prefix. For example,
+ * the prefix:
+ * ComboBox:"ComboBox.arrowButton"
+ *
+ * will be broken into two parts,
+ * ComboBox and "ComboBox.arrowButton"
+ */
+ private Part[] parts;
+ /**
+ * Cached shared style.
+ */
+ private NimbusStyle style;
+ /**
+ * A weakly referenced hash map such that if the reference JComponent
+ * key is garbage collected then the entry is removed from the map.
+ * This cache exists so that when a JComponent has nimbus overrides
+ * in its client map, a unique style will be created and returned
+ * for that JComponent instance, always. In such a situation each
+ * JComponent instance must have its own instance of NimbusStyle.
+ */
+ private WeakHashMapColorModel
.
+ * @see java.awt.image.ColorModel#getRGBdefault
+ * @see #getRed
+ * @see #getGreen
+ * @see #getBlue
+ * @since JDK1.0
+ */
+ @Override public int getRGB() {
+ return argbValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DerivedColor)) return false;
+ DerivedColor that = (DerivedColor) o;
+ if (aOffset != that.aOffset) return false;
+ if (Float.compare(that.bOffset, bOffset) != 0) return false;
+ if (Float.compare(that.hOffset, hOffset) != 0) return false;
+ if (Float.compare(that.sOffset, sOffset) != 0) return false;
+ if (!uiDefaultParentName.equals(that.uiDefaultParentName)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = uiDefaultParentName.hashCode();
+ result = 31 * result + hOffset != +0.0f ?
+ Float.floatToIntBits(hOffset) : 0;
+ result = 31 * result + sOffset != +0.0f ?
+ Float.floatToIntBits(sOffset) : 0;
+ result = 31 * result + bOffset != +0.0f ?
+ Float.floatToIntBits(bOffset) : 0;
+ result = 31 * result + aOffset;
+ return result;
+ }
+
+ /**
+ * Add a PropertyChangeListener to the listener list.
+ * The listener is registered for all properties.
+ * The same listener object may be added more than once, and will be called
+ * as many times as it is added.
+ * If listener
is null, no exception is thrown and no action
+ * is taken.
+ *
+ * @param listener The PropertyChangeListener to be added
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Remove a PropertyChangeListener from the listener list.
+ * This removes a PropertyChangeListener that was registered
+ * for all properties.
+ * If listener
was added more than once to the same event
+ * source, it will be notified one less time after being removed.
+ * If listener
is null, or was never added, no exception is
+ * thrown and no action is taken.
+ *
+ * @param listener The PropertyChangeListener to be removed
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ private float clamp(float value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 1) {
+ value = 1;
+ }
+ return value;
+ }
+
+ private int clamp(int value) {
+ if (value < 0) {
+ value = 0;
+ } else if (value > 255) {
+ value = 255;
+ }
+ return value;
+ }
+
+ /**
+ * Returns a string representation of this Color
. This method
+ * is intended to be used only for debugging purposes. The content and
+ * format of the returned string might vary between implementations. The
+ * returned string might be empty but cannot be null
.
+ *
+ * @return a String representation of this Color
.
+ */
+ @Override
+ public String toString() {
+ Color src = UIManager.getColor(uiDefaultParentName);
+ String s = "DerivedColor(color=" + getRed() + "," + getGreen() + "," + getBlue() +
+ " parent=" + uiDefaultParentName +
+ " offsets=" + getHueOffset() + "," + getSaturationOffset() + ","
+ + getBrightnessOffset() + "," + getAlphaOffset();
+ return src == null ? s : s + " pColor=" + src.getRed() + "," + src.getGreen() + "," + src.getBlue();
+ }
+
+ static class UIResource extends DerivedColor implements javax.swing.plaf.UIResource {
+ UIResource(String uiDefaultParentName, float hOffset, float sOffset,
+ float bOffset, int aOffset) {
+ super(uiDefaultParentName, hOffset, sOffset, bOffset, aOffset);
+ }
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/DropShadowEffect.java b/src/share/classes/javax/swing/plaf/nimbus/DropShadowEffect.java
new file mode 100644
index 0000000000000000000000000000000000000000..b97a8e0a50396c48c472b4eedd124571ab97b877
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/DropShadowEffect.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.util.Arrays;
+
+/**
+ * DropShadowEffect - This effect currently only works with ARGB type buffered
+ * images.
+ *
+ * @author Created by Jasper Potts (Jun 18, 2007)
+ */
+class DropShadowEffect extends ShadowEffect {
+
+ // =================================================================================================================
+ // Effect Methods
+
+ /**
+ * Get the type of this effect, one of UNDER,BLENDED,OVER. UNDER means the result of apply effect should be painted
+ * under the src image. BLENDED means the result of apply sffect contains a modified src image so just it should be
+ * painted. OVER means the result of apply effect should be painted over the src image.
+ *
+ * @return The effect type
+ */
+ @Override
+ EffectType getEffectType() {
+ return EffectType.UNDER;
+ }
+
+ /**
+ * Apply the effect to the src image generating the result . The result image may or may not contain the source
+ * image depending on what the effect type is.
+ *
+ * @param src The source image for applying the effect to
+ * @param dst The destination image to paint effect result into. If this is null then a new image will be created
+ * @param w The width of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @param h The height of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @return Image with the result of the effect
+ */
+ @Override
+ BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h) {
+ if (src == null || src.getType() != BufferedImage.TYPE_INT_ARGB){
+ throw new IllegalArgumentException("Effect only works with " +
+ "source images of type BufferedImage.TYPE_INT_ARGB.");
+ }
+ if (dst != null && dst.getType() != BufferedImage.TYPE_INT_ARGB){
+ throw new IllegalArgumentException("Effect only works with " +
+ "destination images of type BufferedImage.TYPE_INT_ARGB.");
+ }
+ // calculate offset
+ double trangleAngle = Math.toRadians(angle - 90);
+ int offsetX = (int) (Math.sin(trangleAngle) * distance);
+ int offsetY = (int) (Math.cos(trangleAngle) * distance);
+ // clac expanded size
+ int tmpOffX = offsetX + size;
+ int tmpOffY = offsetX + size;
+ int tmpW = w + offsetX + size + size;
+ int tmpH = h + offsetX + size;
+ // create tmp buffers
+ int[] lineBuf = getArrayCache().getTmpIntArray(w);
+ byte[] tmpBuf1 = getArrayCache().getTmpByteArray1(tmpW * tmpH);
+ Arrays.fill(tmpBuf1, (byte) 0x00);
+ byte[] tmpBuf2 = getArrayCache().getTmpByteArray2(tmpW * tmpH);
+ // extract src image alpha channel and inverse and offset
+ Raster srcRaster = src.getRaster();
+ for (int y = 0; y < h; y++) {
+ int dy = (y + tmpOffY);
+ int offset = dy * tmpW;
+ srcRaster.getDataElements(0, y, w, 1, lineBuf);
+ for (int x = 0; x < w; x++) {
+ int dx = x + tmpOffX;
+ tmpBuf1[offset + dx] = (byte) ((lineBuf[x] & 0xFF000000) >>> 24);
+ }
+ }
+ // blur
+ float[] kernel = EffectUtils.createGaussianKernel(size);
+ EffectUtils.blur(tmpBuf1, tmpBuf2, tmpW, tmpH, kernel, size); // horizontal pass
+ EffectUtils.blur(tmpBuf2, tmpBuf1, tmpH, tmpW, kernel, size);// vertical pass
+ //rescale
+ float spread = Math.min(1 / (1 - (0.01f * this.spread)), 255);
+ for (int i = 0; i < tmpBuf1.length; i++) {
+ int val = (int) (((int) tmpBuf1[i] & 0xFF) * spread);
+ tmpBuf1[i] = (val > 255) ? (byte) 0xFF : (byte) val;
+ }
+ // create color image with shadow color and greyscale image as alpha
+ if (dst == null) dst = new BufferedImage(w, h,
+ BufferedImage.TYPE_INT_ARGB);
+ WritableRaster shadowRaster = dst.getRaster();
+ int red = color.getRed(), green = color.getGreen(), blue = color.getBlue();
+ for (int y = 0; y < h; y++) {
+ int srcY = y + tmpOffY;
+ int shadowOffset = (srcY - offsetY) * tmpW;
+ for (int x = 0; x < w; x++) {
+ int srcX = x + tmpOffX;
+ lineBuf[x] = tmpBuf1[shadowOffset + (srcX - offsetX)] << 24 | red << 16 | green << 8 | blue;
+ }
+ shadowRaster.setDataElements(0, y, w, 1, lineBuf);
+ }
+ return dst;
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/Effect.java b/src/share/classes/javax/swing/plaf/nimbus/Effect.java
new file mode 100644
index 0000000000000000000000000000000000000000..8588ef81b5d74043c64ec3513391387ecdea1410
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/Effect.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import sun.awt.AppContext;
+
+import java.awt.image.BufferedImage;
+import java.lang.ref.SoftReference;
+
+/**
+ * Effect
+ *
+ * @author Created by Jasper Potts (Jun 18, 2007)
+ */
+abstract class Effect {
+ enum EffectType {
+ UNDER, BLENDED, OVER
+ }
+
+ // =================================================================================================================
+ // Abstract Methods
+
+ /**
+ * Get the type of this effect, one of UNDER,BLENDED,OVER. UNDER means the result of apply effect should be painted
+ * under the src image. BLENDED means the result of apply sffect contains a modified src image so just it should be
+ * painted. OVER means the result of apply effect should be painted over the src image.
+ *
+ * @return The effect type
+ */
+ abstract EffectType getEffectType();
+
+ /**
+ * Get the opacity to use to paint the result effected image if the EffectType is UNDER or OVER.
+ *
+ * @return The opactity for the effect, 0.0f -> 1.0f
+ */
+ abstract float getOpacity();
+
+ /**
+ * Apply the effect to the src image generating the result . The result image may or may not contain the source
+ * image depending on what the effect type is.
+ *
+ * @param src The source image for applying the effect to
+ * @param dst The dstination image to paint effect result into. If this is null then a new image will be created
+ * @param w The width of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @param h The height of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @return The result of appl
+ */
+ abstract BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h);
+
+ // =================================================================================================================
+ // Static data cache
+
+ protected static ArrayCache getArrayCache() {
+ ArrayCache cache = (ArrayCache)AppContext.getAppContext().get(ArrayCache.class);
+ if (cache == null){
+ cache = new ArrayCache();
+ AppContext.getAppContext().put(ArrayCache.class,cache);
+ }
+ return cache;
+ }
+
+ protected static class ArrayCache {
+ private SoftReferenceBufferedImage
. The pixels are grabbed from
+ * a rectangular area defined by a location and two dimensions. Calling this method on an image of type different
+ * from BufferedImage.TYPE_INT_ARGB
and BufferedImage.TYPE_INT_RGB
will unmanage the
+ * image.pixels
if non-null, a new array of integers otherwise
+ * @throws IllegalArgumentException is pixels
is non-null and of length < w*h
+ */
+ static byte[] getPixels(BufferedImage img,
+ int x, int y, int w, int h, byte[] pixels) {
+ if (w == 0 || h == 0) {
+ return new byte[0];
+ }
+
+ if (pixels == null) {
+ pixels = new byte[w * h];
+ } else if (pixels.length < w * h) {
+ throw new IllegalArgumentException("pixels array must have a length >= w*h");
+ }
+
+ int imageType = img.getType();
+ if (imageType == BufferedImage.TYPE_BYTE_GRAY) {
+ Raster raster = img.getRaster();
+ return (byte[]) raster.getDataElements(x, y, w, h, pixels);
+ } else {
+ throw new IllegalArgumentException("Only type BYTE_GRAY is supported");
+ }
+ }
+
+ /**
+ * BufferedImage
. Calling this method on an
+ * image of type different from BufferedImage.TYPE_INT_ARGB
and BufferedImage.TYPE_INT_RGB
+ * will unmanage the image.pixels
is non-null and of length < w*h
+ */
+ static void setPixels(BufferedImage img,
+ int x, int y, int w, int h, byte[] pixels) {
+ if (pixels == null || w == 0 || h == 0) {
+ return;
+ } else if (pixels.length < w * h) {
+ throw new IllegalArgumentException("pixels array must have a length >= w*h");
+ }
+ int imageType = img.getType();
+ if (imageType == BufferedImage.TYPE_BYTE_GRAY) {
+ WritableRaster raster = img.getRaster();
+ raster.setDataElements(x, y, w, h, pixels);
+ } else {
+ throw new IllegalArgumentException("Only type BYTE_GRAY is supported");
+ }
+ }
+
+ /**
+ * BufferedImage
. The pixels are grabbed from a rectangular
+ * area defined by a location and two dimensions. Calling this method on
+ * an image of type different from BufferedImage.TYPE_INT_ARGB
+ * and BufferedImage.TYPE_INT_RGB
will unmanage the image.pixels
if non-null, a new array of integers
+ * otherwise
+ * @throws IllegalArgumentException is pixels
is non-null and
+ * of length < w*h
+ */
+ public static int[] getPixels(BufferedImage img,
+ int x, int y, int w, int h, int[] pixels) {
+ if (w == 0 || h == 0) {
+ return new int[0];
+ }
+
+ if (pixels == null) {
+ pixels = new int[w * h];
+ } else if (pixels.length < w * h) {
+ throw new IllegalArgumentException("pixels array must have a length" +
+ " >= w*h");
+ }
+
+ int imageType = img.getType();
+ if (imageType == BufferedImage.TYPE_INT_ARGB ||
+ imageType == BufferedImage.TYPE_INT_RGB) {
+ Raster raster = img.getRaster();
+ return (int[]) raster.getDataElements(x, y, w, h, pixels);
+ }
+
+ // Unmanages the image
+ return img.getRGB(x, y, w, h, pixels, 0, w);
+ }
+
+ /**
+ * BufferedImage
. Calling this method on
+ * an image of type different from BufferedImage.TYPE_INT_ARGB
+ * and BufferedImage.TYPE_INT_RGB
will unmanage the image.pixels
is non-null and
+ * of length < w*h
+ */
+ public static void setPixels(BufferedImage img,
+ int x, int y, int w, int h, int[] pixels) {
+ if (pixels == null || w == 0 || h == 0) {
+ return;
+ } else if (pixels.length < w * h) {
+ throw new IllegalArgumentException("pixels array must have a length" +
+ " >= w*h");
+ }
+
+ int imageType = img.getType();
+ if (imageType == BufferedImage.TYPE_INT_ARGB ||
+ imageType == BufferedImage.TYPE_INT_RGB) {
+ WritableRaster raster = img.getRaster();
+ raster.setDataElements(x, y, w, h, pixels);
+ } else {
+ // Unmanages the image
+ img.setRGB(x, y, w, h, pixels, 0, w);
+ }
+ }
+
+ /**
+ * BufferedImage
using the same color model
+ * as the image passed as a parameter. The returned image is only compatible
+ * with the image passed as a parameter. This does not mean the returned
+ * image is compatible with the hardware.BufferedImage
, compatible with the color model
+ * of image
+ */
+ public static BufferedImage createColorModelCompatibleImage(BufferedImage image) {
+ ColorModel cm = image.getColorModel();
+ return new BufferedImage(cm,
+ cm.createCompatibleWritableRaster(image.getWidth(),
+ image.getHeight()),
+ cm.isAlphaPremultiplied(), null);
+ }
+
+ /**
+ * BufferedImage
is compatible with
+ * the graphics hardware. If the method is called in a headless
+ * environment, then the returned BufferedImage will be compatible with
+ * the source image.BufferedImage
of the
+ * specified width and height
+ */
+ public static BufferedImage createCompatibleTranslucentImage(int width,
+ int height) {
+ return isHeadless() ?
+ new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) :
+ getGraphicsConfiguration().createCompatibleImage(width, height,
+ Transparency.TRANSLUCENT);
+ }
+
+ private static boolean isHeadless() {
+ return GraphicsEnvironment.isHeadless();
+ }
+
+ // Returns the graphics configuration for the primary screen
+ private static GraphicsConfiguration getGraphicsConfiguration() {
+ return GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration();
+ }
+
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/ImageCache.java b/src/share/classes/javax/swing/plaf/nimbus/ImageCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..abd345820b7d26f4b2ebf2af93405cc2c927da90
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/ImageCache.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * ImageCache - A fixed pixel count sized cache of Images keyed by arbitrary set of arguments. All images are held with
+ * SoftReferences so they will be dropped by the GC if heap memory gets tight. When our size hits max pixel count least
+ * recently requested images are removed first.
+ *
+ * @author Created by Jasper Potts (Aug 7, 2007)
+ */
+class ImageCache {
+ // Ordered Map keyed by args hash, ordered by most recent accessed entry.
+ private final LinkedHashMapmask
+ * is ignored.
+ */
+ CENTER,
+
+ /**
+ * Painting type indicating the image should be tiled across the specified width and height. When used the
+ * mask
is ignored.
+ */
+ TILE,
+
+ /**
+ * Painting type indicating the image should be split into nine regions with the top, left, bottom and right
+ * areas stretched.
+ */
+ PAINT9_STRETCH,
+
+ /**
+ * Painting type indicating the image should be split into nine regions with the top, left, bottom and right
+ * areas tiled.
+ */
+ PAINT9_TILE
+ }
+
+ ;
+
+ private static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
+
+ static final int PAINT_TOP_LEFT = 1;
+ static final int PAINT_TOP = 2;
+ static final int PAINT_TOP_RIGHT = 4;
+ static final int PAINT_LEFT = 8;
+ static final int PAINT_CENTER = 16;
+ static final int PAINT_RIGHT = 32;
+ static final int PAINT_BOTTOM_RIGHT = 64;
+ static final int PAINT_BOTTOM = 128;
+ static final int PAINT_BOTTOM_LEFT = 256;
+ /**
+ * Specifies that all regions should be painted. If this is set any other regions specified will not be painted.
+ * For example PAINT_ALL | PAINT_CENTER will paint all but the center.
+ */
+ static final int PAINT_ALL = 512;
+
+ /**
+ * Paints using the algorightm specified by paintType
.
+ *
+ * @param g Graphics to render to
+ * @param x X-coordinate
+ * @param y Y-coordinate
+ * @param w Width to render to
+ * @param h Height to render to
+ * @param image Image to render from, if null
this method will do nothing
+ * @param sInsets Insets specifying the portion of the image that will be stretched or tiled, if null
+ * empty Insets
will be used.
+ * @param dInsets Destination insets specifying the portion of the image will be stretched or tiled, if
+ * null
empty Insets
will be used.
+ * @param paintType Specifies what type of algorithm to use in painting
+ * @param mask Specifies portion of image to render, if PAINT_ALL
is specified, any other regions
+ * specified will not be painted, for example PAINT_ALL | PAINT_CENTER paints everything but the
+ * center.
+ */
+ public static void paint(Graphics g, int x, int y, int w, int h,
+ Image image, Insets sInsets,
+ Insets dInsets, PaintType paintType, int mask) {
+ if (image == null || image.getWidth(null) <= 0 || image.getHeight(null) <= 0) {
+ return;
+ }
+ if (sInsets == null) {
+ sInsets = EMPTY_INSETS;
+ }
+ if (dInsets == null) {
+ dInsets = EMPTY_INSETS;
+ }
+ int iw = image.getWidth(null);
+ int ih = image.getHeight(null);
+
+ if (paintType == PaintType.CENTER) {
+ // Center the image
+ g.drawImage(image, x + (w - iw) / 2,
+ y + (h - ih) / 2, null);
+ } else if (paintType == PaintType.TILE) {
+ // Tile the image
+ int lastIY = 0;
+ for (int yCounter = y, maxY = y + h; yCounter < maxY;
+ yCounter += (ih - lastIY), lastIY = 0) {
+ int lastIX = 0;
+ for (int xCounter = x, maxX = x + w; xCounter < maxX;
+ xCounter += (iw - lastIX), lastIX = 0) {
+ int dx2 = Math.min(maxX, xCounter + iw - lastIX);
+ int dy2 = Math.min(maxY, yCounter + ih - lastIY);
+ g.drawImage(image, xCounter, yCounter, dx2, dy2,
+ lastIX, lastIY, lastIX + dx2 - xCounter,
+ lastIY + dy2 - yCounter, null);
+ }
+ }
+ } else {
+ int st = sInsets.top;
+ int sl = sInsets.left;
+ int sb = sInsets.bottom;
+ int sr = sInsets.right;
+
+ int dt = dInsets.top;
+ int dl = dInsets.left;
+ int db = dInsets.bottom;
+ int dr = dInsets.right;
+
+ // Constrain the insets to the size of the image
+ if (st + sb > ih) {
+ db = dt = sb = st = Math.max(0, ih / 2);
+ }
+ if (sl + sr > iw) {
+ dl = dr = sl = sr = Math.max(0, iw / 2);
+ }
+
+ // Constrain the insets to the size of the region we're painting
+ // in.
+ if (dt + db > h) {
+ dt = db = Math.max(0, h / 2 - 1);
+ }
+ if (dl + dr > w) {
+ dl = dr = Math.max(0, w / 2 - 1);
+ }
+
+ boolean stretch = (paintType == PaintType.PAINT9_STRETCH);
+ if ((mask & PAINT_ALL) != 0) {
+ mask = (PAINT_ALL - 1) & ~mask;
+ }
+
+ if ((mask & PAINT_LEFT) != 0) {
+ drawChunk(image, g, stretch, x, y + dt, x + dl, y + h - db,
+ 0, st, sl, ih - sb, false);
+ }
+ if ((mask & PAINT_TOP_LEFT) != 0) {
+ drawImage(image, g, x, y, x + dl, y + dt,
+ 0, 0, sl, st);
+ }
+ if ((mask & PAINT_TOP) != 0) {
+ drawChunk(image, g, stretch, x + dl, y, x + w - dr, y + dt,
+ sl, 0, iw - sr, st, true);
+ }
+ if ((mask & PAINT_TOP_RIGHT) != 0) {
+ drawImage(image, g, x + w - dr, y, x + w, y + dt,
+ iw - sr, 0, iw, st);
+ }
+ if ((mask & PAINT_RIGHT) != 0) {
+ drawChunk(image, g, stretch,
+ x + w - dr, y + dt, x + w, y + h - db,
+ iw - sr, st, iw, ih - sb, false);
+ }
+ if ((mask & PAINT_BOTTOM_RIGHT) != 0) {
+ drawImage(image, g, x + w - dr, y + h - db, x + w, y + h,
+ iw - sr, ih - sb, iw, ih);
+ }
+ if ((mask & PAINT_BOTTOM) != 0) {
+ drawChunk(image, g, stretch,
+ x + dl, y + h - db, x + w - dr, y + h,
+ sl, ih - sb, iw - sr, ih, true);
+ }
+ if ((mask & PAINT_BOTTOM_LEFT) != 0) {
+ drawImage(image, g, x, y + h - db, x + dl, y + h,
+ 0, ih - sb, sl, ih);
+ }
+ if ((mask & PAINT_CENTER) != 0) {
+ drawImage(image, g, x + dl, y + dt, x + w - dr, y + h - db,
+ sl, st, iw - sr, ih - sb);
+ }
+ }
+ }
+
+ /**
+ * Draws a portion of an image, stretched or tiled.
+ *
+ * @param image Image to render.
+ * @param g Graphics to render to
+ * @param stretch Whether the image should be stretched or timed in the
+ * provided space.
+ * @param dx1 X origin to draw to
+ * @param dy1 Y origin to draw to
+ * @param dx2 End x location to draw to
+ * @param dy2 End y location to draw to
+ * @param sx1 X origin to draw from
+ * @param sy1 Y origin to draw from
+ * @param sx2 Max x location to draw from
+ * @param sy2 Max y location to draw from
+ * @param xDirection Used if the image is not stretched. If true it
+ * indicates the image should be tiled along the x axis.
+ */
+ private static void drawChunk(Image image, Graphics g, boolean stretch,
+ int dx1, int dy1, int dx2, int dy2, int sx1,
+ int sy1, int sx2, int sy2,
+ boolean xDirection) {
+ if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
+ sy2 - sy1 <= 0) {
+ // Bogus location, nothing to paint
+ return;
+ }
+ if (stretch) {
+ g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
+ }
+ else {
+ int xSize = sx2 - sx1;
+ int ySize = sy2 - sy1;
+ int deltaX;
+ int deltaY;
+
+ if (xDirection) {
+ deltaX = xSize;
+ deltaY = 0;
+ }
+ else {
+ deltaX = 0;
+ deltaY = ySize;
+ }
+ while (dx1 < dx2 && dy1 < dy2) {
+ int newDX2 = Math.min(dx2, dx1 + xSize);
+ int newDY2 = Math.min(dy2, dy1 + ySize);
+
+ g.drawImage(image, dx1, dy1, newDX2, newDY2,
+ sx1, sy1, sx1 + newDX2 - dx1,
+ sy1 + newDY2 - dy1, null);
+ dx1 += deltaX;
+ dy1 += deltaY;
+ }
+ }
+ }
+
+ private static void drawImage(Image image, Graphics g,
+ int dx1, int dy1, int dx2, int dy2, int sx1,
+ int sy1, int sx2, int sy2) {
+ // PENDING: is this necessary, will G2D do it for me?
+ if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
+ sy2 - sy1 <= 0) {
+ // Bogus location, nothing to paint
+ return;
+ }
+ g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
+ }
+
+
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/InnerGlowEffect.java b/src/share/classes/javax/swing/plaf/nimbus/InnerGlowEffect.java
new file mode 100644
index 0000000000000000000000000000000000000000..3847c9f27f110e04db4f855e125026d0f5d080f3
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/InnerGlowEffect.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import java.awt.Color;
+
+/**
+ * InnerGlowEffect
+ *
+ * @author Created by Jasper Potts (Jun 21, 2007)
+ */
+class InnerGlowEffect extends InnerShadowEffect {
+ InnerGlowEffect() {
+ distance = 0;
+ color = new Color(255, 255, 211);
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/InnerShadowEffect.java b/src/share/classes/javax/swing/plaf/nimbus/InnerShadowEffect.java
new file mode 100644
index 0000000000000000000000000000000000000000..c578c1e529562cd67aa28d73f9494ab8f7e063c4
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/InnerShadowEffect.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.util.Arrays;
+
+/**
+ * InnerShadowEffect - This effect currently only works with ARGB type buffered
+ * images.
+ *
+ * @author Created by Jasper Potts (Jun 18, 2007)
+ */
+class InnerShadowEffect extends ShadowEffect {
+
+ // =================================================================================================================
+ // Effect Methods
+
+ /**
+ * Get the type of this effect, one of UNDER,BLENDED,OVER. UNDER means the result of apply effect should be painted
+ * under the src image. BLENDED means the result of apply sffect contains a modified src image so just it should be
+ * painted. OVER means the result of apply effect should be painted over the src image.
+ *
+ * @return The effect type
+ */
+ Effect.EffectType getEffectType() {
+ return Effect.EffectType.OVER;
+ }
+
+ /**
+ * Apply the effect to the src image generating the result . The result image may or may not contain the source
+ * image depending on what the effect type is.
+ *
+ * @param src The source image for applying the effect to
+ * @param dst The dstination image to paint effect result into. If this is null then a new image will be created
+ * @param w The width of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @param h The height of the src image to apply effect to, this allow the src and dst buffers to be bigger than
+ * the area the need effect applied to it
+ * @return Image with the result of the effect
+ */
+ BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h) {
+ if (src == null || src.getType() != BufferedImage.TYPE_INT_ARGB){
+ throw new IllegalArgumentException("Effect only works with " +
+ "source images of type BufferedImage.TYPE_INT_ARGB.");
+ }
+ if (dst != null && dst.getType() != BufferedImage.TYPE_INT_ARGB){
+ throw new IllegalArgumentException("Effect only works with " +
+ "destination images of type BufferedImage.TYPE_INT_ARGB.");
+ }
+ // calculate offset
+ double trangleAngle = Math.toRadians(angle - 90);
+ int offsetX = (int) (Math.sin(trangleAngle) * distance);
+ int offsetY = (int) (Math.cos(trangleAngle) * distance);
+ // clac expanded size
+ int tmpOffX = offsetX + size;
+ int tmpOffY = offsetX + size;
+ int tmpW = w + offsetX + size + size;
+ int tmpH = h + offsetX + size;
+ // create tmp buffers
+ int[] lineBuf = getArrayCache().getTmpIntArray(w);
+ byte[] srcAlphaBuf = getArrayCache().getTmpByteArray1(tmpW * tmpH);
+ Arrays.fill(srcAlphaBuf, (byte) 0xFF);
+ byte[] tmpBuf1 = getArrayCache().getTmpByteArray2(tmpW * tmpH);
+ byte[] tmpBuf2 = getArrayCache().getTmpByteArray3(tmpW * tmpH);
+ // extract src image alpha channel and inverse and offset
+ Raster srcRaster = src.getRaster();
+ for (int y = 0; y < h; y++) {
+ int dy = (y + tmpOffY);
+ int offset = dy * tmpW;
+ srcRaster.getDataElements(0, y, w, 1, lineBuf);
+ for (int x = 0; x < w; x++) {
+ int dx = x + tmpOffX;
+ srcAlphaBuf[offset + dx] = (byte) ((255 - ((lineBuf[x] & 0xFF000000) >>> 24)) & 0xFF);
+ }
+ }
+ // blur
+ float[] kernel = EffectUtils.createGaussianKernel(size * 2);
+ EffectUtils.blur(srcAlphaBuf, tmpBuf2, tmpW, tmpH, kernel, size * 2); // horizontal pass
+ EffectUtils.blur(tmpBuf2, tmpBuf1, tmpH, tmpW, kernel, size * 2);// vertical pass
+ //rescale
+ float spread = Math.min(1 / (1 - (0.01f * this.spread)), 255);
+ for (int i = 0; i < tmpBuf1.length; i++) {
+ int val = (int) (((int) tmpBuf1[i] & 0xFF) * spread);
+ tmpBuf1[i] = (val > 255) ? (byte) 0xFF : (byte) val;
+ }
+ // create color image with shadow color and greyscale image as alpha
+ if (dst == null) dst = new BufferedImage(w, h,
+ BufferedImage.TYPE_INT_ARGB);
+ WritableRaster shadowRaster = dst.getRaster();
+ int red = color.getRed(), green = color.getGreen(), blue = color.getBlue();
+ for (int y = 0; y < h; y++) {
+ int srcY = y + tmpOffY;
+ int offset = srcY * tmpW;
+ int shadowOffset = (srcY - offsetY) * tmpW;
+ for (int x = 0; x < w; x++) {
+ int srcX = x + tmpOffX;
+ int origianlAlphaVal = 255 - ((int) srcAlphaBuf[offset + srcX] & 0xFF);
+ int shadowVal = (int) tmpBuf1[shadowOffset + (srcX - offsetX)] & 0xFF;
+ int alphaVal = Math.min(origianlAlphaVal, shadowVal);
+ lineBuf[x] = ((byte) alphaVal & 0xFF) << 24 | red << 16 | green << 8 | blue;
+ }
+ shadowRaster.setDataElements(0, y, w, 1, lineBuf);
+ }
+ return dst;
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/LoweredBorder.java b/src/share/classes/javax/swing/plaf/nimbus/LoweredBorder.java
new file mode 100644
index 0000000000000000000000000000000000000000..99bc834def228d5e5790a32f1d18eea2989a054a
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/LoweredBorder.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import javax.swing.border.Border;
+import javax.swing.JComponent;
+import javax.swing.plaf.UIResource;
+import java.awt.Insets;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.Transparency;
+import java.awt.RenderingHints;
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+
+/**
+ * LoweredBorder - A recessed rounded inner shadowed border. Used as the
+ * standard Nimbus TitledBorder. This class is both a painter and a swing
+ * border.
+ *
+ * @author Jasper Potts
+ */
+class LoweredBorder extends AbstractRegionPainter implements Border {
+ private static final int IMG_SIZE = 30;
+ private static final int RADIUS = 13;
+ private static final Insets INSETS = new Insets(10,10,10,10);
+ private static final PaintContext PAINT_CONTEXT = new PaintContext(INSETS,
+ new Dimension(IMG_SIZE,IMG_SIZE),false,
+ PaintContext.CacheMode.NINE_SQUARE_SCALE,
+ Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ // =========================================================================
+ // Painter Methods
+
+ @Override
+ protected Object[] getExtendedCacheKeys(JComponent c) {
+ return new Object[] {c.getBackground()};
+ }
+
+ /**
+ * Actually performs the painting operation. Subclasses must implement this
+ * method. The graphics object passed may represent the actual surface being
+ * rendererd to, or it may be an intermediate buffer. It has also been
+ * pre-translated. Simply render the component as if it were located at 0, 0
+ * and had a width of width
and a height of
+ * height
. For performance reasons, you may want to read the
+ * clip from the Graphics2D object and only render within that space.
+ *
+ * @param g The Graphics2D surface to paint to
+ * @param c The JComponent related to the drawing event. For example,
+ * if the region being rendered is Button, then c
+ * will be a JButton. If the region being drawn is
+ * ScrollBarSlider, then the component will be JScrollBar.
+ * This value may be null.
+ * @param width The width of the region to paint. Note that in the case of
+ * painting the foreground, this value may differ from
+ * c.getWidth().
+ * @param height The height of the region to paint. Note that in the case of
+ * painting the foreground, this value may differ from
+ * c.getHeight().
+ */
+ protected void doPaint(Graphics2D g, JComponent c, int width, int height,
+ Object[] extendedCacheKeys) {
+ BufferedImage img1 = new BufferedImage(IMG_SIZE,IMG_SIZE,
+ BufferedImage.TYPE_INT_ARGB);
+ BufferedImage img2 = new BufferedImage(IMG_SIZE,IMG_SIZE,
+ BufferedImage.TYPE_INT_ARGB);
+ // draw shadow shape
+ Graphics2D g2 = (Graphics2D)img1.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setColor(c.getBackground());
+ g2.fillRoundRect(2,0,26,26,RADIUS,RADIUS);
+ g2.dispose();
+ // draw shadow
+ InnerShadowEffect effect = new InnerShadowEffect();
+ effect.setDistance(1);
+ effect.setSize(3);
+ effect.setColor(getLighter(c.getBackground(),2.1f));
+ effect.setAngle(90);
+ effect.applyEffect(img1,img2,IMG_SIZE,IMG_SIZE);
+ // draw outline to img2
+ g2 = (Graphics2D)img2.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setClip(0,28,IMG_SIZE,1);
+ g2.setColor(getLighter(c.getBackground(),0.90f));
+ g2.drawRoundRect(2,1,25,25,RADIUS,RADIUS);
+ g2.dispose();
+ // draw final image
+ if (width != IMG_SIZE || height != IMG_SIZE){
+ ImageScalingHelper.paint(g,0,0,width,height,img2, INSETS, INSETS,
+ ImageScalingHelper.PaintType.PAINT9_STRETCH,
+ ImageScalingHelper.PAINT_ALL);
+ } else {
+ g.drawImage(img2,0,0,c);
+ }
+ img1 = null;
+ img2 = null;
+ }
+
+ /**
+ * getStyle
method.prefix
+ *
+ *
+ * laf.register(NimbusFooUI.FOO_REGION, "Foo");
+ *
+ *
+ *
+ * UIManager.put("Foo.background", new ColorUIResource(Color.BLACK));
+ * UIManager.put("Foo.Enabled.backgroundPainter", new FooBackgroundPainter());
+ *
+ *
+ * @param region The Synth Region that is being registered. Such as Button, or
+ * ScrollBarThumb, or NimbusFooUI.FOO_REGION.
+ * @param prefix The UIDefault prefix. For example, could be ComboBox, or if
+ * a named components, "MyComboBox", or even something like
+ * ToolBar."MyComboBox"."ComboBox.arrowButton"
+ */
+ public void register(Region region, String prefix) {
+ defaults.register(region, prefix);
+ }
+
+ /**
+ * Simple utility method that reads system keys.
+ */
+ private String getSystemProperty(String key) {
+ return AccessController.doPrivileged(new GetPropertyAction(key));
+ }
+
+ @Override
+ public Icon getDisabledIcon(JComponent component, Icon icon) {
+ if (icon instanceof SynthIcon) {
+ SynthIcon si = (SynthIcon)icon;
+ BufferedImage img = EffectUtils.createCompatibleTranslucentImage(
+ si.getIconWidth(), si.getIconHeight());
+ Graphics2D gfx = img.createGraphics();
+ si.paintIcon(component, gfx, 0, 0);
+ gfx.dispose();
+ return new ImageIconUIResource(GrayFilter.createDisabledImage(img));
+ } else {
+ return super.getDisabledIcon(component, icon);
+ }
+ }
+
+ /**
+ * Get a derived color, derived colors are shared instances and is color
+ * value will change when its parent UIDefault color changes.
+ *
+ * @param uiDefaultParentName The parent UIDefault key
+ * @param hOffset The hue offset
+ * @param sOffset The saturation offset
+ * @param bOffset The brightness offset
+ * @param aOffset The alpha offset
+ * @param uiResource True if the derived color should be a
+ * UIResource, false if it should not be
+ * @return The stored derived color
+ */
+ public Color getDerivedColor(String uiDefaultParentName,
+ float hOffset, float sOffset,
+ float bOffset, int aOffset,
+ boolean uiResource) {
+ return defaults.getDerivedColor(uiDefaultParentName, hOffset, sOffset,
+ bOffset, aOffset, uiResource);
+ }
+
+ /**
+ * Decodes and returns a color, which is derived from an offset between two
+ * other colors.
+ *
+ * @param color1 The first color
+ * @param color2 The second color
+ * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
+ * color 1 and 1.0 is color 2;
+ * @param uiResource True if the derived color should be a UIResource
+ * @return The derived color
+ */
+ protected final Color getDerivedColor(Color color1, Color color2,
+ float midPoint, boolean uiResource) {
+ int argb = deriveARGB(color1, color2, midPoint);
+ if (uiResource) {
+ return new ColorUIResource(argb);
+ } else {
+ return new Color(argb);
+ }
+ }
+
+ /**
+ * Decodes and returns a color, which is derived from a offset between two
+ * other colors.
+ *
+ * @param color1 The first color
+ * @param color2 The second color
+ * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
+ * color 1 and 1.0 is color 2;
+ * @return The derived color, which will be a UIResource
+ */
+ protected final Color getDerivedColor(Color color1, Color color2,
+ float midPoint) {
+ return getDerivedColor(color1, color2, midPoint, true);
+ }
+
+ /**
+ * Package private method which returns either BorderLayout.NORTH,
+ * BorderLayout.SOUTH, BorderLayout.EAST, or BorderLayout.WEST depending
+ * on the location of the toolbar in its parent. The toolbar might be
+ * in PAGE_START, PAGE_END, CENTER, or some other position, but will be
+ * resolved to either NORTH,SOUTH,EAST, or WEST based on where the toolbar
+ * actually IS, with CENTER being NORTH.
+ *
+ * This code is used to determine where the border line should be drawn
+ * by the custom toolbar states, and also used by NimbusIcon to determine
+ * whether the handle icon needs to be shifted to look correct.
+ *
+ * Toollbars are unfortunately odd in the way these things are handled,
+ * and so this code exists to unify the logic related to toolbars so it can
+ * be shared among the static files such as NimbusIcon and generated files
+ * such as the ToolBar state classes.
+ */
+ static Object resolveToolbarConstraint(JToolBar toolbar) {
+ //NOTE: we don't worry about component orientation or PAGE_END etc
+ //because the BasicToolBarUI always uses an absolute position of
+ //NORTH/SOUTH/EAST/WEST.
+ if (toolbar != null) {
+ Container parent = toolbar.getParent();
+ if (parent != null) {
+ LayoutManager m = parent.getLayout();
+ if (m instanceof BorderLayout) {
+ BorderLayout b = (BorderLayout)m;
+ Object con = b.getConstraints(toolbar);
+ if (con == SOUTH || con == EAST || con == WEST) {
+ return con;
+ }
+ return NORTH;
+ }
+ }
+ }
+ return NORTH;
+ }
+
+ /**
+ * Derives the ARGB value for a color based on an offset between two
+ * other colors.
+ *
+ * @param color1 The first color
+ * @param color2 The second color
+ * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
+ * color 1 and 1.0 is color 2;
+ * @return the ARGB value for a new color based on this derivation
+ */
+ static int deriveARGB(Color color1, Color color2, float midPoint) {
+ int r = color1.getRed() +
+ (int) ((color2.getRed() - color1.getRed()) * midPoint + 0.5f);
+ int g = color1.getGreen() +
+ (int) ((color2.getGreen() - color1.getGreen()) * midPoint +
+ 0.5f);
+ int b = color1.getBlue() +
+ (int) ((color2.getBlue() - color1.getBlue()) * midPoint + 0.5f);
+ int a = color1.getAlpha() +
+ (int) ((color2.getAlpha() - color1.getAlpha()) * midPoint +
+ 0.5f);
+ return ((a & 0xFF) << 24) |
+ ((r & 0xFF) << 16) |
+ ((g & 0xFF) << 8) |
+ (b & 0xFF);
+ }
+
+ /**
+ * Simple Symbolic Link style UIDefalts Property
+ */
+ private class LinkProperty implements UIDefaults.ActiveValue, UIResource{
+ private String dstPropName;
+
+ private LinkProperty(String dstPropName) {
+ this.dstPropName = dstPropName;
+ }
+
+ @Override
+ public Object createValue(UIDefaults table) {
+ return UIManager.get(dstPropName);
+ }
+ }
+
+ /**
+ * Nimbus Property that looks up Nimbus keys for standard key names. For
+ * example "Button.background" --> "Button[Enabled].backgound"
+ */
+ private class NimbusProperty implements UIDefaults.ActiveValue, UIResource {
+ private String prefix;
+ private String state = null;
+ private String suffix;
+ private boolean isFont;
+
+ private NimbusProperty(String prefix, String suffix) {
+ this.prefix = prefix;
+ this.suffix = suffix;
+ isFont = "font".equals(suffix);
+ }
+
+ private NimbusProperty(String prefix, String state, String suffix) {
+ this(prefix,suffix);
+ this.state = state;
+ }
+
+ /**
+ * Creates the value retrieved from the
+ * laf.register(Region.PANEL, "\"MyPanel\"");
+ * UIManager.put("\"MyPanel\".background", new ColorUIResource(Color.RED));
+ *
UIDefaults
table.
+ * The object is created each time it is accessed.
+ *
+ * @param table a UIDefaults
table
+ * @return the created Object
+ */
+ @Override
+ public Object createValue(UIDefaults table) {
+ Object obj = null;
+ // check specified state
+ if (state!=null){
+ obj = uiDefaults.get(prefix+"["+state+"]."+suffix);
+ }
+ // check enabled state
+ if (obj==null){
+ obj = uiDefaults.get(prefix+"[Enabled]."+suffix);
+ }
+ // check for defaults
+ if (obj==null){
+ if (isFont) {
+ obj = uiDefaults.get("defaultFont");
+ } else {
+ obj = uiDefaults.get(suffix);
+ }
+ }
+ return obj;
+ }
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java b/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java
new file mode 100644
index 0000000000000000000000000000000000000000..04efc91cf018f42a67e0cee2bfc7b4a39be2d890
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java
@@ -0,0 +1,1259 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import javax.swing.Painter;
+
+import java.beans.PropertyChangeEvent;
+import javax.swing.JComponent;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ColorUIResource;
+import javax.swing.plaf.synth.ColorType;
+import static javax.swing.plaf.synth.SynthConstants.*;
+import javax.swing.plaf.synth.SynthContext;
+import javax.swing.plaf.synth.SynthPainter;
+import javax.swing.plaf.synth.SynthStyle;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Insets;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import sun.awt.AppContext;
+
+/**
+ *
+ *
+ *
+ * JButton.States = Enabled, Disabled, Toolbar
+ * JButton[Enabled].backgroundPainter = somePainter
+ * JButton[Disabled].background = BLUE
+ * JButton[Toolbar].backgroundPainter = someOtherPaint
+ *
JButton.States
entry lists the states
+ * that the JButton style will support. You then specify the settings for
+ * each state. If you do not specify the JButton.States
entry,
+ * then the standard Synth states will be assumed. If you specify the entry
+ * but the list of states is empty or null, then the standard synth states
+ * will be assumed.null
is returned from
+ * getColorForState, then thereafter the color is not updated for other
+ * states or on LAF changes or updates. This DEFAULT_COLOR is used to
+ * ensure that a ColorUIResource is always returned from
+ * getColorForState.Values
object with the defaults
+ * contained in the given TreeMap.
+ *
+ * @param v The Values object to be initialized
+ * @param myDefaults a map of UIDefaults to use in initializing the Values.
+ * This map must contain only keys associated with this Style.
+ */
+ private void init(Values v, TreeMap
+ *
+ */
+ @Override protected Color getColorForState(SynthContext ctx, ColorType type) {
+ String key = null;
+ if (type == ColorType.BACKGROUND) {
+ key = "background";
+ } else if (type == ColorType.FOREGROUND) {
+ //map FOREGROUND as TEXT_FOREGROUND
+ key = "textForeground";
+ } else if (type == ColorType.TEXT_BACKGROUND) {
+ key = "textBackground";
+ } else if (type == ColorType.TEXT_FOREGROUND) {
+ key = "textForeground";
+ } else if (type == ColorType.FOCUS) {
+ key = "focus";
+ } else if (type != null) {
+ key = type.toString();
+ } else {
+ return DEFAULT_COLOR;
+ }
+ Color c = (Color) get(ctx, key);
+ //if all else fails, return a default color (which is a ColorUIResource)
+ if (c == null) c = DEFAULT_COLOR;
+ return c;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * Overridden to cause this style to populate itself with data from
+ * UIDefaults, if necessary. If a value named "font" is not found in
+ * UIDefaults, then the "defaultFont" font in UIDefaults will be returned
+ * instead.
+ */
+ @Override protected Font getFontForState(SynthContext ctx) {
+ Font f = (Font)get(ctx, "font");
+ if (f == null) f = UIManager.getFont("defaultFont");
+
+ // Account for scale
+ // The key "JComponent.sizeVariant" is used to match Apple's LAF
+ String scaleKey = (String)ctx.getComponent().getClientProperty(
+ "JComponent.sizeVariant");
+ if (scaleKey != null){
+ if (LARGE_KEY.equals(scaleKey)){
+ f = f.deriveFont(Math.round(f.getSize2D()*LARGE_SCALE));
+ } else if (SMALL_KEY.equals(scaleKey)){
+ f = f.deriveFont(Math.round(f.getSize2D()*SMALL_SCALE));
+ } else if (MINI_KEY.equals(scaleKey)){
+ f = f.deriveFont(Math.round(f.getSize2D()*MINI_SCALE));
+ }
+ }
+ return f;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * Returns the SynthPainter for this style, which ends up delegating to
+ * the Painters installed in this style.
+ */
+ @Override public SynthPainter getPainter(SynthContext ctx) {
+ return painter;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * Overridden to cause this style to populate itself with data from
+ * UIDefaults, if necessary. If opacity is not specified in UI defaults,
+ * then it defaults to being non-opaque.
+ */
+ @Override public boolean isOpaque(SynthContext ctx) {
+ // Force Table CellRenderers to be opaque
+ if ("Table.cellRenderer".equals(ctx.getComponent().getName())) {
+ return true;
+ }
+ Boolean opaque = (Boolean)get(ctx, "opaque");
+ return opaque == null ? false : opaque;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ *
+ * background
+ * Button.opacity
+ * Button.Enabled.foreground
+ * Button.Enabled+Selected.background
+ *
In this example, suppose you were in the Enabled+Selected state and + * searched for "foreground". In this case, we first check for + * Button.Enabled+Selected.foreground, but no such color exists. We then + * fall back to the next valid state, in this case, + * Button.Enabled.foreground, and have a match. So we return it.
+ * + *Again, if we were in the state Enabled and looked for "background", we + * wouldn't find it in Button.Enabled, or in Button, but would at the top + * level in UIManager. So we return that value.
+ * + *One special note: the "key" passed to this method could be of the form + * "background" or "Button.background" where "Button" equals the prefix + * passed to the NimbusStyle constructor. In either case, it looks for + * "background".
+ * + * @param ctx + * @param key must not be null + */ + @Override public Object get(SynthContext ctx, Object key) { + Values v = getValues(ctx); + + // strip off the prefix, if there is one. + String fullKey = key.toString(); + String partialKey = fullKey.substring(fullKey.indexOf(".") + 1); + + Object obj = null; + int xstate = getExtendedState(ctx, v); + + // check the cache + tmpKey.init(partialKey, xstate); + obj = v.cache.get(tmpKey); + boolean wasInCache = obj != null; + if (!wasInCache){ + // Search exact matching states and then lesser matching states + RuntimeState s = null; + int[] lastIndex = new int[] {-1}; + while (obj == null && + (s = getNextState(v.states, lastIndex, xstate)) != null) { + obj = s.defaults.get(partialKey); + } + // Search Region Defaults + if (obj == null && v.defaults != null) { + obj = v.defaults.get(partialKey); + } + // return found object + // Search UIManager Defaults + if (obj == null) obj = UIManager.get(fullKey); + // Search Synth Defaults for InputMaps + if (obj == null && partialKey.equals("focusInputMap")) { + obj = super.get(ctx, fullKey); + } + // if all we got was a null, store this fact for later use + v.cache.put(new CacheKey(partialKey, xstate), + obj == null ? NULL : obj); + } + // return found object + return obj == NULL ? null : obj; + } + + /** + * Gets the appropriate background Painter, if there is one, for the state + * specified in the given SynthContext. This method does appropriate + * fallback searching, as described in #get. + * + * @param ctx The SynthContext. Must not be null. + * @return The background painter associated for the given state, or null if + * none could be found. + */ + public Painter getBackgroundPainter(SynthContext ctx) { + Values v = getValues(ctx); + int xstate = getExtendedState(ctx, v); + Painter p = null; + + // check the cache + tmpKey.init("backgroundPainter$$instance", xstate); + p = (Painter)v.cache.get(tmpKey); + if (p != null) return p; + + // not in cache, so lookup and store in cache + RuntimeState s = null; + int[] lastIndex = new int[] {-1}; + while ((s = getNextState(v.states, lastIndex, xstate)) != null) { + if (s.backgroundPainter != null) { + p = s.backgroundPainter; + break; + } + } + if (p == null) p = (Painter)get(ctx, "backgroundPainter"); + if (p != null) { + v.cache.put(new CacheKey("backgroundPainter$$instance", xstate), p); + } + return p; + } + + /** + * Gets the appropriate foreground Painter, if there is one, for the state + * specified in the given SynthContext. This method does appropriate + * fallback searching, as described in #get. + * + * @param ctx The SynthContext. Must not be null. + * @return The foreground painter associated for the given state, or null if + * none could be found. + */ + public Painter getForegroundPainter(SynthContext ctx) { + Values v = getValues(ctx); + int xstate = getExtendedState(ctx, v); + Painter p = null; + + // check the cache + tmpKey.init("foregroundPainter$$instance", xstate); + p = (Painter)v.cache.get(tmpKey); + if (p != null) return p; + + // not in cache, so lookup and store in cache + RuntimeState s = null; + int[] lastIndex = new int[] {-1}; + while ((s = getNextState(v.states, lastIndex, xstate)) != null) { + if (s.foregroundPainter != null) { + p = s.foregroundPainter; + break; + } + } + if (p == null) p = (Painter)get(ctx, "foregroundPainter"); + if (p != null) { + v.cache.put(new CacheKey("foregroundPainter$$instance", xstate), p); + } + return p; + } + + /** + * Gets the appropriate border Painter, if there is one, for the state + * specified in the given SynthContext. This method does appropriate + * fallback searching, as described in #get. + * + * @param ctx The SynthContext. Must not be null. + * @return The border painter associated for the given state, or null if + * none could be found. + */ + public Painter getBorderPainter(SynthContext ctx) { + Values v = getValues(ctx); + int xstate = getExtendedState(ctx, v); + Painter p = null; + + // check the cache + tmpKey.init("borderPainter$$instance", xstate); + p = (Painter)v.cache.get(tmpKey); + if (p != null) return p; + + // not in cache, so lookup and store in cache + RuntimeState s = null; + int[] lastIndex = new int[] {-1}; + while ((s = getNextState(v.states, lastIndex, xstate)) != null) { + if (s.borderPainter != null) { + p = s.borderPainter; + break; + } + } + if (p == null) p = (Painter)get(ctx, "borderPainter"); + if (p != null) { + v.cache.put(new CacheKey("borderPainter$$instance", xstate), p); + } + return p; + } + + /** + * Utility method which returns the proper Values based on the given + * SynthContext. Ensures that parsing of the values has occurred, or + * reoccurs as necessary. + * + * @param ctx The SynthContext + * @return a non-null values reference + */ + private Values getValues(SynthContext ctx) { + validate(); + return values; + } + + /** + * Simple utility method that searchs the given array of Strings for the + * given string. This method is only called from getExtendedState if + * the developer has specified a specific state for the component to be + * in (ie, has "wedged" the component in that state) by specifying + * they client property "Nimbus.State". + * + * @param names a non-null array of strings + * @param name the name to look for in the array + * @return true or false based on whether the given name is in the array + */ + private boolean contains(String[] names, String name) { + assert name != null; + for (int i=0; iIn addition, this method checks the component in the given context + * for a client property called "Nimbus.State". If one exists, then it will + * decompose the String associated with that property to determine what + * state to return. In this way, the developer can force a component to be + * in a specific state, regardless of what the "real" state of the component + * is.
+ * + *The string associated with "Nimbus.State" would be of the form: + *
Enabled+CustomState+MouseOver+ * + * @param ctx + * @param v + * @return + */ + private int getExtendedState(SynthContext ctx, Values v) { + JComponent c = ctx.getComponent(); + int xstate = 0; + int mask = 1; + //check for the Nimbus.State client property + //Performance NOTE: getClientProperty ends up inside a synchronized + //block, so there is some potential for performance issues here, however + //I'm not certain that there is one on a modern VM. + Object property = c.getClientProperty("Nimbus.State"); + if (property != null) { + String stateNames = property.toString(); + String[] states = stateNames.split("\\+"); + if (v.stateTypes == null){ + // standard states only + for (String stateStr : states) { + State.StandardState s = State.getStandardState(stateStr); + if (s != null) xstate |= s.getState(); + } + } else { + // custom states + for (State s : v.stateTypes) { + if (contains(states, s.getName())) { + xstate |= mask; + } + mask <<= 1; + } + } + } else { + //if there are no custom states defined, then simply return the + //state that Synth reported + if (v.stateTypes == null) return ctx.getComponentState(); + + //there are custom states on this values, so I'll have to iterate + //over them all and return a custom extended state + int state = ctx.getComponentState(); + for (State s : v.stateTypes) { + if (s.isInState(c, state)) { + xstate |= mask; + } + mask <<= 1; + } + } + return xstate; + } + + /** + *
Gets the RuntimeState that most closely matches the state in the given + * context, but is less specific than the given "lastState". Essentially, + * this allows you to search for the next best state.
+ * + *For example, if you had the following three states: + *
+ * Enabled + * Enabled+Pressed + * Disabled + *+ * And you wanted to find the state that best represented + * ENABLED+PRESSED+FOCUSED and
lastState
was null (or an
+ * empty array, or an array with a single int with index == -1), then
+ * Enabled+Pressed would be returned. If you then call this method again but
+ * pass the index of Enabled+Pressed as the "lastState", then
+ * Enabled would be returned. If you call this method a third time and pass
+ * the index of Enabled in as the lastState
, then null would be
+ * returned.
+ *
+ * The actual code path for determining the proper state is the same as + * in Synth.
+ * + * @param ctx + * @param lastState a 1 element array, allowing me to do pass-by-reference. + * @return + */ + private RuntimeState getNextState(RuntimeState[] states, + int[] lastState, + int xstate) { + // Use the StateInfo with the most bits that matches that of state. + // If there are none, then fallback to + // the StateInfo with a state of 0, indicating it'll match anything. + + // Consider if we have 3 StateInfos a, b and c with states: + // SELECTED, SELECTED | ENABLED, 0 + // + // Input Return Value + // ----- ------------ + // SELECTED a + // SELECTED | ENABLED b + // MOUSE_OVER c + // SELECTED | ENABLED | FOCUSED b + // ENABLED c + + if (states != null && states.length > 0) { + int bestCount = 0; + int bestIndex = -1; + int wildIndex = -1; + + //if xstate is 0, then search for the runtime state with component + //state of 0. That is, find the exact match and return it. + if (xstate == 0) { + for (int counter = states.length - 1; counter >= 0; counter--) { + if (states[counter].state == 0) { + lastState[0] = counter; + return states[counter]; + } + } + //an exact match couldn't be found, so there was no match. + lastState[0] = -1; + return null; + } + + //xstate is some value != 0 + + //determine from which index to start looking. If lastState[0] is -1 + //then we know to start from the end of the state array. Otherwise, + //we start at the lastIndex - 1. + int lastStateIndex = lastState == null || lastState[0] == -1 ? + states.length : lastState[0]; + + for (int counter = lastStateIndex - 1; counter >= 0; counter--) { + int oState = states[counter].state; + + if (oState == 0) { + if (wildIndex == -1) { + wildIndex = counter; + } + } else if ((xstate & oState) == oState) { + // This is key, we need to make sure all bits of the + // StateInfo match, otherwise a StateInfo with + // SELECTED | ENABLED would match ENABLED, which we + // don't want. + + // This comes from BigInteger.bitCnt + int bitCount = oState; + bitCount -= (0xaaaaaaaa & bitCount) >>> 1; + bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) & + 0x33333333); + bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f; + bitCount += bitCount >>> 8; + bitCount += bitCount >>> 16; + bitCount = bitCount & 0xff; + if (bitCount > bestCount) { + bestIndex = counter; + bestCount = bitCount; + } + } + } + if (bestIndex != -1) { + lastState[0] = bestIndex; + return states[bestIndex]; + } + if (wildIndex != -1) { + lastState[0] = wildIndex; + return states[wildIndex]; + } + } + lastState[0] = -1; + return null; + } + + /** + * Contains values such as the UIDefaults and painters asssociated with + * a state. WhereasState
represents a distinct state that a
+ * component can be in (such as Enabled), this class represents the colors,
+ * fonts, painters, etc associated with some state for this
+ * style.
+ */
+ private final class RuntimeState implements Cloneable {
+ int state;
+ Painter backgroundPainter;
+ Painter foregroundPainter;
+ Painter borderPainter;
+ String stateName;
+ UIDefaults defaults = new UIDefaults(10, .7f);
+
+ private RuntimeState(int state, String stateName) {
+ this.state = state;
+ this.stateName = stateName;
+ }
+
+ @Override
+ public String toString() {
+ return stateName;
+ }
+
+ @Override
+ public RuntimeState clone() {
+ RuntimeState clone = new RuntimeState(state, stateName);
+ clone.backgroundPainter = backgroundPainter;
+ clone.foregroundPainter = foregroundPainter;
+ clone.borderPainter = borderPainter;
+ clone.defaults.putAll(defaults);
+ return clone;
+ }
+ }
+
+ /**
+ * Essentially a struct of data for a style. A default instance of this
+ * class is used by NimbusStyle. Additional instances exist for each
+ * component that has overrides.
+ */
+ private static final class Values {
+ /**
+ * The list of State types. A State represents a type of state, such
+ * as Enabled, Default, WindowFocused, etc. These can be custom states.
+ */
+ State[] stateTypes = null;
+ /**
+ * The list of actual runtime state representations. These can represent things such
+ * as Enabled + Focused. Thus, they differ from States in that they contain
+ * several states together, and have associated properties, data, etc.
+ */
+ RuntimeState[] states = null;
+ /**
+ * The content margins for this region.
+ */
+ Insets contentMargins;
+ /**
+ * Defaults on the region/component level.
+ */
+ UIDefaults defaults = new UIDefaults(10, .7f);
+ /**
+ * Simple cache. After a value has been looked up, it is stored
+ * in this cache for later retrieval. The key is a concatenation of
+ * the property being looked up, two dollar signs, and the extended
+ * state. So for example:
+ *
+ * foo.bar$$2353
+ */
+ MapRepresents a built in, or custom, state in Nimbus.
+ * + *Synth provides several built in states, which are: + *
However, there are many more states that could be described in a LookAndFeel, and it + * would be nice to style components differently based on these different states. + * For example, a progress bar could be "indeterminate". It would be very convenient + * to allow this to be defined as a "state".
+ * + *This class, State, is intended to be used for such situations. + * Simply implement the abstract #isInState method. It returns true if the given + * JComponent is "in this state", false otherwise. This method will be called + * many times in performance sensitive loops. It must execute + * very quickly.
+ * + *For example, the following might be an implementation of a custom + * "Indeterminate" state for JProgressBars:
+ * + *
+ * public final class IndeterminateState extends State<JProgressBar> {
+ * public IndeterminateState() {
+ * super("Indeterminate");
+ * }
+ *
+ * @Override
+ * protected boolean isInState(JProgressBar c) {
+ * return c.isIndeterminate();
+ * }
+ * }
+ *
+ */
+public abstract class StateCreate a new custom State. Specify the name for the state. The name should + * be unique within the states set for any one particular component. + * The name of the state should coincide with the name used in UIDefaults.
+ * + *For example, the following would be correct:
+ *
+ * defaults.put("Button.States", "Enabled, Foo, Disabled");
+ * defaults.put("Button.Foo", new FooState("Foo"));
+ *
+ *
+ * @param name a simple user friendly name for the state, such as "Indeterminate"
+ * or "EmbeddedPanel" or "Blurred". It is customary to use camel case,
+ * with the first letter capitalized.
+ */
+ protected State(String name) {
+ this.name = name;
+ }
+
+ @Override public String toString() { return name; }
+
+ /**
+ * This is the main entry point, called by NimbusStyle.
+ * + *There are both custom states and standard states. Standard states + * correlate to the states defined in SynthConstants. When a UI delegate + * constructs a SynthContext, it specifies the state that the component is + * in according to the states defined in SynthConstants. Our NimbusStyle + * will then take this state, and query each State instance in the style + * asking whether isInState(c, s).
+ * + *Now, only the standard states care about the "s" param. So we have + * this odd arrangement:
+ *Gets whether the specified JComponent is in the custom state represented + * by this class. This is an extremely performance sensitive loop. + * Please take proper precautions to ensure that it executes quickly.
+ * + *Nimbus uses this method to help determine what state a JComponent is
+ * in. For example, a custom State could exist for JProgressBar such that
+ * it would return true
when the progress bar is indeterminate.
+ * Such an implementation of this method would simply be:
return c.isIndeterminate();
+ *
+ * @param c the JComponent to test. This will never be null.
+ * @return true if c
is in the custom state represented by
+ * this State
instance
+ */
+ protected abstract boolean isInState(T c);
+
+ String getName() { return name; }
+
+ static boolean isStandardStateName(String name) {
+ return standardStates.containsKey(name);
+ }
+
+ static StandardState getStandardState(String name) {
+ return standardStates.get(name);
+ }
+
+ static final class StandardState extends StateJScrollBar
.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintArrowButtonBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBackground(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the border of an arrow button. Arrow buttons are created by
+ * some components, such as JScrollBar
.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintArrowButtonBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the foreground of an arrow button. This method is responsible
+ * for drawing a graphical representation of a direction, typically
+ * an arrow. Arrow buttons are created by
+ * some components, such as JScrollBar
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param direction One of SwingConstants.NORTH, SwingConstants.SOUTH
+ * SwingConstants.EAST or SwingConstants.WEST
+ */
+ public void paintArrowButtonForeground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h,
+ int direction) {
+ //assume that the painter is arranged with the arrow pointing... LEFT?
+ String compName = context.getComponent().getName();
+ boolean ltr = context.getComponent().
+ getComponentOrientation().isLeftToRight();
+ // The hard coding for spinners here needs to be replaced by a more
+ // general method for disabling rotation
+ if ("Spinner.nextButton".equals(compName) ||
+ "Spinner.previousButton".equals(compName)) {
+ if (ltr){
+ paintForeground(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(w, 0);
+ transform.scale(-1, 1);
+ paintForeground(context, g, x, y, w, h, transform);
+ }
+ } else if (direction == SwingConstants.WEST) {
+ paintForeground(context, g, x, y, w, h, null);
+ } else if (direction == SwingConstants.NORTH) {
+ if (ltr){
+ AffineTransform transform = new AffineTransform();
+ transform.scale(-1, 1);
+ transform.rotate(Math.toRadians(90));
+ paintForeground(context, g, y, 0, h, w, transform);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.rotate(Math.toRadians(90));
+ transform.translate(0, -(x + w));
+ paintForeground(context, g, y, 0, h, w, transform);
+ }
+ } else if (direction == SwingConstants.EAST) {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(w, 0);
+ transform.scale(-1, 1);
+ paintForeground(context, g, x, y, w, h, transform);
+ } else if (direction == SwingConstants.SOUTH) {
+ if (ltr){
+ AffineTransform transform = new AffineTransform();
+ transform.rotate(Math.toRadians(-90));
+ transform.translate(-h, 0);
+ paintForeground(context, g, y, x, h, w, transform);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.scale(-1, 1);
+ transform.rotate(Math.toRadians(-90));
+ transform.translate(-(h+y), -(w+x));
+ paintForeground(context, g, y, x, h, w, transform);
+ }
+ }
+ }
+
+ /**
+ * Paints the background of a button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintButtonBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintButtonBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a check box menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintCheckBoxMenuItemBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a check box menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintCheckBoxMenuItemBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a check box.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintCheckBoxBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a check box.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintCheckBoxBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a color chooser.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintColorChooserBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a color chooser.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintColorChooserBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a combo box.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintComboBoxBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBackground(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the border of a combo box.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintComboBoxBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a desktop icon.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintDesktopIconBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a desktop icon.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintDesktopIconBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a desktop pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintDesktopPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a desktop pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintDesktopPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of an editor pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintEditorPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of an editor pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintEditorPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a file chooser.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintFileChooserBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a file chooser.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintFileChooserBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a formatted text field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintFormattedTextFieldBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBackground(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the border of a formatted text field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintFormattedTextFieldBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBorder(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBorder(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the background of an internal frame title pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintInternalFrameTitlePaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of an internal frame title pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintInternalFrameTitlePaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of an internal frame.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintInternalFrameBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of an internal frame.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintInternalFrameBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a label.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintLabelBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a label.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintLabelBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a list.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintListBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a list.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintListBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a menu bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a menu bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuItemBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuItemBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a menu.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a menu.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintMenuBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of an option pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintOptionPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of an option pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintOptionPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a panel.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPanelBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a panel.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPanelBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a password field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPasswordFieldBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a password field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPasswordFieldBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a popup menu.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPopupMenuBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a popup menu.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintPopupMenuBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a progress bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintProgressBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a progress bar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation one of JProgressBar.HORIZONTAL
or
+ * JProgressBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintProgressBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of a progress bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintProgressBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a progress bar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation one of JProgressBar.HORIZONTAL
or
+ * JProgressBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintProgressBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the foreground of a progress bar. is responsible for
+ * providing an indication of the progress of the progress bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation one of JProgressBar.HORIZONTAL
or
+ * JProgressBar.VERTICAL
+ */
+ public void paintProgressBarForeground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintForeground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of a radio button menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRadioButtonMenuItemBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a radio button menu item.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRadioButtonMenuItemBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a radio button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRadioButtonBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a radio button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRadioButtonBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a root pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRootPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a root pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintRootPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a scrollbar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a scrollbar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintScrollBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of a scrollbar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a scrollbar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintScrollBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the thumb of a scrollbar. The thumb provides
+ * a graphical indication as to how much of the Component is visible in a
+ * JScrollPane
.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ */
+ public void paintScrollBarThumbBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of the thumb of a scrollbar. The thumb provides
+ * a graphical indication as to how much of the Component is visible in a
+ * JScrollPane
.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ */
+ public void paintScrollBarThumbBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the track of a scrollbar. The track contains
+ * the thumb.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollBarTrackBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the track of a scrollbar. The track contains
+ * the thumb. This implementation invokes the method of the same name without
+ * the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintScrollBarTrackBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of the track of a scrollbar. The track contains
+ * the thumb.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollBarTrackBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the track of a scrollbar. The track contains
+ * the thumb. This implementation invokes the method of the same name without
+ * the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation Orientation of the JScrollBar, one of
+ * JScrollBar.HORIZONTAL
or
+ * JScrollBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintScrollBarTrackBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of a scroll pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a scroll pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintScrollPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a separator.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSeparatorBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a separator. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSeparator.HORIZONTAL
or
+ * JSeparator.VERTICAL
+ * @since 1.6
+ */
+ public void paintSeparatorBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of a separator.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSeparatorBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a separator. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSeparator.HORIZONTAL
or
+ * JSeparator.VERTICAL
+ * @since 1.6
+ */
+ public void paintSeparatorBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the foreground of a separator.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSeparator.HORIZONTAL
or
+ * JSeparator.VERTICAL
+ */
+ public void paintSeparatorForeground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintForeground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSliderBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a slider. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ * @since 1.6
+ */
+ public void paintSliderBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSliderBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a slider. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ * @since 1.6
+ */
+ public void paintSliderBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the thumb of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ */
+ public void paintSliderThumbBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ if (context.getComponent().getClientProperty(
+ "Slider.paintThumbArrowShape") == Boolean.TRUE){
+ if (orientation == JSlider.HORIZONTAL){
+ orientation = JSlider.VERTICAL;
+ } else {
+ orientation = JSlider.HORIZONTAL;
+ }
+ paintBackground(context, g, x, y, w, h, orientation);
+ } else {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+ }
+
+ /**
+ * Paints the border of the thumb of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ */
+ public void paintSliderThumbBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the track of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSliderTrackBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the track of a slider. This implementation invokes
+ * the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ * @since 1.6
+ */
+ public void paintSliderTrackBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of the track of a slider.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSliderTrackBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the track of a slider. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSlider.HORIZONTAL
or
+ * JSlider.VERTICAL
+ * @since 1.6
+ */
+ public void paintSliderTrackBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of a spinner.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSpinnerBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a spinner.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSpinnerBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the divider of a split pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSplitPaneDividerBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the divider of a split pane. This implementation
+ * invokes the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSplitPane.HORIZONTAL_SPLIT
or
+ * JSplitPane.VERTICAL_SPLIT
+ * @since 1.6
+ */
+ public void paintSplitPaneDividerBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ if (orientation == JSplitPane.HORIZONTAL_SPLIT) {
+ AffineTransform transform = new AffineTransform();
+ transform.scale(-1, 1);
+ transform.rotate(Math.toRadians(90));
+ paintBackground(context, g, y, x, h, w, transform);
+ } else {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+ }
+
+ /**
+ * Paints the foreground of the divider of a split pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSplitPane.HORIZONTAL_SPLIT
or
+ * JSplitPane.VERTICAL_SPLIT
+ */
+ public void paintSplitPaneDividerForeground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintForeground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the divider, when the user is dragging the divider, of a
+ * split pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JSplitPane.HORIZONTAL_SPLIT
or
+ * JSplitPane.VERTICAL_SPLIT
+ */
+ public void paintSplitPaneDragDivider(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a split pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSplitPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a split pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintSplitPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the area behind the tabs of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneTabAreaBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the area behind the tabs of a tabbed pane.
+ * This implementation invokes the method of the same name without the
+ * orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JTabbedPane.TOP
,
+ * JTabbedPane.LEFT
,
+ * JTabbedPane.BOTTOM
, or
+ * JTabbedPane.RIGHT
+ * @since 1.6
+ */
+ public void paintTabbedPaneTabAreaBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ if (orientation == JTabbedPane.LEFT) {
+ AffineTransform transform = new AffineTransform();
+ transform.scale(-1, 1);
+ transform.rotate(Math.toRadians(90));
+ paintBackground(context, g, y, x, h, w, transform);
+ } else if (orientation == JTabbedPane.RIGHT) {
+ AffineTransform transform = new AffineTransform();
+ transform.rotate(Math.toRadians(90));
+ transform.translate(0, -(x + w));
+ paintBackground(context, g, y, 0, h, w, transform);
+ } else if (orientation == JTabbedPane.BOTTOM) {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(1, -1);
+ transform.translate(0,-h);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ } else {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+ }
+
+ /**
+ * Paints the border of the area behind the tabs of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneTabAreaBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the area behind the tabs of a tabbed pane. This
+ * implementation invokes the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JTabbedPane.TOP
,
+ * JTabbedPane.LEFT
,
+ * JTabbedPane.BOTTOM
, or
+ * JTabbedPane.RIGHT
+ * @since 1.6
+ */
+ public void paintTabbedPaneTabAreaBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tab of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param tabIndex Index of tab being painted.
+ */
+ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g,
+ int x, int y, int w, int h,
+ int tabIndex) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tab of a tabbed pane. This implementation
+ * invokes the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param tabIndex Index of tab being painted.
+ * @param orientation One of JTabbedPane.TOP
,
+ * JTabbedPane.LEFT
,
+ * JTabbedPane.BOTTOM
, or
+ * JTabbedPane.RIGHT
+ * @since 1.6
+ */
+ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g,
+ int x, int y, int w, int h,
+ int tabIndex, int orientation) {
+ if (orientation == JTabbedPane.LEFT) {
+ AffineTransform transform = new AffineTransform();
+ transform.scale(-1, 1);
+ transform.rotate(Math.toRadians(90));
+ paintBackground(context, g, y, x, h, w, transform);
+ } else if (orientation == JTabbedPane.RIGHT) {
+ AffineTransform transform = new AffineTransform();
+ transform.rotate(Math.toRadians(90));
+ transform.translate(0, -(x + w));
+ paintBackground(context, g, y, 0, h, w, transform);
+ } else if (orientation == JTabbedPane.BOTTOM) {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(1, -1);
+ transform.translate(0,-h);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ } else {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+ }
+
+ /**
+ * Paints the border of a tab of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param tabIndex Index of tab being painted.
+ */
+ public void paintTabbedPaneTabBorder(SynthContext context, Graphics g,
+ int x, int y, int w, int h,
+ int tabIndex) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a tab of a tabbed pane. This implementation invokes
+ * the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param tabIndex Index of tab being painted.
+ * @param orientation One of JTabbedPane.TOP
,
+ * JTabbedPane.LEFT
,
+ * JTabbedPane.BOTTOM
, or
+ * JTabbedPane.RIGHT
+ * @since 1.6
+ */
+ public void paintTabbedPaneTabBorder(SynthContext context, Graphics g,
+ int x, int y, int w, int h,
+ int tabIndex, int orientation) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the area that contains the content of the
+ * selected tab of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneContentBackground(SynthContext context,
+ Graphics g, int x, int y, int w,
+ int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the area that contains the content of the
+ * selected tab of a tabbed pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTabbedPaneContentBorder(SynthContext context, Graphics g,
+ int x, int y, int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the header of a table.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTableHeaderBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the header of a table.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTableHeaderBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a table.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTableBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a table.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTableBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a text area.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextAreaBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a text area.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextAreaBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a text pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextPaneBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a text pane.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextPaneBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a text field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextFieldBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBackground(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBackground(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the border of a text field.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTextFieldBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ if (context.getComponent().getComponentOrientation().isLeftToRight()){
+ paintBorder(context, g, x, y, w, h, null);
+ } else {
+ AffineTransform transform = new AffineTransform();
+ transform.translate(x,y);
+ transform.scale(-1, 1);
+ transform.translate(-w,0);
+ paintBorder(context, g, 0, 0, w, h, transform);
+ }
+ }
+
+ /**
+ * Paints the background of a toggle button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToggleButtonBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a toggle button.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToggleButtonBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tool bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tool bar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of a tool bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a tool bar. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the tool bar's content area.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarContentBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the tool bar's content area. This implementation
+ * invokes the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarContentBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of the content area of a tool bar.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarContentBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the content area of a tool bar. This implementation
+ * invokes the method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarContentBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of the window containing the tool bar when it
+ * has been detached from its primary frame.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarDragWindowBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the window containing the tool bar when it
+ * has been detached from its primary frame. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarDragWindowBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBackground(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the border of the window containing the tool bar when it
+ * has been detached from it's primary frame.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolBarDragWindowBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the window containing the tool bar when it
+ * has been detached from it's primary frame. This implementation invokes the
+ * method of the same name without the orientation.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ * @param orientation One of JToolBar.HORIZONTAL
or
+ * JToolBar.VERTICAL
+ * @since 1.6
+ */
+ public void paintToolBarDragWindowBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h, int orientation) {
+ paintBorder(context, g, x, y, w, h, orientation);
+ }
+
+ /**
+ * Paints the background of a tool tip.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolTipBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a tool tip.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintToolTipBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of a tree.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTreeBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a tree.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTreeBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the background of the row containing a cell in a tree.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTreeCellBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of the row containing a cell in a tree.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTreeCellBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the focus indicator for a cell in a tree when it has focus.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintTreeCellFocus(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ //TODO
+ }
+
+ /**
+ * Paints the background of the viewport.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintViewportBackground(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBackground(context, g, x, y, w, h, null);
+ }
+
+ /**
+ * Paints the border of a viewport.
+ *
+ * @param context SynthContext identifying the JComponent
and
+ * Region
to paint to
+ * @param g Graphics
to paint to
+ * @param x X coordinate of the area to paint to
+ * @param y Y coordinate of the area to paint to
+ * @param w Width of the area to paint to
+ * @param h Height of the area to paint to
+ */
+ public void paintViewportBorder(SynthContext context,
+ Graphics g, int x, int y,
+ int w, int h) {
+ paintBorder(context, g, x, y, w, h, null);
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/TableScrollPaneCorner.java b/src/share/classes/javax/swing/plaf/nimbus/TableScrollPaneCorner.java
new file mode 100644
index 0000000000000000000000000000000000000000..367fbff9b3863c0d88ef12a7b6bdae4c6e6fd50e
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/TableScrollPaneCorner.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package javax.swing.plaf.nimbus;
+
+import javax.swing.Painter;
+
+import javax.swing.JComponent;
+import javax.swing.UIManager;
+import javax.swing.plaf.UIResource;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+
+/**
+ * TableScrollPaneCorner - A simple component that paints itself using the table
+ * header background painter. It is used to fill the top right corner of
+ * scrollpane.
+ *
+ * @author Created by Jasper Potts (Jan 28, 2008)
+ */
+class TableScrollPaneCorner extends JComponent implements UIResource{
+
+ /**
+ * Paint the component using the Nimbus Table Header Background Painter
+ */
+ @Override protected void paintComponent(Graphics g) {
+ Painter painter = (Painter) UIManager.get(
+ "TableHeader:\"TableHeader.renderer\"[Enabled].backgroundPainter");
+ if (painter != null){
+ if (g instanceof Graphics2D){
+ painter.paint((Graphics2D)g,this,getWidth()+1,getHeight());
+ } else {
+ // paint using image to not Graphics2D to support
+ // Java 1.1 printing API
+ BufferedImage img = new BufferedImage(getWidth(),getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D)img.getGraphics();
+ painter.paint(g2,this,getWidth()+1,getHeight());
+ g2.dispose();
+ g.drawImage(img,0,0,null);
+ img = null;
+ }
+ }
+ }
+}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/ToolBarSeparatorPainter.java b/src/share/classes/javax/swing/plaf/nimbus/ToolBarSeparatorPainter.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ea45e16b029d5d67e5cfe76e86768de3e04014f
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/ToolBarSeparatorPainter.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.swing.plaf.nimbus;
+
+import javax.swing.plaf.nimbus.AbstractRegionPainter.PaintContext.CacheMode;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import javax.swing.JComponent;
+
+/**
+ * A special painter implementation for tool bar separators in Nimbus.
+ * The designer tool doesn't have support for painters which render
+ * repeated patterns, but that's exactly what the toolbar separator design
+ * is for Nimbus. This custom painter is designed to handle this situation.
+ * When support is added to the design tool / code generator to deal with
+ * repeated patterns, then we can remove this class.
+ * + */ +final class ToolBarSeparatorPainter extends AbstractRegionPainter { + private static final int SPACE = 3; + private static final int INSET = 2; + + @Override + protected PaintContext getPaintContext() { + //the paint context returned will have a few dummy values. The + //implementation of doPaint doesn't bother with the "decode" methods + //but calculates where to paint the circles manually. As such, we + //only need to indicate in our PaintContext that we don't want this + //to ever be cached + return new PaintContext( + new Insets(1, 0, 1, 0), + new Dimension(38, 7), + false, CacheMode.NO_CACHING, 1, 1); + } + + @Override + protected void doPaint(Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys) { + //it is assumed that in the normal orientation the separator renders + //horizontally. Other code rotates it as necessary for a vertical + //separator. + g.setColor(c.getForeground()); + int y = height / 2; + for (int i=INSET; i<=width-INSET; i+=SPACE) { + g.fillRect(i, y, 1, 1); + } + } +} diff --git a/src/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html b/src/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html new file mode 100644 index 0000000000000000000000000000000000000000..1e170c4d3209206a223a7320b111a0553eb6ef5b --- /dev/null +++ b/src/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html @@ -0,0 +1,207 @@ + +
+ + + +Key | Value | Preview |
---|---|---|
control |
+#d6d9df (214,217,223) |
+
++ |
info |
+#f2f2bd (242,242,189) |
++ |
nimbusAlertYellow |
+#ffdc23 (255,220,35) |
++ |
nimbusBase |
+#33628c (51,98,140) |
++ |
nimbusDisabledText |
+#8e8f91 (142,143,145) |
++ |
nimbusFocus |
+#73a4d1 (115,164,209) |
+
++ |
nimbusGreen |
+#b0b332 (176,179,50) |
++ |
nimbusInfoBlue |
+#2f5cb4 (47,92,180) |
++ |
nimbusLightBackground |
+#ffffff (255,255,255) |
++ |
nimbusOrange |
+#bf6204 (191,98,4) |
++ |
nimbusRed |
+#a92e22 (169,46,34) |
+
++ |
nimbusSelectedText |
+#ffffff (255,255,255) |
++ |
nimbusSelectionBackground |
+#39698a (57,105,138) |
++ |
text |
+#000000 (0,0,0) |
++ |
Key | Value | Preview |
---|---|---|
activeCaption |
+
+#babec6 (186,190,198) |
++ |
background |
+#d6d9df (214,217,223) |
++ |
controlDkShadow |
+#a4abb8 (164,171,184) |
++ + |
controlHighlight |
+#e9ecf2 (233,236,242) |
++ |
controlLHighlight |
+#f7f8fa (247,248,250) |
++ |
controlShadow |
+
+#ccd3e0 (204,211,224) |
++ |
controlText |
+#000000 (0,0,0) |
++ |
desktop |
+#3d6079 (61,96,121) |
++ + |
inactiveCaption |
+#bdc1c8 (189,193,200) |
++ |
infoText |
+#000000 (0,0,0) |
++ |
menu |
+
+#edeff2 (237,239,242) |
++ |
menuText |
+#000000 (0,0,0) |
++ |
nimbusBlueGrey |
+#a9b0be (169,176,190) |
++ + |
nimbusBorder |
+#9297a1 (146,151,161) |
++ |
nimbusSelection |
+#39698a (57,105,138) |
++ |
scrollbar |
+
+#cdd0d5 (205,208,213) |
++ |
textBackground |
+#39698a (57,105,138) |
++ |
textForeground |
+#000000 (0,0,0) |
++ + |
textHighlight |
+#39698a (57,105,138) |
++ |
textHighlightText |
+#ffffff (255,255,255) |
++ |
textInactiveText |
+
+#8e8f91 (142,143,145) |
++ |
Nimbus uses instances of the {@link javax.swing.Painter} interface to paint +components. With each Swing component it associates a foreground and a +background {@code Painter}, and there may be several painters for different +component states. + +
Nimbus allows customizing many of its properties, including painters, by
+altering the {@link UIDefaults} table. Here's an example:
+
+
+
+ UIManager.put("ProgressBar.tileWidth", myTileWidth);
+ UIManager.put("ProgressBar[Enabled].backgroundPainter", myBgPainter);
+ UIManager.put("ProgressBar[Enabled].foregroundPainter", myFgPainter);
+
Per-component customization is also possible. When rendering a component,
+Nimbus checks its client property named "Nimbus.Overrides". The value of this
+property should be an instance of {@code UIDefaults}. Settings from that table
+override the UIManager settings, but for that particular component instance
+only. An optional client property, "Nimbus.Overrides.InheritDefaults" of type
+Boolean, specifies whether the overriding settings should be merged with
+default ones ({@code true}), or replace them ({@code false}). By default they
+are merged:
+
+
+
+ JProgressBar bar = new JProgressBar();
+ UIDefaults overrides = new UIDefaults();
+ overrides.put("ProgressBar.cycleTime", 330);
+ ...
+ bar.putClientProperty("Nimbus.Overrides", overrides);
+ bar.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
+
Colors in Nimbus are derived from a core set of +primary colors. There are also +secondary colors, which are +derived from primary ones, but serve themselves as base colors for other +derived colors. The derivation mechanism allows for runtime customization, +i.e. if a primary or secondary color is changed, all colors that are derived +from it are automatically updated. The method +{@link javax.swing.plaf.nimbus.NimbusLookAndFeel#getDerivedColor(java.lang.String, float, float, float, int, boolean)} +may be used to create a derived color. + +
These classes are designed to be used while the
+corresponding LookAndFeel
class has been
+installed
+(UIManager.setLookAndFeel(new XXXLookAndFeel())
).
+Using them while a different LookAndFeel
is installed
+may produce unexpected results, including exceptions.
+Additionally, changing the LookAndFeel
+maintained by the UIManager
without updating the
+corresponding ComponentUI
of any
+JComponent
s may also produce unexpected results,
+such as the wrong colors showing up, and is generally not
+encouraged.
+
+
Note:
+Most of the Swing API is not thread safe.
+For details, see
+Threads and Swing,
+a section in
+The Java Tutorial.
+
+@since 1.7
+@serial exclude
+
+
+
diff --git a/src/share/classes/javax/swing/plaf/nimbus/skin.laf b/src/share/classes/javax/swing/plaf/nimbus/skin.laf
new file mode 100644
index 0000000000000000000000000000000000000000..ac2867b59994b72eb11949129d577f21ca79a93c
--- /dev/null
+++ b/src/share/classes/javax/swing/plaf/nimbus/skin.laf
@@ -0,0 +1,28332 @@
+
+
+
+
+
Updates the internal "pressed" state. If shouldActLikeButton() + * is true, and if this method call will change the internal state, + * then the combo and button will be repainted.
+ * + *Note that this method is called either when a press event + * occurs on the combo box, or on the arrow button.
+ */ + private void updatePressed(boolean p) { + this.pressed = p && isEnabled(); + if (shouldActLikeButton()) { + comboBox.repaint(); + } + } + + /** + *Updates the internal "over" state. If shouldActLikeButton() + * is true, and if this method call will change the internal state, + * then the combo and button will be repainted.
+ * + *Note that this method is called either when a mouseover/mouseoff event + * occurs on the combo box, or on the arrow button.
+ */ + private void updateOver(boolean o) { + boolean old = isRollover(); + this.over = o && isEnabled(); + boolean newo = isRollover(); + if (shouldActLikeButton() && old != newo) { + comboBox.repaint(); + } + } + + //------------------------------------------------------------------ + // DefaultButtonModel Methods + //------------------------------------------------------------------ + + /** + * {@inheritDoc} + * + * Ensures that isPressed() will return true if the combo is pressed, + * or the arrowButton is pressed, or if the combo popup is + * visible. This is the case because a combo box looks pressed when + * the popup is visible, and so should the arrow button. + */ + @Override + public boolean isPressed() { + boolean b = shouldActLikeButton() ? pressed : super.isPressed(); + return b || (pressedWhenPopupVisible && comboBox.isPopupVisible()); + } + + /** + * {@inheritDoc} + * + * Ensures that the armed state is in sync with the pressed state + * if shouldActLikeButton is true. Without this method, the arrow + * button will not look pressed when the popup is open, regardless + * of the result of isPressed() alone. + */ + @Override + public boolean isArmed() { + boolean b = shouldActLikeButton() || + (pressedWhenPopupVisible && comboBox.isPopupVisible()); + return b ? isPressed() : super.isArmed(); + } + + /** + * {@inheritDoc} + * + * Ensures that isRollover() will return true if the combo is + * rolled over, or the arrowButton is rolled over. + */ + @Override + public boolean isRollover() { + return shouldActLikeButton() ? over : super.isRollover(); + } + + /** + * {@inheritDoc} + * + * Forwards pressed states to the internal "pressed" field + */ + @Override + public void setPressed(boolean b) { + super.setPressed(b); + updatePressed(b); + } + + /** + * {@inheritDoc} + * + * Forwards rollover states to the internal "over" field + */ + @Override + public void setRollover(boolean b) { + super.setRollover(b); + updateOver(b); + } + + //------------------------------------------------------------------ + // MouseListener/MouseMotionListener Methods + //------------------------------------------------------------------ + + @Override + public void mouseEntered(MouseEvent mouseEvent) { + updateOver(true); + } + + @Override + public void mouseExited(MouseEvent mouseEvent) { + updateOver(false); + } + + @Override + public void mousePressed(MouseEvent mouseEvent) { + updatePressed(true); + } + + @Override + public void mouseReleased(MouseEvent mouseEvent) { + updatePressed(false); + } + + @Override + public void mouseClicked(MouseEvent e) {} + + //------------------------------------------------------------------ + // PopupMenuListener Methods + //------------------------------------------------------------------ + + /** + * @inheritDoc + * + * Ensures that the combo box is repainted when the popup is closed. + * This avoids a bug where clicking off the combo wasn't causing a repaint, + * and thus the combo box still looked pressed even when it was not. + * + * This bug was only noticed when acting as a button, but may be generally + * present. If so, remove the if() block + */ + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + if (shouldActLikeButton() || pressedWhenPopupVisible) { + comboBox.repaint(); + } + } + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + } + + /** + * Handler for repainting combo when editor component gains/looses focus + */ + private static class EditorFocusHandler implements FocusListener, + PropertyChangeListener { + private JComboBox comboBox; + private ComboBoxEditor editor = null; + private Component editorComponent = null; + + private EditorFocusHandler(JComboBox comboBox) { + this.comboBox = comboBox; + editor = comboBox.getEditor(); + if (editor != null){ + editorComponent = editor.getEditorComponent(); + if (editorComponent != null){ + editorComponent.addFocusListener(this); + } + } + comboBox.addPropertyChangeListener("editor",this); + } + + public void unregister(){ + comboBox.removePropertyChangeListener(this); + if (editorComponent!=null){ + editorComponent.removeFocusListener(this); + } + } + + /** Invoked when a component gains the keyboard focus. */ + public void focusGained(FocusEvent e) { + // repaint whole combo on focus gain + comboBox.repaint(); + } + + /** Invoked when a component loses the keyboard focus. */ + public void focusLost(FocusEvent e) { + // repaint whole combo on focus loss + comboBox.repaint(); + } + + /** + * Called when the combos editor changes + * + * @param evt A PropertyChangeEvent object describing the event source and + * the property that has changed. + */ + public void propertyChange(PropertyChangeEvent evt) { + ComboBoxEditor newEditor = comboBox.getEditor(); + if (editor != newEditor){ + if (editorComponent!=null){ + editorComponent.removeFocusListener(this); + } + editor = newEditor; + if (editor != null){ + editorComponent = editor.getEditorComponent(); + if (editorComponent != null){ + editorComponent.addFocusListener(this); + } + } + } + } + } } diff --git a/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java b/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java index 178981fd8fcf92edea97b622ab25f790aaf6d2dd..976ec0adc6607476ce2b297e71df99de3c58400e 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java @@ -138,9 +138,9 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } } else { - selectedUIState = SynthConstants.FOCUSED; if (enabled) { selectedUIState |= SynthConstants.ENABLED; + selectedUIState = SynthConstants.FOCUSED; } else { selectedUIState |= SynthConstants.DISABLED; @@ -251,6 +251,26 @@ public class SynthLookAndFeel extends BasicLookAndFeel { ((SynthLookAndFeel)laf). shouldUpdateStyleOnAncestorChanged()); } + // Note: The following two nimbus based overrides should be refactored + // to be in the Nimbus LAF. Due to constraints in an update release, + // we couldn't actually provide the public API necessary to allow + // NimbusLookAndFeel (a subclass of SynthLookAndFeel) to provide its + // own rules for shouldUpdateStyle. + else if ("Nimbus.Overrides" == eName) { + // Always update when the Nimbus.Overrides client property has + // been changed + return true; + } + else if ("Nimbus.Overrides.InheritDefaults" == eName) { + // Always update when the Nimbus.Overrides.InheritDefaults + // client property has changed + return true; + } + else if ("JComponent.sizeVariant" == eName) { + // Always update when the JComponent.sizeVariant + // client property has changed + return true; + } return false; } @@ -622,6 +642,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { /** * Called by UIManager when this look and feel is installed. */ + @Override public void initialize() { super.initialize(); DefaultLookup.setDefaultLookup(new SynthDefaultLookup()); @@ -633,6 +654,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { /** * Called by UIManager when this look and feel is uninstalled. */ + @Override public void uninitialize() { KeyboardFocusManager.getCurrentKeyboardFocusManager(). removePropertyChangeListener(_handler); @@ -647,6 +669,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return Defaults table. */ + @Override public UIDefaults getDefaults() { UIDefaults table = new UIDefaults(60, 0.75f); @@ -704,6 +727,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return true. */ + @Override public boolean isSupportedLookAndFeel() { return true; } @@ -713,6 +737,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return false */ + @Override public boolean isNativeLookAndFeel() { return false; } @@ -722,6 +747,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return textual description of synth. */ + @Override public String getDescription() { return "Synth look and feel"; } @@ -731,6 +757,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return a short string identifying this look and feel. */ + @Override public String getName() { return "Synth look and feel"; } @@ -740,6 +767,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { * * @return a short string identifying this look and feel. */ + @Override public String getID() { return "Synth"; } @@ -805,6 +833,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { tk.addPropertyChangeListener(key, this); } + @Override public void propertyChange(PropertyChangeEvent pce) { UIDefaults defaults = UIManager.getLookAndFeelDefaults(); if (defaults.getBoolean("Synth.doNotSetTextAA")) { @@ -873,6 +902,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { if (!isUpdatePending()) { setUpdatePending(true); Runnable uiUpdater = new Runnable() { + @Override public void run() { updateAllUIs(); setUpdatePending(false); @@ -889,6 +919,7 @@ public class SynthLookAndFeel extends BasicLookAndFeel { } private class Handler implements PropertyChangeListener { + @Override public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); Object newValue = evt.getNewValue(); diff --git a/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java b/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java index 93c66c376dc7814c0eb8fe80e5e81565f9784d97..c6a75375bf7a7fdc2273aef9cde93c52e3b323d0 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java @@ -27,14 +27,11 @@ package javax.swing.plaf.synth; import java.awt.*; import java.awt.geom.AffineTransform; -import java.awt.event.*; import javax.swing.*; -import javax.swing.event.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicProgressBarUI; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import java.io.Serializable; import sun.swing.plaf.synth.SynthUI; import sun.swing.SwingUtilities2; @@ -46,24 +43,29 @@ import sun.swing.SwingUtilities2; class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, PropertyChangeListener { private SynthStyle style; - private int progressPadding; + private boolean rotateText; // added for Nimbus LAF private boolean paintOutsideClip; + private boolean tileWhenIndeterminate; //whether to tile indeterminate painting + private int tileWidth; //the width of each tile public static ComponentUI createUI(JComponent x) { return new SynthProgressBarUI(); } + @Override protected void installListeners() { super.installListeners(); progressBar.addPropertyChangeListener(this); } + @Override protected void uninstallListeners() { super.uninstallListeners(); progressBar.removePropertyChangeListener(this); } + @Override protected void installDefaults() { updateStyle(progressBar); } @@ -72,17 +74,34 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, SynthContext context = getContext(c, ENABLED); SynthStyle oldStyle = style; style = SynthLookAndFeel.updateStyle(context, this); - if (style != oldStyle) { - setCellLength(style.getInt(context, "ProgressBar.cellLength", 1)); - setCellSpacing(style.getInt(context, "ProgressBar.cellSpacing", 0)); - progressPadding = style.getInt(context, - "ProgressBar.progressPadding", 0); - paintOutsideClip = style.getBoolean(context, - "ProgressBar.paintOutsideClip", false); + setCellLength(style.getInt(context, "ProgressBar.cellLength", 1)); + setCellSpacing(style.getInt(context, "ProgressBar.cellSpacing", 0)); + progressPadding = style.getInt(context, + "ProgressBar.progressPadding", 0); + paintOutsideClip = style.getBoolean(context, + "ProgressBar.paintOutsideClip", false); + rotateText = style.getBoolean(context, + "ProgressBar.rotateText", false); + tileWhenIndeterminate = style.getBoolean(context, "ProgressBar.tileWhenIndeterminate", false); + tileWidth = style.getInt(context, "ProgressBar.tileWidth", 15); + // handle scaling for sizeVarients for special case components. The + // key "JComponent.sizeVariant" scales for large/small/mini + // components are based on Apples LAF + String scaleKey = (String)progressBar.getClientProperty( + "JComponent.sizeVariant"); + if (scaleKey != null){ + if ("large".equals(scaleKey)){ + tileWidth *= 1.15; + } else if ("small".equals(scaleKey)){ + tileWidth *= 0.857; + } else if ("mini".equals(scaleKey)){ + tileWidth *= 0.784; + } } context.dispose(); } + @Override protected void uninstallDefaults() { SynthContext context = getContext(progressBar, ENABLED); @@ -108,6 +127,7 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, return SynthLookAndFeel.getComponentState(c); } + @Override public int getBaseline(JComponent c, int width, int height) { super.getBaseline(c, width, height); if (progressBar.isStringPainted() && @@ -122,6 +142,16 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, return -1; } + @Override + protected Rectangle getBox(Rectangle r) { + if (tileWhenIndeterminate) { + return SwingUtilities.calculateInnerArea(progressBar, r); + } else { + return super.getBox(r); + } + } + + @Override protected void setAnimationIndex(int newValue) { if (paintOutsideClip) { if (getAnimationIndex() == newValue) { @@ -134,6 +164,7 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, } } + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -145,6 +176,7 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, context.dispose(); } + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -196,44 +228,98 @@ class SynthProgressBarUI extends BasicProgressBarUI implements SynthUI, width = boxRect.width - progressPadding - progressPadding; height = boxRect.height - progressPadding - progressPadding; } - context.getPainter().paintProgressBarForeground(context, g, - x, y, width, height, pBar.getOrientation()); - if (pBar.isStringPainted() && !pBar.isIndeterminate()) { + //if tiling and indeterminate, then paint the progress bar foreground a + //bit wider than it should be. Shift as needed to ensure that there is + //an animated effect + if (tileWhenIndeterminate && pBar.isIndeterminate()) { + double percentComplete = (double)getAnimationIndex() / (double)getFrameCount(); + int offset = (int)(percentComplete * tileWidth); + Shape clip = g.getClip(); + g.clipRect(x, y, width, height); + if (pBar.getOrientation() == JProgressBar.HORIZONTAL) { + //paint each tile horizontally + for (int i=x-tileWidth+offset; i<=width; i+=tileWidth) { + context.getPainter().paintProgressBarForeground( + context, g, i, y, tileWidth, height, pBar.getOrientation()); + } + } else { //JProgressBar.VERTICAL + //paint each tile vertically + for (int i=y-offset; iIf non-zero, tabOverlap indicates the amount that the tab bounds + * should be altered such that they would overlap with a tab on either the + * leading or trailing end of a run (ie: in TOP, this would be on the left + * or right).
+ + *A positive overlap indicates that tabs should overlap right/down, + * while a negative overlap indicates tha tabs should overlap left/up.
+ * + *When tabOverlap is specified, it both changes the x position and width + * of the tab if in TOP or BOTTOM placement, and changes the y position and + * height if in LEFT or RIGHT placement.
+ * + *This is done for the following reason. Consider a run of 10 tabs. + * There are 9 gaps between these tabs. If you specified a tabOverlap of + * "-1", then each of the tabs "x" values will be shifted left. This leaves + * 9 pixels of space to the right of the right-most tab unpainted. So, each + * tab's width is also extended by 1 pixel to make up the difference.
+ * + *This property respects the RTL component orientation.
+ */ + private int tabOverlap = 0; + + /** + * When a tabbed pane has multiple rows of tabs, this indicates whether + * the tabs in the upper row(s) should extend to the base of the tab area, + * or whether they should remain at their normal tab height. This does not + * affect the bounds of the tabs, only the bounds of area painted by the + * tabs. The text position does not change. The result is that the bottom + * border of the upper row of tabs becomes fully obscured by the lower tabs, + * resulting in a cleaner look. + */ + private boolean extendTabsToBase = false; + private SynthContext tabAreaContext; private SynthContext tabContext; private SynthContext tabContentContext; @@ -64,6 +95,14 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh private Rectangle tabAreaBounds = new Rectangle(); + //added for the Nimbus look and feel, where the tab area is painted differently depending on the + //state for the selected tab + private boolean tabAreaStatesMatchSelectedTab = false; + //added for the Nimbus LAF to ensure that the labels don't move whether the tab is selected or not + private boolean nudgeSelectedLabel = true; + + private boolean selectedTabIsPressed = false; + public static ComponentUI createUI(JComponent c) { return new SynthTabbedPaneUI(); } @@ -90,12 +129,19 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh if (style != oldStyle) { tabRunOverlay = style.getInt(context, "TabbedPane.tabRunOverlay", 0); + tabOverlap = style.getInt(context, "TabbedPane.tabOverlap", 0); + extendTabsToBase = style.getBoolean(context, + "TabbedPane.extendTabsToBase", false); textIconGap = style.getInt(context, "TabbedPane.textIconGap", 0); selectedTabPadInsets = (Insets)style.get(context, "TabbedPane.selectedTabPadInsets"); if (selectedTabPadInsets == null) { selectedTabPadInsets = new Insets(0, 0, 0, 0); } + tabAreaStatesMatchSelectedTab = style.getBoolean(context, + "TabbedPane.tabAreaStatesMatchSelectedTab", false); + nudgeSelectedLabel = style.getBoolean(context, + "TabbedPane.nudgeSelectedLabel", true); if (oldStyle != null) { uninstallKeyboardActions(); installKeyboardActions(); @@ -199,6 +245,14 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh } protected JButton createScrollButton(int direction) { + // added for Nimbus LAF so that it can use the basic arrow buttons + // UIManager is queried directly here because this is called before + // updateStyle is called so the style can not be queried directly + if (UIManager.getBoolean("TabbedPane.useBasicArrows")) { + JButton btn = super.createScrollButton(direction); + btn.setBorder(BorderFactory.createEmptyBorder()); + return btn; + } return new SynthScrollableTabButton(direction); } @@ -208,6 +262,75 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh } } + /** + * @inheritDoc + * + * Overridden to keep track of whether the selected tab is also pressed. + */ + @Override + protected MouseListener createMouseListener() { + final MouseListener delegate = super.createMouseListener(); + final MouseMotionListener delegate2 = (MouseMotionListener)delegate; + return new MouseListener() { + public void mouseClicked(MouseEvent e) { delegate.mouseClicked(e); } + public void mouseEntered(MouseEvent e) { delegate.mouseEntered(e); } + public void mouseExited(MouseEvent e) { delegate.mouseExited(e); } + + public void mousePressed(MouseEvent e) { + if (!tabPane.isEnabled()) { + return; + } + + int tabIndex = tabForCoordinate(tabPane, e.getX(), e.getY()); + if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex)) { + if (tabIndex == tabPane.getSelectedIndex()) { + // Clicking on selected tab + selectedTabIsPressed = true; + //TODO need to just repaint the tab area! + tabPane.repaint(); + } + } + + //forward the event (this will set the selected index, or none at all + delegate.mousePressed(e); + } + + public void mouseReleased(MouseEvent e) { + if (selectedTabIsPressed) { + selectedTabIsPressed = false; + //TODO need to just repaint the tab area! + tabPane.repaint(); + } + //forward the event + delegate.mouseReleased(e); + + //hack: The super method *should* be setting the mouse-over property correctly + //here, but it doesn't. That is, when the mouse is released, whatever tab is below the + //released mouse should be in rollover state. But, if you select a tab and don't + //move the mouse, this doesn't happen. Hence, forwarding the event. + delegate2.mouseMoved(e); + } + }; + } + + @Override + protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) { + if (nudgeSelectedLabel) { + return super.getTabLabelShiftX(tabPlacement, tabIndex, isSelected); + } else { + return 0; + } + } + + @Override + protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { + if (nudgeSelectedLabel) { + return super.getTabLabelShiftY(tabPlacement, tabIndex, isSelected); + } else { + return 0; + } + } + public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -321,6 +444,20 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh Rectangle tabAreaBounds) { Rectangle clipRect = g.getClipBounds(); + //if the tab area's states should match that of the selected tab, then + //first update the selected tab's states, then set the state + //for the tab area to match + //otherwise, restore the tab area's state to ENABLED (which is the + //only supported state otherwise). + if (tabAreaStatesMatchSelectedTab && selectedIndex >= 0) { + updateTabContext(selectedIndex, true, selectedTabIsPressed, + (getRolloverTab() == selectedIndex), + (getFocusIndex() == selectedIndex)); + ss.setComponentState(tabContext.getComponentState()); + } else { + ss.setComponentState(SynthConstants.ENABLED); + } + // Paint the tab area. SynthLookAndFeel.updateSubregion(ss, g, tabAreaBounds); ss.getPainter().paintTabbedPaneTabAreaBackground(ss, g, @@ -362,17 +499,22 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh Rectangle r = null; - if ((oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount())) { - r = getTabBounds(tabPane, oldRolloverTab); - if (r != null) { - tabPane.repaint(r); + if (oldRolloverTab != index && tabAreaStatesMatchSelectedTab) { + //TODO need to just repaint the tab area! + tabPane.repaint(); + } else { + if ((oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount())) { + r = getTabBounds(tabPane, oldRolloverTab); + if (r != null) { + tabPane.repaint(r); + } } - } - if (index >= 0) { - r = getTabBounds(tabPane, index); - if (r != null) { - tabPane.repaint(r); + if (index >= 0) { + r = getTabBounds(tabPane, index); + if (r != null) { + tabPane.repaint(r); + } } } } @@ -383,18 +525,51 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh Rectangle tabRect = rects[tabIndex]; int selectedIndex = tabPane.getSelectedIndex(); boolean isSelected = selectedIndex == tabIndex; - updateTabContext(tabIndex, isSelected, - (getRolloverTab() == tabIndex), - (getFocusIndex() == tabIndex)); + updateTabContext(tabIndex, isSelected, isSelected && selectedTabIsPressed, + (getRolloverTab() == tabIndex), + (getFocusIndex() == tabIndex)); SynthLookAndFeel.updateSubregion(ss, g, tabRect); - tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, - g, tabRect.x, tabRect.y, tabRect.width, - tabRect.height, tabIndex, - tabPane.getTabPlacement()); + int x = tabRect.x; + int y = tabRect.y; + int height = tabRect.height; + int width = tabRect.width; + int placement = tabPane.getTabPlacement(); + if (extendTabsToBase && runCount > 1) { + //paint this tab such that its edge closest to the base is equal to + //edge of the selected tab closest to the base. In terms of the TOP + //tab placement, this will cause the bottom of each tab to be + //painted even with the bottom of the selected tab. This is because + //in each tab placement (TOP, LEFT, BOTTOM, RIGHT) the selected tab + //is closest to the base. + if (selectedIndex >= 0) { + Rectangle r = rects[selectedIndex]; + switch (placement) { + case TOP: + int bottomY = r.y + r.height; + height = bottomY - tabRect.y; + break; + case LEFT: + int rightX = r.x + r.width; + width = rightX - tabRect.x; + break; + case BOTTOM: + int topY = r.y; + height = (tabRect.y + tabRect.height) - topY; + y = topY; + break; + case RIGHT: + int leftX = r.x; + width = (tabRect.x + tabRect.width) - leftX; + x = leftX; + break; + } + } + } + tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, g, + x, y, width, height, tabIndex, placement); tabContext.getPainter().paintTabbedPaneTabBorder(tabContext, g, - tabRect.x, tabRect.y, tabRect.width, tabRect.height, - tabIndex, tabPane.getTabPlacement()); + x, y, width, height, tabIndex, placement); if (tabPane.getTabComponentAt(tabIndex) == null) { String title = tabPane.getTitleAt(tabIndex); @@ -561,7 +736,7 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh } protected Insets getTabInsets(int tabPlacement, int tabIndex) { - updateTabContext(tabIndex, false, false, + updateTabContext(tabIndex, false, false, false, (getFocusIndex() == tabIndex)); return tabInsets; } @@ -575,7 +750,7 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh } private void updateTabContext(int index, boolean selected, - boolean isMouseOver, boolean hasFocus) { + boolean isMouseDown, boolean isMouseOver, boolean hasFocus) { int state = 0; if (!tabPane.isEnabled() || !tabPane.isEnabledAt(index)) { state |= SynthConstants.DISABLED; @@ -599,9 +774,68 @@ class SynthTabbedPaneUI extends BasicTabbedPaneUI implements SynthUI, PropertyCh if (hasFocus && tabPane.hasFocus()) { state |= SynthConstants.FOCUSED; // individual tab has focus } + if (isMouseDown) { + state |= SynthConstants.PRESSED; + } + tabContext.setComponentState(state); } + /** + * @inheritDoc + * + * Overridden to create a TabbedPaneLayout subclass which takes into + * account tabOverlap. + */ + @Override protected LayoutManager createLayoutManager() { + if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) { + return super.createLayoutManager(); + } else { /* WRAP_TAB_LAYOUT */ + return new TabbedPaneLayout() { + @Override + public void calculateLayoutInfo() { + super.calculateLayoutInfo(); + //shift all the tabs, if necessary + if (tabOverlap != 0) { + int tabCount = tabPane.getTabCount(); + //left-to-right/right-to-left only affects layout + //when placement is TOP or BOTTOM + boolean ltr = tabPane.getComponentOrientation().isLeftToRight(); + for (int i = runCount - 1; i >= 0; i--) { + int start = tabRuns[i]; + int next = tabRuns[(i == runCount - 1)? 0 : i + 1]; + int end = (next != 0? next - 1: tabCount - 1); + for (int j = start+1; j <= end; j++) { + // xshift and yshift represent the amount & + // direction to shift the tab in their + // respective axis. + int xshift = 0; + int yshift = 0; + // configure xshift and y shift based on tab + // position and ltr/rtl + switch (tabPane.getTabPlacement()) { + case JTabbedPane.TOP: + case JTabbedPane.BOTTOM: + xshift = ltr ? tabOverlap : -tabOverlap; + break; + case JTabbedPane.LEFT: + case JTabbedPane.RIGHT: + yshift = tabOverlap; + break; + default: //do nothing + } + rects[j].x += xshift; + rects[j].y += yshift; + rects[j].width += Math.abs(xshift); + rects[j].height += Math.abs(yshift); + } + } + } + } + }; + } + } + private class SynthScrollableTabButton extends SynthArrowButton implements UIResource { public SynthScrollableTabButton(int direction) { diff --git a/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java b/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java index 20d3c01f34834c26704ba622741c36fecea96564..b37d9f1262d32d6eddbfc736f70cb8875a6f69a1 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java @@ -33,6 +33,7 @@ import javax.swing.plaf.*; import javax.swing.plaf.basic.*; import javax.swing.table.*; +import sun.swing.DefaultLookup; import sun.swing.plaf.synth.*; import sun.swing.table.*; @@ -160,6 +161,7 @@ class SynthTableHeaderUI extends BasicTableHeaderUI implements private class HeaderRenderer extends DefaultTableCellHeaderRenderer { HeaderRenderer() { setHorizontalAlignment(JLabel.LEADING); + setName("TableHeader.renderer"); } @Override @@ -178,24 +180,40 @@ class SynthTableHeaderUI extends BasicTableHeaderUI implements SynthLookAndFeel.resetSelectedUI(); } + //stuff a variable into the client property of this renderer indicating the sort order, + //so that different rendering can be done for the header based on sorted state. + RowSorter rs = table == null ? null : table.getRowSorter(); + java.util.List extends RowSorter.SortKey> sortKeys = rs == null ? null : rs.getSortKeys(); + if (sortKeys != null && sortKeys.size() > 0 && sortKeys.get(0).getColumn() == + table.convertColumnIndexToModel(column)) { + switch(sortKeys.get(0).getSortOrder()) { + case ASCENDING: + putClientProperty("Table.sortOrder", "ASCENDING"); + break; + case DESCENDING: + putClientProperty("Table.sortOrder", "DESCENDING"); + break; + case UNSORTED: + putClientProperty("Table.sortOrder", "UNSORTED"); + break; + default: + throw new AssertionError("Cannot happen"); + } + } else { + putClientProperty("Table.sortOrder", "UNSORTED"); + } + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); return this; } + @Override public void setBorder(Border border) { if (border instanceof SynthBorder) { super.setBorder(border); } } - - public String getName() { - String name = super.getName(); - if (name == null) { - return "TableHeader.renderer"; - } - return name; - } } } diff --git a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java index be90ac5198b45c22b6acf63f254f4800a8a41135..1b8cf9894465b4c8f915973d8176c014cb96d407 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java @@ -27,6 +27,7 @@ package javax.swing.plaf.synth; import java.awt.Color; import java.awt.Component; +import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; @@ -70,6 +71,7 @@ class SynthTableUI extends BasicTableUI implements SynthUI, private boolean useTableColors; private boolean useUIBorder; + private Color alternateColor; //the background color to use for cells for alternate cells // TableCellRenderer installed on the JTable at the time we're installed, // cached so that we can reinstall them at uninstallUI time. @@ -161,6 +163,21 @@ class SynthTableUI extends BasicTableUI implements SynthUI, if (rowHeight != null) { LookAndFeel.installProperty(table, "rowHeight", rowHeight); } + boolean showGrid = style.getBoolean(context, "Table.showGrid", true); + if (!showGrid) { + table.setShowGrid(false); + } + Dimension d = table.getIntercellSpacing(); +// if (d == null || d instanceof UIResource) { + if (d != null) { + d = (Dimension)style.get(context, "Table.intercellSpacing"); + } + alternateColor = (Color)style.get(context, "Table.alternateRowColor"); + if (d != null) { + table.setIntercellSpacing(d); + } + + if (oldStyle != null) { uninstallKeyboardActions(); installKeyboardActions(); @@ -617,6 +634,14 @@ class SynthTableUI extends BasicTableUI implements SynthUI, else { TableCellRenderer renderer = table.getCellRenderer(row, column); Component component = table.prepareRenderer(renderer, row, column); + Color b = component.getBackground(); + if ((b == null || b instanceof UIResource + || component instanceof SynthBooleanTableCellRenderer) + && !table.isCellSelected(row, column)) { + if (alternateColor != null && row % 2 == 0) { + component.setBackground(alternateColor); + } + } rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } @@ -634,16 +659,8 @@ class SynthTableUI extends BasicTableUI implements SynthUI, private boolean isRowSelected; public SynthBooleanTableCellRenderer() { - super(); setHorizontalAlignment(JLabel.CENTER); - } - - public String getName() { - String name = super.getName(); - if (name == null) { - return "Table.cellRenderer"; - } - return name; + setName("Table.cellRenderer"); } public Component getTableCellRendererComponent( @@ -652,17 +669,24 @@ class SynthTableUI extends BasicTableUI implements SynthUI, isRowSelected = isSelected; if (isSelected) { - setForeground(table.getSelectionForeground()); - setBackground(table.getSelectionBackground()); + setForeground(unwrap(table.getSelectionForeground())); + setBackground(unwrap(table.getSelectionBackground())); } else { - setForeground(table.getForeground()); - setBackground(table.getBackground()); + setForeground(unwrap(table.getForeground())); + setBackground(unwrap(table.getBackground())); } setSelected((value != null && ((Boolean)value).booleanValue())); return this; } + private Color unwrap(Color c) { + if (c instanceof UIResource) { + return new Color(c.getRGB()); + } + return c; + } + public boolean isOpaque() { return isRowSelected ? true : super.isOpaque(); } @@ -732,7 +756,7 @@ class SynthTableUI extends BasicTableUI implements SynthUI, } else if (columnClass == Icon.class || columnClass == ImageIcon.class) { setHorizontalAlignment(JLabel.CENTER); - setIcon((Icon)value); + setIcon((value instanceof Icon) ? (Icon)value : null); setText(""); } else if (columnClass == Date.class) { diff --git a/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java b/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java index 3a650d2abebdf9bb7f8e256e2552ee5f812dfe52..01947655afe352fd185b3a2325e170b908f86318 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java @@ -27,10 +27,11 @@ package javax.swing.plaf.synth; import javax.swing.*; import javax.swing.text.*; -import javax.swing.event.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicTextAreaUI; import java.awt.*; +import java.awt.event.FocusListener; +import java.awt.event.FocusEvent; import java.beans.PropertyChangeEvent; import sun.swing.plaf.synth.SynthUI; @@ -50,7 +51,7 @@ import sun.swing.plaf.synth.SynthUI; * * @author Shannon Hickey */ -class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { +class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI, FocusListener { private SynthStyle style; /** @@ -63,16 +64,26 @@ class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { return new SynthTextAreaUI(); } + public void focusGained(FocusEvent e) { + getComponent().repaint(); + } + + public void focusLost(FocusEvent e) { + getComponent().repaint(); + } + protected void installDefaults() { // Installs the text cursor on the component super.installDefaults(); updateStyle(getComponent()); + getComponent().addFocusListener(this); } protected void uninstallDefaults() { SynthContext context = getContext(getComponent(), ENABLED); getComponent().putClientProperty("caretAspectRatio", null); + getComponent().removeFocusListener(this); style.uninstallDefaults(context); context.dispose(); diff --git a/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java b/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java index 74b9f7cca67a9405c9c3a468e8cfc8d29a0e5518..d4b22baaf2b3042660a66b3b21384a541ddb12e6 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java @@ -25,12 +25,10 @@ package javax.swing.plaf.synth; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.text.View; +import java.awt.Graphics; +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; /** * Synth's ToggleButtonUI. @@ -45,15 +43,21 @@ class SynthToggleButtonUI extends SynthButtonUI { return new SynthToggleButtonUI(); } + @Override protected String getPropertyPrefix() { return "ToggleButton."; } + @Override void paintBackground(SynthContext context, Graphics g, JComponent c) { - context.getPainter().paintToggleButtonBackground(context, g, 0, 0, - c.getWidth(), c.getHeight()); + if (((AbstractButton) c).isContentAreaFilled()) { + int x = 0, y = 0, w = c.getWidth(), h = c.getHeight(); + SynthPainter painter = context.getPainter(); + painter.paintToggleButtonBackground(context, g, x, y, w, h); + } } + @Override public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) { context.getPainter().paintToggleButtonBorder(context, g, x, y, w, h); diff --git a/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java b/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java index 60aa951c9f395886121ab610b3c1df9df67c753d..c49536c34e745bc73e76a926f46871ae84dcd18d 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java @@ -25,18 +25,24 @@ package javax.swing.plaf.synth; -import javax.swing.*; -import javax.swing.event.*; -import java.awt.*; -import java.awt.event.*; - -import java.beans.*; - -import javax.swing.border.*; -import javax.swing.plaf.*; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Box; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JSeparator; +import javax.swing.JToolBar; +import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicToolBarUI; -import sun.swing.plaf.synth.*; - +import sun.swing.plaf.synth.SynthIcon; +import sun.swing.plaf.synth.SynthUI; /** * A Synth L&F implementation of ToolBarUI. This implementation @@ -57,23 +63,35 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, return new SynthToolBarUI(); } + @Override protected void installDefaults() { toolBar.setLayout(createLayout()); updateStyle(toolBar); } + @Override protected void installListeners() { super.installListeners(); toolBar.addPropertyChangeListener(this); } + @Override protected void uninstallListeners() { super.uninstallListeners(); toolBar.removePropertyChangeListener(this); } private void updateStyle(JToolBar c) { - SynthContext context = getContext(c, ENABLED); + SynthContext context = getContext( + c, Region.TOOL_BAR_CONTENT, null, ENABLED); + contentStyle = SynthLookAndFeel.updateStyle(context, this); + context.dispose(); + + context = getContext(c, Region.TOOL_BAR_DRAG_WINDOW, null, ENABLED); + dragWindowStyle = SynthLookAndFeel.updateStyle(context, this); + context.dispose(); + + context = getContext(c, ENABLED); SynthStyle oldStyle = style; style = SynthLookAndFeel.updateStyle(context, this); @@ -86,16 +104,9 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, } } context.dispose(); - - context = getContext(c, Region.TOOL_BAR_CONTENT, ENABLED); - contentStyle = SynthLookAndFeel.updateStyle(context, this); - context.dispose(); - - context = getContext(c, Region.TOOL_BAR_DRAG_WINDOW, ENABLED); - dragWindowStyle = SynthLookAndFeel.updateStyle(context, this); - context.dispose(); } + @Override protected void uninstallDefaults() { SynthContext context = getContext(toolBar, ENABLED); @@ -105,12 +116,14 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, handleIcon = null; - context = getContext(toolBar, Region.TOOL_BAR_CONTENT, ENABLED); + context = getContext(toolBar, Region.TOOL_BAR_CONTENT, + contentStyle, ENABLED); contentStyle.uninstallDefaults(context); context.dispose(); contentStyle = null; - context = getContext(toolBar, Region.TOOL_BAR_DRAG_WINDOW, ENABLED); + context = getContext(toolBar, Region.TOOL_BAR_DRAG_WINDOW, + dragWindowStyle, ENABLED); dragWindowStyle.uninstallDefaults(context); context.dispose(); dragWindowStyle = null; @@ -118,11 +131,11 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, toolBar.setLayout(null); } - protected void installComponents() { - } + @Override + protected void installComponents() {} - protected void uninstallComponents() { - } + @Override + protected void uninstallComponents() {} protected LayoutManager createLayout() { return new SynthToolBarLayoutManager(); @@ -137,13 +150,15 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, SynthLookAndFeel.getRegion(c), style, state); } - private SynthContext getContext(JComponent c, Region region) { - return getContext(c, region, getComponentState(c, region)); + private SynthContext getContext(JComponent c, Region region, SynthStyle style) { + return SynthContext.getContext(SynthContext.class, c, region, + style, getComponentState(c, region)); } - private SynthContext getContext(JComponent c, Region region, int state) { + private SynthContext getContext(JComponent c, Region region, + SynthStyle style, int state) { return SynthContext.getContext(SynthContext.class, c, region, - dragWindowStyle, state); + style, state); } private Region getRegion(JComponent c) { @@ -158,6 +173,7 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, return SynthLookAndFeel.getComponentState(c); } + @Override public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -169,6 +185,7 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, context.dispose(); } + @Override public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); @@ -183,12 +200,15 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, } // Overloaded to do nothing so we can share listeners. + @Override protected void setBorderToNonRollover(Component c) {} // Overloaded to do nothing so we can share listeners. + @Override protected void setBorderToRollover(Component c) {} // Overloaded to do nothing so we can share listeners. + @Override protected void setBorderToNormal(Component c) {} protected void paint(SynthContext context, Graphics g) { @@ -201,7 +221,8 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, SynthIcon.getIconHeight(handleIcon, context)); } - SynthContext subcontext = getContext(toolBar, Region.TOOL_BAR_CONTENT); + SynthContext subcontext = getContext( + toolBar, Region.TOOL_BAR_CONTENT, contentStyle); paintContent(subcontext, g, contentRect); subcontext.dispose(); } @@ -217,12 +238,14 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, toolBar.getOrientation()); } + @Override protected void paintDragWindow(Graphics g) { int w = dragWindow.getWidth(); int h = dragWindow.getHeight(); - SynthContext context = getContext(toolBar,Region.TOOL_BAR_DRAG_WINDOW); - SynthLookAndFeel.updateSubregion(context, g, new Rectangle( - 0, 0, w, h)); + SynthContext context = getContext( + toolBar, Region.TOOL_BAR_DRAG_WINDOW, dragWindowStyle); + SynthLookAndFeel.updateSubregion( + context, g, new Rectangle(0, 0, w, h)); context.getPainter().paintToolBarDragWindowBackground(context, g, 0, 0, w, h, dragWindow.getOrientation()); @@ -319,6 +342,19 @@ class SynthToolBarUI extends BasicToolBarUI implements PropertyChangeListener, Component c; Dimension d; + + // JToolBar by default uses a somewhat modified BoxLayout as + // its layout manager. For compatibility reasons, we want to + // support Box "glue" as a way to move things around on the + // toolbar. "glue" is represented in BoxLayout as a Box.Filler + // with a minimum and preferred size of (0,0). + // So what we do here is find the number of such glue fillers + // and figure out how much space should be allocated to them. + int glueCount = 0; + for (int i=0; igetTableCellRendererComponent
method and set the border
* of the returned component directly.
*/
- protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
+ private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
+ protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
// We need a place to store the color the JLabel should be returned
// to after its foreground and background colors have been set
@@ -109,12 +110,18 @@ public class DefaultTableCellRenderer extends JLabel
super();
setOpaque(true);
setBorder(getNoFocusBorder());
+ setName("Table.cellRenderer");
}
- private static Border getNoFocusBorder() {
+ private Border getNoFocusBorder() {
+ Border border = DefaultLookup.getBorder(this, ui, "Table.cellNoFocusBorder");
if (System.getSecurityManager() != null) {
+ if (border != null) return border;
return SAFE_NO_FOCUS_BORDER;
} else {
+ if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
+ return border;
+ }
return noFocusBorder;
}
}
@@ -190,8 +197,8 @@ public class DefaultTableCellRenderer extends JLabel
&& dropLocation.getRow() == row
&& dropLocation.getColumn() == column) {
- fg = UIManager.getColor("Table.dropCellForeground");
- bg = UIManager.getColor("Table.dropCellBackground");
+ fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
+ bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
isSelected = true;
}
@@ -202,12 +209,18 @@ public class DefaultTableCellRenderer extends JLabel
super.setBackground(bg == null ? table.getSelectionBackground()
: bg);
} else {
+ Color background = unselectedBackground != null
+ ? unselectedBackground
+ : table.getBackground();
+ if (background == null || background instanceof javax.swing.plaf.UIResource) {
+ Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor");
+ if (alternateColor != null && row % 2 == 0)
+ background = alternateColor;
+ }
super.setForeground(unselectedForeground != null
? unselectedForeground
: table.getForeground());
- super.setBackground(unselectedBackground != null
- ? unselectedBackground
- : table.getBackground());
+ super.setBackground(background);
}
setFont(table.getFont());
@@ -215,20 +228,20 @@ public class DefaultTableCellRenderer extends JLabel
if (hasFocus) {
Border border = null;
if (isSelected) {
- border = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
+ border = DefaultLookup.getBorder(this, ui, "Table.focusSelectedCellHighlightBorder");
}
if (border == null) {
- border = UIManager.getBorder("Table.focusCellHighlightBorder");
+ border = DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder");
}
setBorder(border);
if (!isSelected && table.isCellEditable(row, column)) {
Color col;
- col = UIManager.getColor("Table.focusCellForeground");
+ col = DefaultLookup.getColor(this, ui, "Table.focusCellForeground");
if (col != null) {
super.setForeground(col);
}
- col = UIManager.getColor("Table.focusCellBackground");
+ col = DefaultLookup.getColor(this, ui, "Table.focusCellBackground");
if (col != null) {
super.setBackground(col);
}
@@ -261,6 +274,7 @@ public class DefaultTableCellRenderer extends JLabel
if (p != null) {
p = p.getParent();
}
+
// p should now be the JTable.
boolean colorMatch = (back != null) && (p != null) &&
back.equals(p.getBackground()) &&
diff --git a/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java b/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java
index 6363ae995981d09b38de3980d199ecfc810526a4..dd7a1ca9b213e97b24e5c004082f100ebdfdf8b7 100644
--- a/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java
+++ b/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java
@@ -25,16 +25,24 @@
package javax.swing.tree;
-import javax.swing.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicGraphicsUtils;
-import java.awt.*;
-import java.awt.event.*;
-import java.beans.*;
-import java.io.*;
-import java.util.*;
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JTree;
+import javax.swing.LookAndFeel;
+import javax.swing.UIManager;
+import javax.swing.border.EmptyBorder;
+import sun.swing.DefaultLookup;
/**
* Displays an entry in a tree.
@@ -148,6 +156,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
protected Color borderSelectionColor;
private boolean isDropCell;
+ private boolean fillBackground = true;
/**
* Set to true after the constructor has run.
@@ -177,41 +186,48 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
// null. As such, if the value is null, this does not reset the
// value.
if (!inited || (getLeafIcon() instanceof UIResource)) {
- setLeafIcon(UIManager.getIcon("Tree.leafIcon"));
+ setLeafIcon(DefaultLookup.getIcon(this, ui, "Tree.leafIcon"));
}
if (!inited || (getClosedIcon() instanceof UIResource)) {
- setClosedIcon(UIManager.getIcon("Tree.closedIcon"));
+ setClosedIcon(DefaultLookup.getIcon(this, ui, "Tree.closedIcon"));
}
if (!inited || (getOpenIcon() instanceof UIManager)) {
- setOpenIcon(UIManager.getIcon("Tree.openIcon"));
+ setOpenIcon(DefaultLookup.getIcon(this, ui, "Tree.openIcon"));
}
if (!inited || (getTextSelectionColor() instanceof UIResource)) {
setTextSelectionColor(
- UIManager.getColor("Tree.selectionForeground"));
+ DefaultLookup.getColor(this, ui, "Tree.selectionForeground"));
}
if (!inited || (getTextNonSelectionColor() instanceof UIResource)) {
setTextNonSelectionColor(
- UIManager.getColor("Tree.textForeground"));
+ DefaultLookup.getColor(this, ui, "Tree.textForeground"));
}
if (!inited || (getBackgroundSelectionColor() instanceof UIResource)) {
setBackgroundSelectionColor(
- UIManager.getColor("Tree.selectionBackground"));
+ DefaultLookup.getColor(this, ui, "Tree.selectionBackground"));
}
if (!inited ||
(getBackgroundNonSelectionColor() instanceof UIResource)) {
setBackgroundNonSelectionColor(
- UIManager.getColor("Tree.textBackground"));
+ DefaultLookup.getColor(this, ui, "Tree.textBackground"));
}
if (!inited || (getBorderSelectionColor() instanceof UIResource)) {
setBorderSelectionColor(
- UIManager.getColor("Tree.selectionBorderColor"));
+ DefaultLookup.getColor(this, ui, "Tree.selectionBorderColor"));
}
- Object value = UIManager.get("Tree.drawsFocusBorderAroundIcon");
- drawsFocusBorderAroundIcon = (value != null && ((Boolean)value).
- booleanValue());
- value = UIManager.get("Tree.drawDashedFocusIndicator");
- drawDashedFocusIndicator = (value != null && ((Boolean)value).
- booleanValue());
+ drawsFocusBorderAroundIcon = DefaultLookup.getBoolean(
+ this, ui, "Tree.drawsFocusBorderAroundIcon", false);
+ drawDashedFocusIndicator = DefaultLookup.getBoolean(
+ this, ui, "Tree.drawDashedFocusIndicator", false);
+
+ fillBackground = DefaultLookup.getBoolean(this, ui, "Tree.rendererFillBackground", true);
+ Insets margins = DefaultLookup.getInsets(this, ui, "Tree.rendererMargins");
+ if (margins != null) {
+ setBorder(new EmptyBorder(margins.top, margins.left,
+ margins.bottom, margins.right));
+ }
+
+ setName("Tree.cellRenderer");
}
@@ -220,7 +236,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
* represent non-leaf nodes that are expanded.
*/
public Icon getDefaultOpenIcon() {
- return UIManager.getIcon("Tree.openIcon");
+ return DefaultLookup.getIcon(this, ui, "Tree.openIcon");
}
/**
@@ -228,7 +244,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
* represent non-leaf nodes that are not expanded.
*/
public Icon getDefaultClosedIcon() {
- return UIManager.getIcon("Tree.closedIcon");
+ return DefaultLookup.getIcon(this, ui, "Tree.closedIcon");
}
/**
@@ -236,7 +252,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
* represent leaf nodes.
*/
public Icon getDefaultLeafIcon() {
- return UIManager.getIcon("Tree.leafIcon");
+ return DefaultLookup.getIcon(this, ui, "Tree.leafIcon");
}
/**
@@ -425,7 +441,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
&& dropLocation.getChildIndex() == -1
&& tree.getRowForPath(dropLocation.getPath()) == row) {
- Color col = UIManager.getColor("Tree.dropCellForeground");
+ Color col = DefaultLookup.getColor(this, ui, "Tree.dropCellForeground");
if (col != null) {
fg = col;
} else {
@@ -441,26 +457,24 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
setForeground(fg);
- // There needs to be a way to specify disabled icons.
+ Icon icon = null;
+ if (leaf) {
+ icon = getLeafIcon();
+ } else if (expanded) {
+ icon = getOpenIcon();
+ } else {
+ icon = getClosedIcon();
+ }
+
if (!tree.isEnabled()) {
setEnabled(false);
- if (leaf) {
- setDisabledIcon(getLeafIcon());
- } else if (expanded) {
- setDisabledIcon(getOpenIcon());
- } else {
- setDisabledIcon(getClosedIcon());
- }
- }
- else {
+ LookAndFeel laf = UIManager.getLookAndFeel();
+ Icon disabledIcon = laf.getDisabledIcon(tree, icon);
+ if (disabledIcon != null) icon = disabledIcon;
+ setDisabledIcon(icon);
+ } else {
setEnabled(true);
- if (leaf) {
- setIcon(getLeafIcon());
- } else if (expanded) {
- setIcon(getOpenIcon());
- } else {
- setIcon(getClosedIcon());
- }
+ setIcon(icon);
}
setComponentOrientation(tree.getComponentOrientation());
@@ -476,7 +490,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
Color bColor;
if (isDropCell) {
- bColor = UIManager.getColor("Tree.dropCellBackground");
+ bColor = DefaultLookup.getColor(this, ui, "Tree.dropCellBackground");
if (bColor == null) {
bColor = getBackgroundSelectionColor();
}
@@ -490,9 +504,7 @@ public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer
}
int imageOffset = -1;
- if(bColor != null) {
- Icon currentI = getIcon();
-
+ if (bColor != null && fillBackground) {
imageOffset = getLabelStart();
g.setColor(bColor);
if(getComponentOrientation().isLeftToRight()) {
diff --git a/src/share/classes/sun/swing/DefaultLookup.java b/src/share/classes/sun/swing/DefaultLookup.java
index af46f955f9f91fa9ce69b862e729996fcdd84b56..c5dccc5e13b873375639c2b875c6d8ea1220eb1a 100644
--- a/src/share/classes/sun/swing/DefaultLookup.java
+++ b/src/share/classes/sun/swing/DefaultLookup.java
@@ -27,6 +27,7 @@ package sun.swing;
import java.awt.Color;
import java.awt.Insets;
import javax.swing.*;
+import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import sun.awt.AppContext;
@@ -137,6 +138,10 @@ public class DefaultLookup {
return ((Number)iValue).intValue();
}
+ public static int getInt(JComponent c, ComponentUI ui, String key) {
+ return getInt(c, ui, key, -1);
+ }
+
public static Insets getInsets(JComponent c, ComponentUI ui, String key,
Insets defaultValue) {
Object iValue = get(c, ui, key);
@@ -147,6 +152,10 @@ public class DefaultLookup {
return (Insets)iValue;
}
+ public static Insets getInsets(JComponent c, ComponentUI ui, String key) {
+ return getInsets(c, ui, key, null);
+ }
+
public static boolean getBoolean(JComponent c, ComponentUI ui, String key,
boolean defaultValue) {
Object iValue = get(c, ui, key);
@@ -157,6 +166,10 @@ public class DefaultLookup {
return ((Boolean)iValue).booleanValue();
}
+ public static boolean getBoolean(JComponent c, ComponentUI ui, String key) {
+ return getBoolean(c, ui, key, false);
+ }
+
public static Color getColor(JComponent c, ComponentUI ui, String key,
Color defaultValue) {
Object iValue = get(c, ui, key);
@@ -167,7 +180,35 @@ public class DefaultLookup {
return (Color)iValue;
}
+ public static Color getColor(JComponent c, ComponentUI ui, String key) {
+ return getColor(c, ui, key, null);
+ }
+
+ public static Icon getIcon(JComponent c, ComponentUI ui, String key,
+ Icon defaultValue) {
+ Object iValue = get(c, ui, key);
+ if (iValue == null || !(iValue instanceof Icon)) {
+ return defaultValue;
+ }
+ return (Icon)iValue;
+ }
+
+ public static Icon getIcon(JComponent c, ComponentUI ui, String key) {
+ return getIcon(c, ui, key, null);
+ }
+
+ public static Border getBorder(JComponent c, ComponentUI ui, String key,
+ Border defaultValue) {
+ Object iValue = get(c, ui, key);
+ if (iValue == null || !(iValue instanceof Border)) {
+ return defaultValue;
+ }
+ return (Border)iValue;
+ }
+ public static Border getBorder(JComponent c, ComponentUI ui, String key) {
+ return getBorder(c, ui, key, null);
+ }
public Object getDefault(JComponent c, ComponentUI ui, String key) {
// basic
diff --git a/src/share/classes/sun/swing/FilePane.java b/src/share/classes/sun/swing/FilePane.java
index 71112b319d8c328c91236bc719ce0a0638565faa..eae3d5a0d602be71b2d79ed0a1fd84001d43adf8 100644
--- a/src/share/classes/sun/swing/FilePane.java
+++ b/src/share/classes/sun/swing/FilePane.java
@@ -265,6 +265,7 @@ public class FilePane extends JPanel implements PropertyChangeListener {
private Color listViewBackground;
private boolean listViewWindowsStyle;
private boolean readOnly;
+ private boolean fullRowSelection = false;
private ListSelectionModel listSelectionModel;
private JList list;
@@ -448,6 +449,7 @@ public class FilePane extends JPanel implements PropertyChangeListener {
kiloByteString = UIManager.getString("FileChooser.fileSizeKiloBytes", l);
megaByteString = UIManager.getString("FileChooser.fileSizeMegaBytes", l);
gigaByteString = UIManager.getString("FileChooser.fileSizeGigaBytes", l);
+ fullRowSelection = UIManager.getBoolean("FileView.fullRowSelection");
renameErrorTitleText = UIManager.getString("FileChooser.renameErrorTitleText", l);
renameErrorText = UIManager.getString("FileChooser.renameErrorText", l);
@@ -991,6 +993,7 @@ public class FilePane extends JPanel implements PropertyChangeListener {
public DetailsTableCellEditor(JTextField tf) {
super(tf);
this.tf = tf;
+ tf.setName("Table.editor");
tf.addFocusListener(editorFocusListener);
}
@@ -1018,7 +1021,8 @@ public class FilePane extends JPanel implements PropertyChangeListener {
}
public void setBounds(int x, int y, int width, int height) {
- if (getHorizontalAlignment() == SwingConstants.LEADING) {
+ if (getHorizontalAlignment() == SwingConstants.LEADING &&
+ !fullRowSelection) {
// Restrict width to actual text
width = Math.min(width, this.getPreferredSize().width+4);
} else {
@@ -1039,9 +1043,9 @@ public class FilePane extends JPanel implements PropertyChangeListener {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
- if (table.convertColumnIndexToModel(column) != COLUMN_FILENAME ||
- (listViewWindowsStyle && !table.isFocusOwner())) {
-
+ if ((table.convertColumnIndexToModel(column) != COLUMN_FILENAME ||
+ (listViewWindowsStyle && !table.isFocusOwner())) &&
+ !fullRowSelection) {
isSelected = false;
}
@@ -1338,6 +1342,7 @@ public class FilePane extends JPanel implements PropertyChangeListener {
Rectangle r = list.getCellBounds(index, index);
if (editCell == null) {
editCell = new JTextField();
+ editCell.setName("Tree.cellEditor");
editCell.addActionListener(new EditActionListener());
editCell.addFocusListener(editorFocusListener);
editCell.setNextFocusableComponent(list);
@@ -1797,10 +1802,11 @@ public class FilePane extends JPanel implements PropertyChangeListener {
Point p = evt.getPoint();
index = table.rowAtPoint(p);
- if (SwingUtilities2.pointOutsidePrefSize(table,
- index,
- table.columnAtPoint(p), p)) {
+ boolean pointOutsidePrefSize =
+ SwingUtilities2.pointOutsidePrefSize(
+ table, index, table.columnAtPoint(p), p);
+ if (pointOutsidePrefSize && !fullRowSelection) {
return;
}
diff --git a/src/share/classes/sun/swing/plaf/GTKKeybindings.java b/src/share/classes/sun/swing/plaf/GTKKeybindings.java
new file mode 100644
index 0000000000000000000000000000000000000000..3701d86ccd51a4da155b9537302e1563b182e1c3
--- /dev/null
+++ b/src/share/classes/sun/swing/plaf/GTKKeybindings.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.swing.plaf;
+
+import javax.swing.JTextField;
+import javax.swing.UIDefaults;
+import javax.swing.text.DefaultEditorKit;
+
+/**
+ * GTKKeybindings - The standard set of keymaps for the GTK Platform
+ *
+ * @author Jasper Potts
+ */
+public class GTKKeybindings {
+
+ /**
+ * Install all GTK keybindings into the provided UIDefaults table
+ *
+ * @param table The UiDefaults table to install into
+ */
+ public static void installKeybindings(UIDefaults table) {
+ Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", DefaultEditorKit.copyAction,
+ "ctrl V", DefaultEditorKit.pasteAction,
+ "ctrl X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
+ "ctrl LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl A", DefaultEditorKit.selectAllAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+ Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", DefaultEditorKit.copyAction,
+ "ctrl V", DefaultEditorKit.pasteAction,
+ "ctrl X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
+ "ctrl LEFT", DefaultEditorKit.beginLineAction,
+ "ctrl KP_LEFT", DefaultEditorKit.beginLineAction,
+ "ctrl RIGHT", DefaultEditorKit.endLineAction,
+ "ctrl KP_RIGHT", DefaultEditorKit.endLineAction,
+ "ctrl shift LEFT", DefaultEditorKit.selectionBeginLineAction,
+ "ctrl shift KP_LEFT", DefaultEditorKit.selectionBeginLineAction,
+ "ctrl shift RIGHT", DefaultEditorKit.selectionEndLineAction,
+ "ctrl shift KP_RIGHT", DefaultEditorKit.selectionEndLineAction,
+ "ctrl A", DefaultEditorKit.selectAllAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+ Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", DefaultEditorKit.copyAction,
+ "ctrl V", DefaultEditorKit.pasteAction,
+ "ctrl X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
+ "ctrl LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl A", DefaultEditorKit.selectAllAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+
+ "UP", DefaultEditorKit.upAction,
+ "KP_UP", DefaultEditorKit.upAction,
+ "DOWN", DefaultEditorKit.downAction,
+ "KP_DOWN", DefaultEditorKit.downAction,
+ "PAGE_UP", DefaultEditorKit.pageUpAction,
+ "PAGE_DOWN", DefaultEditorKit.pageDownAction,
+ "shift PAGE_UP", "selection-page-up",
+ "shift PAGE_DOWN", "selection-page-down",
+ "ctrl shift PAGE_UP", "selection-page-left",
+ "ctrl shift PAGE_DOWN", "selection-page-right",
+ "shift UP", DefaultEditorKit.selectionUpAction,
+ "shift KP_UP", DefaultEditorKit.selectionUpAction,
+ "shift DOWN", DefaultEditorKit.selectionDownAction,
+ "shift KP_DOWN", DefaultEditorKit.selectionDownAction,
+ "ENTER", DefaultEditorKit.insertBreakAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "TAB", DefaultEditorKit.insertTabAction,
+ "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "ctrl HOME", DefaultEditorKit.beginAction,
+ "ctrl END", DefaultEditorKit.endAction,
+ "ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
+ "ctrl shift END", DefaultEditorKit.selectionEndAction,
+ "ctrl T", "next-link-action",
+ "ctrl shift T", "previous-link-action",
+ "ctrl SPACE", "activate-link-action",
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+
+ Object[] defaults = new Object[]{
+ "Button.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released",
+ "ENTER", "pressed",
+ "released ENTER", "released"
+ }),
+ "CheckBox.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "ComboBox.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "hidePopup",
+ "PAGE_UP", "pageUpPassThrough",
+ "PAGE_DOWN", "pageDownPassThrough",
+ "HOME", "homePassThrough",
+ "END", "endPassThrough",
+ "DOWN", "selectNext",
+ "KP_DOWN", "selectNext",
+ "alt DOWN", "togglePopup",
+ "alt KP_DOWN", "togglePopup",
+ "alt UP", "togglePopup",
+ "alt KP_UP", "togglePopup",
+ "SPACE", "spacePopup",
+ "ENTER", "enterPressed",
+ "UP", "selectPrevious",
+ "KP_UP", "selectPrevious"
+
+ }),
+ "EditorPane.focusInputMap", multilineInputMap,
+ "FileChooser.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "cancelSelection",
+ "F2", "editFileName",
+ "F5", "refresh",
+ "BACK_SPACE", "Go Up",
+ "ENTER", "approveSelection",
+ "ctrl ENTER", "approveSelection"
+ }),
+ "FormattedTextField.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", DefaultEditorKit.copyAction,
+ "ctrl V", DefaultEditorKit.pasteAction,
+ "ctrl X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
+ "ctrl LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl A", DefaultEditorKit.selectAllAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "ctrl BACK_SLASH", "unselect",
+ "control shift O", "toggle-componentOrientation",
+ "ESCAPE", "reset-field-edit",
+ "UP", "increment",
+ "KP_UP", "increment",
+ "DOWN", "decrement",
+ "KP_DOWN", "decrement",
+ }),
+ "InternalFrame.windowBindings",
+ new Object[]{
+ "shift ESCAPE", "showSystemMenu",
+ "ctrl SPACE", "showSystemMenu",
+ "ESCAPE", "hideSystemMenu"
+ },
+ "List.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "UP", "selectPreviousRow",
+ "KP_UP", "selectPreviousRow",
+ "shift UP", "selectPreviousRowExtendSelection",
+ "shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift UP", "selectPreviousRowExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "DOWN", "selectNextRow",
+ "KP_DOWN", "selectNextRow",
+ "shift DOWN", "selectNextRowExtendSelection",
+ "shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl shift DOWN", "selectNextRowExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "LEFT", "selectPreviousColumn",
+ "KP_LEFT", "selectPreviousColumn",
+ "shift LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "RIGHT", "selectNextColumn",
+ "KP_RIGHT", "selectNextColumn",
+ "shift RIGHT", "selectNextColumnExtendSelection",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "HOME", "selectFirstRow",
+ "shift HOME", "selectFirstRowExtendSelection",
+ "ctrl shift HOME", "selectFirstRowExtendSelection",
+ "ctrl HOME", "selectFirstRowChangeLead",
+ "END", "selectLastRow",
+ "shift END", "selectLastRowExtendSelection",
+ "ctrl shift END", "selectLastRowExtendSelection",
+ "ctrl END", "selectLastRowChangeLead",
+ "PAGE_UP", "scrollUp",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl PAGE_UP", "scrollUpChangeLead",
+ "PAGE_DOWN", "scrollDown",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl PAGE_DOWN", "scrollDownChangeLead",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo"
+ }),
+ "List.focusInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "LEFT", "selectNextColumn",
+ "KP_LEFT", "selectNextColumn",
+ "shift LEFT", "selectNextColumnExtendSelection",
+ "shift KP_LEFT", "selectNextColumnExtendSelection",
+ "ctrl shift LEFT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
+ "ctrl LEFT", "selectNextColumnChangeLead",
+ "ctrl KP_LEFT", "selectNextColumnChangeLead",
+ "RIGHT", "selectPreviousColumn",
+ "KP_RIGHT", "selectPreviousColumn",
+ "shift RIGHT", "selectPreviousColumnExtendSelection",
+ "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
+ "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
+ "ctrl RIGHT", "selectPreviousColumnChangeLead",
+ "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
+ }),
+ "MenuBar.windowBindings", new Object[]{
+ "F10", "takeFocus"
+ },
+ "OptionPane.windowBindings", new Object[]{
+ "ESCAPE", "close"
+ },
+ "PasswordField.focusInputMap", passwordInputMap,
+ "PopupMenu.selectedWindowInputMapBindings",
+ new Object[]{
+ "ESCAPE", "cancel",
+ "DOWN", "selectNext",
+ "KP_DOWN", "selectNext",
+ "UP", "selectPrevious",
+ "KP_UP", "selectPrevious",
+ "LEFT", "selectParent",
+ "KP_LEFT", "selectParent",
+ "RIGHT", "selectChild",
+ "KP_RIGHT", "selectChild",
+ "ENTER", "return",
+ "SPACE", "return"
+ },
+ "PopupMenu.selectedWindowInputMapBindings.RightToLeft",
+ new Object[]{
+ "LEFT", "selectChild",
+ "KP_LEFT", "selectChild",
+ "RIGHT", "selectParent",
+ "KP_RIGHT", "selectParent",
+ },
+ "RadioButton.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released",
+ "RETURN", "pressed"
+ }),
+ // These bindings are only enabled when there is a default
+ // button set on the rootpane.
+ "RootPane.defaultButtonWindowKeyBindings", new Object[]{
+ "ENTER", "press",
+ "released ENTER", "release",
+ "ctrl ENTER", "press",
+ "ctrl released ENTER", "release"
+ },
+ "ScrollBar.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "positiveUnitIncrement",
+ "KP_RIGHT", "positiveUnitIncrement",
+ "DOWN", "positiveUnitIncrement",
+ "KP_DOWN", "positiveUnitIncrement",
+ "PAGE_DOWN", "positiveBlockIncrement",
+ "LEFT", "negativeUnitIncrement",
+ "KP_LEFT", "negativeUnitIncrement",
+ "UP", "negativeUnitIncrement",
+ "KP_UP", "negativeUnitIncrement",
+ "PAGE_UP", "negativeBlockIncrement",
+ "HOME", "minScroll",
+ "END", "maxScroll"
+ }),
+ "ScrollBar.ancestorInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "negativeUnitIncrement",
+ "KP_RIGHT", "negativeUnitIncrement",
+ "LEFT", "positiveUnitIncrement",
+ "KP_LEFT", "positiveUnitIncrement",
+ }),
+ "ScrollPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "unitScrollRight",
+ "KP_RIGHT", "unitScrollRight",
+ "DOWN", "unitScrollDown",
+ "KP_DOWN", "unitScrollDown",
+ "LEFT", "unitScrollLeft",
+ "KP_LEFT", "unitScrollLeft",
+ "UP", "unitScrollUp",
+ "KP_UP", "unitScrollUp",
+ "PAGE_UP", "scrollUp",
+ "PAGE_DOWN", "scrollDown",
+ "ctrl PAGE_UP", "scrollLeft",
+ "ctrl PAGE_DOWN", "scrollRight",
+ "ctrl HOME", "scrollHome",
+ "ctrl END", "scrollEnd"
+ }),
+ "ScrollPane.ancestorInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl PAGE_UP", "scrollRight",
+ "ctrl PAGE_DOWN", "scrollLeft",
+ }),
+ "Slider.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "positiveUnitIncrement",
+ "KP_RIGHT", "positiveUnitIncrement",
+ "DOWN", "negativeUnitIncrement",
+ "KP_DOWN", "negativeUnitIncrement",
+ "PAGE_DOWN", "negativeBlockIncrement",
+ "LEFT", "negativeUnitIncrement",
+ "KP_LEFT", "negativeUnitIncrement",
+ "UP", "positiveUnitIncrement",
+ "KP_UP", "positiveUnitIncrement",
+ "PAGE_UP", "positiveBlockIncrement",
+ "HOME", "minScroll",
+ "END", "maxScroll"
+ }),
+ "Slider.focusInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "negativeUnitIncrement",
+ "KP_RIGHT", "negativeUnitIncrement",
+ "LEFT", "positiveUnitIncrement",
+ "KP_LEFT", "positiveUnitIncrement",
+ }),
+ "Spinner.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "increment",
+ "KP_UP", "increment",
+ "DOWN", "decrement",
+ "KP_DOWN", "decrement",
+ }),
+ "SplitPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "negativeIncrement",
+ "DOWN", "positiveIncrement",
+ "LEFT", "negativeIncrement",
+ "RIGHT", "positiveIncrement",
+ "KP_UP", "negativeIncrement",
+ "KP_DOWN", "positiveIncrement",
+ "KP_LEFT", "negativeIncrement",
+ "KP_RIGHT", "positiveIncrement",
+ "HOME", "selectMin",
+ "END", "selectMax",
+ "F8", "startResize",
+ "F6", "toggleFocus",
+ "ctrl TAB", "focusOutForward",
+ "ctrl shift TAB", "focusOutBackward"
+ }),
+ "TabbedPane.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "navigateRight",
+ "KP_RIGHT", "navigateRight",
+ "LEFT", "navigateLeft",
+ "KP_LEFT", "navigateLeft",
+ "UP", "navigateUp",
+ "KP_UP", "navigateUp",
+ "DOWN", "navigateDown",
+ "KP_DOWN", "navigateDown",
+ "ctrl DOWN", "requestFocusForVisibleComponent",
+ "ctrl KP_DOWN", "requestFocusForVisibleComponent",
+ "SPACE", "selectTabWithFocus"
+ }),
+ "TabbedPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl TAB", "navigateNext",
+ "ctrl shift TAB", "navigatePrevious",
+ "ctrl PAGE_DOWN", "navigatePageDown",
+ "ctrl PAGE_UP", "navigatePageUp",
+ "ctrl UP", "requestFocus",
+ "ctrl KP_UP", "requestFocus",
+ }),
+ "TableHeader.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[] {
+ "SPACE", "toggleSortOrder",
+ "LEFT", "selectColumnToLeft",
+ "KP_LEFT", "selectColumnToLeft",
+ "RIGHT", "selectColumnToRight",
+ "KP_RIGHT", "selectColumnToRight",
+ "alt LEFT", "moveColumnLeft",
+ "alt KP_LEFT", "moveColumnLeft",
+ "alt RIGHT", "moveColumnRight",
+ "alt KP_RIGHT", "moveColumnRight",
+ "alt shift LEFT", "resizeLeft",
+ "alt shift KP_LEFT", "resizeLeft",
+ "alt shift RIGHT", "resizeRight",
+ "alt shift KP_RIGHT", "resizeRight",
+ "ESCAPE", "focusTable",
+ }),
+ "Table.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "RIGHT", "selectNextColumn",
+ "KP_RIGHT", "selectNextColumn",
+ "shift RIGHT", "selectNextColumnExtendSelection",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "LEFT", "selectPreviousColumn",
+ "KP_LEFT", "selectPreviousColumn",
+ "shift LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "DOWN", "selectNextRow",
+ "KP_DOWN", "selectNextRow",
+ "shift DOWN", "selectNextRowExtendSelection",
+ "shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl shift DOWN", "selectNextRowExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "UP", "selectPreviousRow",
+ "KP_UP", "selectPreviousRow",
+ "shift UP", "selectPreviousRowExtendSelection",
+ "shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift UP", "selectPreviousRowExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "HOME", "selectFirstColumn",
+ "shift HOME", "selectFirstColumnExtendSelection",
+ "ctrl shift HOME", "selectFirstRowExtendSelection",
+ "ctrl HOME", "selectFirstRow",
+ "END", "selectLastColumn",
+ "shift END", "selectLastColumnExtendSelection",
+ "ctrl shift END", "selectLastRowExtendSelection",
+ "ctrl END", "selectLastRow",
+ "PAGE_UP", "scrollUpChangeSelection",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
+ "ctrl PAGE_UP", "scrollLeftChangeSelection",
+ "PAGE_DOWN", "scrollDownChangeSelection",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
+ "ctrl PAGE_DOWN", "scrollRightChangeSelection",
+ "TAB", "selectNextColumnCell",
+ "shift TAB", "selectPreviousColumnCell",
+ "ENTER", "selectNextRowCell",
+ "shift ENTER", "selectPreviousRowCell",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "ESCAPE", "cancel",
+ "F2", "startEditing",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo",
+ "F8", "focusHeader"
+ }),
+ "Table.ancestorInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "selectPreviousColumn",
+ "KP_RIGHT", "selectPreviousColumn",
+ "shift RIGHT", "selectPreviousColumnExtendSelection",
+ "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
+ "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
+ "shift RIGHT", "selectPreviousColumnChangeLead",
+ "shift KP_RIGHT", "selectPreviousColumnChangeLead",
+ "LEFT", "selectNextColumn",
+ "KP_LEFT", "selectNextColumn",
+ "shift LEFT", "selectNextColumnExtendSelection",
+ "shift KP_LEFT", "selectNextColumnExtendSelection",
+ "ctrl shift LEFT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
+ "ctrl LEFT", "selectNextColumnChangeLead",
+ "ctrl KP_LEFT", "selectNextColumnChangeLead",
+ "ctrl PAGE_UP", "scrollRightChangeSelection",
+ "ctrl PAGE_DOWN", "scrollLeftChangeSelection",
+ "ctrl shift PAGE_UP", "scrollRightExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
+ }),
+ "TextArea.focusInputMap", multilineInputMap,
+ "TextField.focusInputMap", fieldInputMap,
+ "TextPane.focusInputMap", multilineInputMap,
+ "ToggleButton.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "ToolBar.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "navigateUp",
+ "KP_UP", "navigateUp",
+ "DOWN", "navigateDown",
+ "KP_DOWN", "navigateDown",
+ "LEFT", "navigateLeft",
+ "KP_LEFT", "navigateLeft",
+ "RIGHT", "navigateRight",
+ "KP_RIGHT", "navigateRight"
+ }),
+ "Tree.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "UP", "selectPrevious",
+ "KP_UP", "selectPrevious",
+ "shift UP", "selectPreviousExtendSelection",
+ "shift KP_UP", "selectPreviousExtendSelection",
+ "ctrl shift UP", "selectPreviousExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousExtendSelection",
+ "ctrl UP", "selectPreviousChangeLead",
+ "ctrl KP_UP", "selectPreviousChangeLead",
+ "DOWN", "selectNext",
+ "KP_DOWN", "selectNext",
+ "shift DOWN", "selectNextExtendSelection",
+ "shift KP_DOWN", "selectNextExtendSelection",
+ "ctrl shift DOWN", "selectNextExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextExtendSelection",
+ "ctrl DOWN", "selectNextChangeLead",
+ "ctrl KP_DOWN", "selectNextChangeLead",
+ "RIGHT", "selectChild",
+ "KP_RIGHT", "selectChild",
+ "LEFT", "selectParent",
+ "KP_LEFT", "selectParent",
+ "typed +", "expand",
+ "typed -", "collapse",
+ "BACK_SPACE", "moveSelectionToParent",
+ "PAGE_UP", "scrollUpChangeSelection",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl PAGE_UP", "scrollUpChangeLead",
+ "PAGE_DOWN", "scrollDownChangeSelection",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl PAGE_DOWN", "scrollDownChangeLead",
+ "HOME", "selectFirst",
+ "shift HOME", "selectFirstExtendSelection",
+ "ctrl shift HOME", "selectFirstExtendSelection",
+ "ctrl HOME", "selectFirstChangeLead",
+ "END", "selectLast",
+ "shift END", "selectLastExtendSelection",
+ "ctrl shift END", "selectLastExtendSelection",
+ "ctrl END", "selectLastChangeLead",
+ "F2", "startEditing",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "ctrl LEFT", "scrollLeft",
+ "ctrl KP_LEFT", "scrollLeft",
+ "ctrl RIGHT", "scrollRight",
+ "ctrl KP_RIGHT", "scrollRight",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo"
+ }),
+ "Tree.focusInputMap.RightToLeft",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "selectParent",
+ "KP_RIGHT", "selectParent",
+ "LEFT", "selectChild",
+ "KP_LEFT", "selectChild",
+ }),
+ "Tree.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "cancel"
+ }),
+ };
+ table.putDefaults(defaults);
+ }
+}
diff --git a/src/share/classes/sun/swing/plaf/WindowsKeybindings.java b/src/share/classes/sun/swing/plaf/WindowsKeybindings.java
new file mode 100644
index 0000000000000000000000000000000000000000..48f93e78762dcdac42f526623b55c455ef728c96
--- /dev/null
+++ b/src/share/classes/sun/swing/plaf/WindowsKeybindings.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.swing.plaf;
+
+import javax.swing.JTextField;
+import javax.swing.UIDefaults;
+import javax.swing.text.DefaultEditorKit;
+
+/**
+ * WindowsKeybindings - The standard set of keymaps for the Windows Platform
+ *
+ * @author Jasper Potts
+ */
+public class WindowsKeybindings {
+
+ /**
+ * Install all Windows keybindings into the provided UIDefaults table
+ *
+ * @param table The UiDefaults table to install into
+ */
+ public static void installKeybindings(UIDefaults table) {
+ // *** Text
+ Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "control C", DefaultEditorKit.copyAction,
+ "control V", DefaultEditorKit.pasteAction,
+ "control X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "control A", DefaultEditorKit.selectAllAction,
+ "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "control LEFT", DefaultEditorKit.previousWordAction,
+ "control RIGHT", DefaultEditorKit.nextWordAction,
+ "control shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "control shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+ Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "control C", DefaultEditorKit.copyAction,
+ "control V", DefaultEditorKit.pasteAction,
+ "control X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "control A", DefaultEditorKit.selectAllAction,
+ "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "control LEFT", DefaultEditorKit.beginLineAction,
+ "control RIGHT", DefaultEditorKit.endLineAction,
+ "control shift LEFT", DefaultEditorKit.selectionBeginLineAction,
+ "control shift RIGHT", DefaultEditorKit.selectionEndLineAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+ Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[]{
+ "control C", DefaultEditorKit.copyAction,
+ "control V", DefaultEditorKit.pasteAction,
+ "control X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "control LEFT", DefaultEditorKit.previousWordAction,
+ "control RIGHT", DefaultEditorKit.nextWordAction,
+ "control shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "control shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "control A", DefaultEditorKit.selectAllAction,
+ "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "control HOME", DefaultEditorKit.beginAction,
+ "control END", DefaultEditorKit.endAction,
+ "control shift HOME", DefaultEditorKit.selectionBeginAction,
+ "control shift END", DefaultEditorKit.selectionEndAction,
+ "UP", DefaultEditorKit.upAction,
+ "DOWN", DefaultEditorKit.downAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "PAGE_UP", DefaultEditorKit.pageUpAction,
+ "PAGE_DOWN", DefaultEditorKit.pageDownAction,
+ "shift PAGE_UP", "selection-page-up",
+ "shift PAGE_DOWN", "selection-page-down",
+ "ctrl shift PAGE_UP", "selection-page-left",
+ "ctrl shift PAGE_DOWN", "selection-page-right",
+ "shift UP", DefaultEditorKit.selectionUpAction,
+ "shift DOWN", DefaultEditorKit.selectionDownAction,
+ "ENTER", DefaultEditorKit.insertBreakAction,
+ "TAB", DefaultEditorKit.insertTabAction,
+ "control T", "next-link-action",
+ "control shift T", "previous-link-action",
+ "control SPACE", "activate-link-action",
+ "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
+ });
+ Object[] defaults = {
+ "TextField.focusInputMap", fieldInputMap,
+ "PasswordField.focusInputMap", passwordInputMap,
+ "TextArea.focusInputMap", multilineInputMap,
+ "TextPane.focusInputMap", multilineInputMap,
+ "EditorPane.focusInputMap", multilineInputMap,
+ "Button.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "CheckBox.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "hidePopup",
+ "PAGE_UP", "pageUpPassThrough",
+ "PAGE_DOWN", "pageDownPassThrough",
+ "HOME", "homePassThrough",
+ "END", "endPassThrough",
+ "DOWN", "selectNext2",
+ "KP_DOWN", "selectNext2",
+ "UP", "selectPrevious2",
+ "KP_UP", "selectPrevious2",
+ "ENTER", "enterPressed",
+ "F4", "togglePopup",
+ "alt DOWN", "togglePopup",
+ "alt KP_DOWN", "togglePopup",
+ "alt UP", "togglePopup",
+ "alt KP_UP", "togglePopup"
+ }),
+ "Desktop.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl F5", "restore",
+ "ctrl F4", "close",
+ "ctrl F7", "move",
+ "ctrl F8", "resize",
+ "RIGHT", "right",
+ "KP_RIGHT", "right",
+ "LEFT", "left",
+ "KP_LEFT", "left",
+ "UP", "up",
+ "KP_UP", "up",
+ "DOWN", "down",
+ "KP_DOWN", "down",
+ "ESCAPE", "escape",
+ "ctrl F9", "minimize",
+ "ctrl F10", "maximize",
+ "ctrl F6", "selectNextFrame",
+ "ctrl TAB", "selectNextFrame",
+ "ctrl alt F6", "selectNextFrame",
+ "shift ctrl alt F6", "selectPreviousFrame",
+ "ctrl F12", "navigateNext",
+ "shift ctrl F12", "navigatePrevious"
+ }),
+ "FileChooser.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "cancelSelection",
+ "F2", "editFileName",
+ "F5", "refresh",
+ "BACK_SPACE", "Go Up",
+ "ENTER", "approveSelection",
+ "ctrl ENTER", "approveSelection"
+ }),
+ "InternalFrame.windowBindings", new Object[]{
+ "shift ESCAPE", "showSystemMenu",
+ "ctrl SPACE", "showSystemMenu",
+ "ESCAPE", "hideSystemMenu"
+ },
+ "List.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "UP", "selectPreviousRow",
+ "KP_UP", "selectPreviousRow",
+ "shift UP", "selectPreviousRowExtendSelection",
+ "shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift UP", "selectPreviousRowExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "DOWN", "selectNextRow",
+ "KP_DOWN", "selectNextRow",
+ "shift DOWN", "selectNextRowExtendSelection",
+ "shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl shift DOWN", "selectNextRowExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "LEFT", "selectPreviousColumn",
+ "KP_LEFT", "selectPreviousColumn",
+ "shift LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "RIGHT", "selectNextColumn",
+ "KP_RIGHT", "selectNextColumn",
+ "shift RIGHT", "selectNextColumnExtendSelection",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "HOME", "selectFirstRow",
+ "shift HOME", "selectFirstRowExtendSelection",
+ "ctrl shift HOME", "selectFirstRowExtendSelection",
+ "ctrl HOME", "selectFirstRowChangeLead",
+ "END", "selectLastRow",
+ "shift END", "selectLastRowExtendSelection",
+ "ctrl shift END", "selectLastRowExtendSelection",
+ "ctrl END", "selectLastRowChangeLead",
+ "PAGE_UP", "scrollUp",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl PAGE_UP", "scrollUpChangeLead",
+ "PAGE_DOWN", "scrollDown",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl PAGE_DOWN", "scrollDownChangeLead",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo"
+ }),
+ "MenuBar.windowBindings", new Object[]{
+ "F10", "takeFocus"
+ },
+ "RadioButton.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "OptionPane.windowBindings", new Object[]{
+ "ESCAPE", "close"
+ },
+ "FormattedTextField.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", DefaultEditorKit.copyAction,
+ "ctrl V", DefaultEditorKit.pasteAction,
+ "ctrl X", DefaultEditorKit.cutAction,
+ "COPY", DefaultEditorKit.copyAction,
+ "PASTE", DefaultEditorKit.pasteAction,
+ "CUT", DefaultEditorKit.cutAction,
+ "control INSERT", DefaultEditorKit.copyAction,
+ "shift INSERT", DefaultEditorKit.pasteAction,
+ "shift DELETE", DefaultEditorKit.cutAction,
+ "shift LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
+ "shift RIGHT", DefaultEditorKit.selectionForwardAction,
+ "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
+ "ctrl LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
+ "ctrl RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
+ "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
+ "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
+ "ctrl A", DefaultEditorKit.selectAllAction,
+ "HOME", DefaultEditorKit.beginLineAction,
+ "END", DefaultEditorKit.endLineAction,
+ "shift HOME", DefaultEditorKit.selectionBeginLineAction,
+ "shift END", DefaultEditorKit.selectionEndLineAction,
+ "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
+ "ctrl H", DefaultEditorKit.deletePrevCharAction,
+ "DELETE", DefaultEditorKit.deleteNextCharAction,
+ "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
+ "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
+ "RIGHT", DefaultEditorKit.forwardAction,
+ "LEFT", DefaultEditorKit.backwardAction,
+ "KP_RIGHT", DefaultEditorKit.forwardAction,
+ "KP_LEFT", DefaultEditorKit.backwardAction,
+ "ENTER", JTextField.notifyAction,
+ "ctrl BACK_SLASH", "unselect",
+ "control shift O", "toggle-componentOrientation",
+ "ESCAPE", "reset-field-edit",
+ "UP", "increment",
+ "KP_UP", "increment",
+ "DOWN", "decrement",
+ "KP_DOWN", "decrement",
+ }),
+ // These bindings are only enabled when there is a default
+ // button set on the rootpane.
+ "RootPane.defaultButtonWindowKeyBindings", new Object[]{
+ "ENTER", "press",
+ "released ENTER", "release",
+ "ctrl ENTER", "press",
+ "ctrl released ENTER", "release"
+ },
+ "ScrollBar.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "positiveUnitIncrement",
+ "KP_RIGHT", "positiveUnitIncrement",
+ "DOWN", "positiveUnitIncrement",
+ "KP_DOWN", "positiveUnitIncrement",
+ "PAGE_DOWN", "positiveBlockIncrement",
+ "ctrl PAGE_DOWN", "positiveBlockIncrement",
+ "LEFT", "negativeUnitIncrement",
+ "KP_LEFT", "negativeUnitIncrement",
+ "UP", "negativeUnitIncrement",
+ "KP_UP", "negativeUnitIncrement",
+ "PAGE_UP", "negativeBlockIncrement",
+ "ctrl PAGE_UP", "negativeBlockIncrement",
+ "HOME", "minScroll",
+ "END", "maxScroll"
+ }),
+ "ScrollPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "unitScrollRight",
+ "KP_RIGHT", "unitScrollRight",
+ "DOWN", "unitScrollDown",
+ "KP_DOWN", "unitScrollDown",
+ "LEFT", "unitScrollLeft",
+ "KP_LEFT", "unitScrollLeft",
+ "UP", "unitScrollUp",
+ "KP_UP", "unitScrollUp",
+ "PAGE_UP", "scrollUp",
+ "PAGE_DOWN", "scrollDown",
+ "ctrl PAGE_UP", "scrollLeft",
+ "ctrl PAGE_DOWN", "scrollRight",
+ "ctrl HOME", "scrollHome",
+ "ctrl END", "scrollEnd"
+ }),
+ "Slider.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "positiveUnitIncrement",
+ "KP_RIGHT", "positiveUnitIncrement",
+ "DOWN", "negativeUnitIncrement",
+ "KP_DOWN", "negativeUnitIncrement",
+ "PAGE_DOWN", "negativeBlockIncrement",
+ "LEFT", "negativeUnitIncrement",
+ "KP_LEFT", "negativeUnitIncrement",
+ "UP", "positiveUnitIncrement",
+ "KP_UP", "positiveUnitIncrement",
+ "PAGE_UP", "positiveBlockIncrement",
+ "HOME", "minScroll",
+ "END", "maxScroll"
+ }),
+ "Spinner.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "increment",
+ "KP_UP", "increment",
+ "DOWN", "decrement",
+ "KP_DOWN", "decrement",
+ }),
+ "SplitPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "negativeIncrement",
+ "DOWN", "positiveIncrement",
+ "LEFT", "negativeIncrement",
+ "RIGHT", "positiveIncrement",
+ "KP_UP", "negativeIncrement",
+ "KP_DOWN", "positiveIncrement",
+ "KP_LEFT", "negativeIncrement",
+ "KP_RIGHT", "positiveIncrement",
+ "HOME", "selectMin",
+ "END", "selectMax",
+ "F8", "startResize",
+ "F6", "toggleFocus",
+ "ctrl TAB", "focusOutForward",
+ "ctrl shift TAB", "focusOutBackward"
+ }),
+ "TabbedPane.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "RIGHT", "navigateRight",
+ "KP_RIGHT", "navigateRight",
+ "LEFT", "navigateLeft",
+ "KP_LEFT", "navigateLeft",
+ "UP", "navigateUp",
+ "KP_UP", "navigateUp",
+ "DOWN", "navigateDown",
+ "KP_DOWN", "navigateDown",
+ "ctrl DOWN", "requestFocusForVisibleComponent",
+ "ctrl KP_DOWN", "requestFocusForVisibleComponent",
+ }),
+ "TabbedPane.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl TAB", "navigateNext",
+ "ctrl shift TAB", "navigatePrevious",
+ "ctrl PAGE_DOWN", "navigatePageDown",
+ "ctrl PAGE_UP", "navigatePageUp",
+ "ctrl UP", "requestFocus",
+ "ctrl KP_UP", "requestFocus",
+ }),
+ "TableHeader.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[] {
+ "SPACE", "toggleSortOrder",
+ "LEFT", "selectColumnToLeft",
+ "KP_LEFT", "selectColumnToLeft",
+ "RIGHT", "selectColumnToRight",
+ "KP_RIGHT", "selectColumnToRight",
+ "alt LEFT", "moveColumnLeft",
+ "alt KP_LEFT", "moveColumnLeft",
+ "alt RIGHT", "moveColumnRight",
+ "alt KP_RIGHT", "moveColumnRight",
+ "alt shift LEFT", "resizeLeft",
+ "alt shift KP_LEFT", "resizeLeft",
+ "alt shift RIGHT", "resizeRight",
+ "alt shift KP_RIGHT", "resizeRight",
+ "ESCAPE", "focusTable",
+ }),
+ "Table.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "RIGHT", "selectNextColumn",
+ "KP_RIGHT", "selectNextColumn",
+ "shift RIGHT", "selectNextColumnExtendSelection",
+ "shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift RIGHT", "selectNextColumnExtendSelection",
+ "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
+ "ctrl RIGHT", "selectNextColumnChangeLead",
+ "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+ "LEFT", "selectPreviousColumn",
+ "KP_LEFT", "selectPreviousColumn",
+ "shift LEFT", "selectPreviousColumnExtendSelection",
+ "shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
+ "ctrl LEFT", "selectPreviousColumnChangeLead",
+ "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+ "DOWN", "selectNextRow",
+ "KP_DOWN", "selectNextRow",
+ "shift DOWN", "selectNextRowExtendSelection",
+ "shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl shift DOWN", "selectNextRowExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
+ "ctrl DOWN", "selectNextRowChangeLead",
+ "ctrl KP_DOWN", "selectNextRowChangeLead",
+ "UP", "selectPreviousRow",
+ "KP_UP", "selectPreviousRow",
+ "shift UP", "selectPreviousRowExtendSelection",
+ "shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl shift UP", "selectPreviousRowExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
+ "ctrl UP", "selectPreviousRowChangeLead",
+ "ctrl KP_UP", "selectPreviousRowChangeLead",
+ "HOME", "selectFirstColumn",
+ "shift HOME", "selectFirstColumnExtendSelection",
+ "ctrl shift HOME", "selectFirstRowExtendSelection",
+ "ctrl HOME", "selectFirstRow",
+ "END", "selectLastColumn",
+ "shift END", "selectLastColumnExtendSelection",
+ "ctrl shift END", "selectLastRowExtendSelection",
+ "ctrl END", "selectLastRow",
+ "PAGE_UP", "scrollUpChangeSelection",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
+ "ctrl PAGE_UP", "scrollLeftChangeSelection",
+ "PAGE_DOWN", "scrollDownChangeSelection",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
+ "ctrl PAGE_DOWN", "scrollRightChangeSelection",
+ "TAB", "selectNextColumnCell",
+ "shift TAB", "selectPreviousColumnCell",
+ "ENTER", "selectNextRowCell",
+ "shift ENTER", "selectPreviousRowCell",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "ESCAPE", "cancel",
+ "F2", "startEditing",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo",
+ "F8", "focusHeader"
+ }),
+ "ToggleButton.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "SPACE", "pressed",
+ "released SPACE", "released"
+ }),
+ "ToolBar.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "UP", "navigateUp",
+ "KP_UP", "navigateUp",
+ "DOWN", "navigateDown",
+ "KP_DOWN", "navigateDown",
+ "LEFT", "navigateLeft",
+ "KP_LEFT", "navigateLeft",
+ "RIGHT", "navigateRight",
+ "KP_RIGHT", "navigateRight"
+ }),
+ "Tree.focusInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ADD", "expand",
+ "SUBTRACT", "collapse",
+ "ctrl C", "copy",
+ "ctrl V", "paste",
+ "ctrl X", "cut",
+ "COPY", "copy",
+ "PASTE", "paste",
+ "CUT", "cut",
+ "control INSERT", "copy",
+ "shift INSERT", "paste",
+ "shift DELETE", "cut",
+ "UP", "selectPrevious",
+ "KP_UP", "selectPrevious",
+ "shift UP", "selectPreviousExtendSelection",
+ "shift KP_UP", "selectPreviousExtendSelection",
+ "ctrl shift UP", "selectPreviousExtendSelection",
+ "ctrl shift KP_UP", "selectPreviousExtendSelection",
+ "ctrl UP", "selectPreviousChangeLead",
+ "ctrl KP_UP", "selectPreviousChangeLead",
+ "DOWN", "selectNext",
+ "KP_DOWN", "selectNext",
+ "shift DOWN", "selectNextExtendSelection",
+ "shift KP_DOWN", "selectNextExtendSelection",
+ "ctrl shift DOWN", "selectNextExtendSelection",
+ "ctrl shift KP_DOWN", "selectNextExtendSelection",
+ "ctrl DOWN", "selectNextChangeLead",
+ "ctrl KP_DOWN", "selectNextChangeLead",
+ "RIGHT", "selectChild",
+ "KP_RIGHT", "selectChild",
+ "LEFT", "selectParent",
+ "KP_LEFT", "selectParent",
+ "PAGE_UP", "scrollUpChangeSelection",
+ "shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl shift PAGE_UP", "scrollUpExtendSelection",
+ "ctrl PAGE_UP", "scrollUpChangeLead",
+ "PAGE_DOWN", "scrollDownChangeSelection",
+ "shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
+ "ctrl PAGE_DOWN", "scrollDownChangeLead",
+ "HOME", "selectFirst",
+ "shift HOME", "selectFirstExtendSelection",
+ "ctrl shift HOME", "selectFirstExtendSelection",
+ "ctrl HOME", "selectFirstChangeLead",
+ "END", "selectLast",
+ "shift END", "selectLastExtendSelection",
+ "ctrl shift END", "selectLastExtendSelection",
+ "ctrl END", "selectLastChangeLead",
+ "F2", "startEditing",
+ "ctrl A", "selectAll",
+ "ctrl SLASH", "selectAll",
+ "ctrl BACK_SLASH", "clearSelection",
+ "ctrl LEFT", "scrollLeft",
+ "ctrl KP_LEFT", "scrollLeft",
+ "ctrl RIGHT", "scrollRight",
+ "ctrl KP_RIGHT", "scrollRight",
+ "SPACE", "addToSelection",
+ "ctrl SPACE", "toggleAndAnchor",
+ "shift SPACE", "extendTo",
+ "ctrl shift SPACE", "moveSelectionTo"
+ }),
+ "Tree.ancestorInputMap",
+ new UIDefaults.LazyInputMap(new Object[]{
+ "ESCAPE", "cancel"
+ }),
+ };
+ table.putDefaults(defaults);
+ }
+
+}
diff --git a/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java b/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
index 84d522106ccd90b134d82b2ce4a15220cfd4b170..dde00682cceec6aebc0a94455ee058c6e625232e 100644
--- a/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
+++ b/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
@@ -183,14 +183,7 @@ public abstract class SynthFileChooserUI extends BasicFileChooserUI implements
}
}
- ActionMap createActionMap() {
- ActionMap map = new ActionMapUIResource();
- map.put("approveSelection", getApproveSelectionAction());
- map.put("cancelSelection", getCancelSelectionAction());
- map.put("Go Up", getChangeToParentDirectoryAction());
- map.put("fileNameCompletion", getFileNameCompletionAction());
- return map;
- }
+ protected abstract ActionMap createActionMap();
protected void installDefaults(JFileChooser fc) {
diff --git a/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java b/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
index 7069c394ad6a7019b0f7a824ba8bc3b38ca40252..a2a4b2e5e0a7bb820e08542357b0e2137f44873d 100644
--- a/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
+++ b/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
@@ -38,8 +38,7 @@ import javax.swing.filechooser.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.synth.*;
-
-import sun.swing.SwingUtilities2;
+import javax.swing.plaf.ActionMapUIResource;
import sun.awt.shell.ShellFolder;
import sun.swing.*;
@@ -286,9 +285,9 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI {
b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
b.setMargin(shrinkwrap);
+ topButtonPanel.add(b);
+ topButtonPanel.add(Box.createRigidArea(hstrut5));
}
- topButtonPanel.add(b);
- topButtonPanel.add(Box.createRigidArea(hstrut5));
// View button group
ButtonGroup viewButtonGroup = new ButtonGroup();
@@ -521,6 +520,9 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI {
}
}
+ @Override public void rescanCurrentDirectory(JFileChooser fc) {
+ filePane.rescanCurrentDirectory();
+ }
protected void doSelectedFileChanged(PropertyChangeEvent e) {
super.doSelectedFileChanged(e);
@@ -635,6 +637,14 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI {
// ************ FileChooser UI PLAF methods **************
// *******************************************************
+ protected ActionMap createActionMap() {
+ ActionMap map = new ActionMapUIResource();
+ // add standard actions
+ FilePane.addActionsToMap(map, filePane.getActions());
+ // add synth only actions
+ map.put("fileNameCompletion", getFileNameCompletionAction());
+ return map;
+ }
// *****************************
// ***** Directory Actions *****
@@ -649,32 +659,44 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI {
}
protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
- return new DirectoryComboBoxRenderer();
+ return new DirectoryComboBoxRenderer(directoryComboBox.getRenderer());
}
//
// Renderer for DirectoryComboBox
//
- class DirectoryComboBoxRenderer extends DefaultListCellRenderer {
+ // Synth has some odd behavior with regards to renderers. Renderers are styled
+ // in a specific manner by the SynthComboBoxUI. If we extend DefaultListCellRenderer
+ // here, then we get none of those benefits or behaviors, leading to poor
+ // looking combo boxes.
+ // So what we do here is delegate most jobs to the "real" or original renderer,
+ // and simply monkey with the icon and text of the renderer.
+ private class DirectoryComboBoxRenderer implements ListCellRenderer {
+ private ListCellRenderer delegate;
IndentIcon ii = new IndentIcon();
- public Component getListCellRendererComponent(JList list, Object value,
- int index, boolean isSelected,
- boolean cellHasFocus) {
- super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ private DirectoryComboBoxRenderer(ListCellRenderer delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ assert c instanceof JLabel;
+ JLabel label = (JLabel)c;
if (value == null) {
- setText("");
- return this;
+ label.setText("");
+ return label;
}
- File directory = (File)value;
- setText(getFileChooser().getName(directory));
+ File directory = (File) value;
+ label.setText(getFileChooser().getName(directory));
Icon icon = getFileChooser().getIcon(directory);
ii.icon = icon;
ii.depth = directoryComboBoxModel.getDepth(index);
- setIcon(ii);
+ label.setIcon(ii);
- return this;
+ return label;
}
}
@@ -862,24 +884,33 @@ public class SynthFileChooserUIImpl extends SynthFileChooserUI {
// Renderer for Types ComboBox
//
protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
- return new FilterComboBoxRenderer();
+ return new FilterComboBoxRenderer(filterComboBox.getRenderer());
}
/**
* Render different type sizes and styles.
*/
- public class FilterComboBoxRenderer extends DefaultListCellRenderer {
- public Component getListCellRendererComponent(JList list,
- Object value, int index, boolean isSelected,
- boolean cellHasFocus) {
+ public class FilterComboBoxRenderer implements ListCellRenderer {
+ private ListCellRenderer delegate;
+ private FilterComboBoxRenderer(ListCellRenderer delegate) {
+ this.delegate = delegate;
+ }
- super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ String text = null;
if (value != null && value instanceof FileFilter) {
- setText(((FileFilter)value).getDescription());
+ text = ((FileFilter) value).getDescription();
}
- return this;
+ //this should always be true, since SynthComboBoxUI's SynthComboBoxRenderer
+ //extends JLabel
+ assert c instanceof JLabel;
+ if (text != null) {
+ ((JLabel)c).setText(text);
+ }
+ return c;
}
}
diff --git a/src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java b/src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java
index 6198f1448237d1d567b068d071c34456f3eb0715..117ca3d4a0202bd789b2400bbbfee0d1c66db9ea 100644
--- a/src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java
+++ b/src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java
@@ -26,16 +26,23 @@ package sun.swing.table;
import java.awt.Component;
import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import javax.swing.border.Border;
import javax.swing.table.*;
+import sun.swing.DefaultLookup;
+
-/**
- */
public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
implements UIResource {
private boolean horizontalTextPositionSet;
+ private Icon sortArrow;
+ private EmptyIcon emptyIcon = new EmptyIcon();
public DefaultTableCellHeaderRenderer() {
setHorizontalAlignment(JLabel.CENTER);
@@ -58,8 +65,8 @@ public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
Color fgColor = null;
Color bgColor = null;
if (hasFocus) {
- fgColor = UIManager.getColor("TableHeader.focusCellForeground");
- bgColor = UIManager.getColor("TableHeader.focusCellBackground");
+ fgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellForeground");
+ bgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellBackground");
}
if (fgColor == null) {
fgColor = header.getForeground();
@@ -85,16 +92,16 @@ public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
if (sortOrder != null) {
switch(sortOrder) {
case ASCENDING:
- sortIcon = UIManager.getIcon(
- "Table.ascendingSortIcon");
+ sortIcon = DefaultLookup.getIcon(
+ this, ui, "Table.ascendingSortIcon");
break;
case DESCENDING:
- sortIcon = UIManager.getIcon(
- "Table.descendingSortIcon");
+ sortIcon = DefaultLookup.getIcon(
+ this, ui, "Table.descendingSortIcon");
break;
case UNSORTED:
- sortIcon = UIManager.getIcon(
- "Table.naturalSortIcon");
+ sortIcon = DefaultLookup.getIcon(
+ this, ui, "Table.naturalSortIcon");
break;
}
}
@@ -103,13 +110,14 @@ public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
setText(value == null ? "" : value.toString());
setIcon(sortIcon);
+ sortArrow = sortIcon;
Border border = null;
if (hasFocus) {
- border = UIManager.getBorder("TableHeader.focusCellBorder");
+ border = DefaultLookup.getBorder(this, ui, "TableHeader.focusCellBorder");
}
if (border == null) {
- border = UIManager.getBorder("TableHeader.cellBorder");
+ border = DefaultLookup.getBorder(this, ui, "TableHeader.cellBorder");
}
setBorder(border);
@@ -129,4 +137,60 @@ public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
}
return rv;
}
+
+ @Override
+ public void paintComponent(Graphics g) {
+ boolean b = DefaultLookup.getBoolean(this, ui,
+ "TableHeader.rightAlignSortArrow", false);
+ if (b && sortArrow != null) {
+ //emptyIcon is used so that if the text in the header is right
+ //aligned, or if the column is too narrow, then the text will
+ //be sized appropriately to make room for the icon that is about
+ //to be painted manually here.
+ emptyIcon.width = sortArrow.getIconWidth();
+ emptyIcon.height = sortArrow.getIconHeight();
+ setIcon(emptyIcon);
+ super.paintComponent(g);
+ Point position = computeIconPosition(g);
+ sortArrow.paintIcon(this, g, position.x, position.y);
+ } else {
+ super.paintComponent(g);
+ }
+ }
+
+ private Point computeIconPosition(Graphics g) {
+ FontMetrics fontMetrics = g.getFontMetrics();
+ Rectangle viewR = new Rectangle();
+ Rectangle textR = new Rectangle();
+ Rectangle iconR = new Rectangle();
+ Insets i = getInsets();
+ viewR.x = i.left;
+ viewR.y = i.top;
+ viewR.width = getWidth() - (i.left + i.right);
+ viewR.height = getHeight() - (i.top + i.bottom);
+ SwingUtilities.layoutCompoundLabel(
+ this,
+ fontMetrics,
+ getText(),
+ sortArrow,
+ getVerticalAlignment(),
+ getHorizontalAlignment(),
+ getVerticalTextPosition(),
+ getHorizontalTextPosition(),
+ viewR,
+ iconR,
+ textR,
+ getIconTextGap());
+ int x = getWidth() - i.right - sortArrow.getIconWidth();
+ int y = iconR.y;
+ return new Point(x, y);
+ }
+
+ private class EmptyIcon implements Icon {
+ int width = 0;
+ int height = 0;
+ public void paintIcon(Component c, Graphics g, int x, int y) {}
+ public int getIconWidth() { return width; }
+ public int getIconHeight() { return height; }
+ }
}
diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java
index 8a5030c83a1043478350200cd7243b9ec0f3ad82..967a2850f908d991265d007a24cafa70afadd574 100644
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -568,6 +568,17 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
{
XEvent ev = new XEvent();
while(true) {
+ // Fix for 6829923: we should gracefully handle toolkit thread interruption
+ if (Thread.currentThread().isInterrupted()) {
+ // We expect interruption from the AppContext.dispose() method only.
+ // If the thread is interrupted from another place, let's skip it
+ // for compatibility reasons. Probably some time later we'll remove
+ // the check for AppContext.isDisposed() and will unconditionally
+ // break the loop here.
+ if (AppContext.getAppContext().isDisposed()) {
+ break;
+ }
+ }
awtLock();
try {
if (loop == SECONDARY_LOOP) {
diff --git a/test/javax/sound/midi/Gervill/SoftChannel/NoteOverFlowTest.java b/test/javax/sound/midi/Gervill/SoftChannel/NoteOverFlowTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdb33571b4d04ea373e3f81486dcb25489626640
--- /dev/null
+++ b/test/javax/sound/midi/Gervill/SoftChannel/NoteOverFlowTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SoftChannel noteOn/noteOff overflow test */
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.VoiceStatus;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+import com.sun.media.sound.AudioSynthesizer;
+import com.sun.media.sound.SoftSynthesizer;
+
+public class NoteOverFlowTest {
+
+ public static void main(String[] args) throws Exception
+ {
+ AudioSynthesizer synth = new SoftSynthesizer();
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+ AudioInputStream stream = synth.openStream(format, null);
+
+ // Make all voices busy, e.g.
+ // send midi on and midi off on all available voices
+ MidiChannel ch1 = synth.getChannels()[0];
+ ch1.programChange(48); // Use contionus instrument like string ensemble
+ for (int i = 0; i < synth.getMaxPolyphony(); i++) {
+ ch1.noteOn(64, 64);
+ ch1.noteOff(64);
+ }
+
+ // Now send single midi on, and midi off message
+ ch1.noteOn(64, 64);
+ ch1.noteOff(64);
+
+ // Read 10 sec from stream, by this time all voices should be inactvie
+ stream.skip(format.getFrameSize() * ((int)(format.getFrameRate() * 20)));
+
+ // If no voice are active, then this test will pass
+ VoiceStatus[] v = synth.getVoiceStatus();
+ for (int i = 0; i < v.length; i++) {
+ if(v[i].active)
+ {
+ throw new RuntimeException("Not all voices are inactive!");
+ }
+ }
+
+ // Close the synthesizer after use
+ synth.close();
+ }
+}
diff --git a/test/javax/sound/midi/Gervill/SoftFilter/TestProcessAudio.java b/test/javax/sound/midi/Gervill/SoftFilter/TestProcessAudio.java
new file mode 100644
index 0000000000000000000000000000000000000000..032f66762c0f425a527d723d171259a037ed19ed
--- /dev/null
+++ b/test/javax/sound/midi/Gervill/SoftFilter/TestProcessAudio.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SoftFilter processAudio method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Random;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class TestProcessAudio {
+
+ public static void main(String[] args) throws Exception {
+ AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+ SoftAudioBuffer sbuffer = new SoftAudioBuffer(3600, format);
+ SoftFilter filter = new SoftFilter(format.getSampleRate());
+ Random random = new Random(42);
+
+
+ for (int t = 0; t <= 6; t++)
+ {
+ if(t == 0) filter.setFilterType(SoftFilter.FILTERTYPE_BP12);
+ if(t == 1) filter.setFilterType(SoftFilter.FILTERTYPE_HP12);
+ if(t == 2) filter.setFilterType(SoftFilter.FILTERTYPE_HP24);
+ if(t == 3) filter.setFilterType(SoftFilter.FILTERTYPE_LP12);
+ if(t == 4) filter.setFilterType(SoftFilter.FILTERTYPE_LP24);
+ if(t == 5) filter.setFilterType(SoftFilter.FILTERTYPE_LP6);
+ if(t == 6) filter.setFilterType(SoftFilter.FILTERTYPE_NP12);
+
+
+ // Try first by reseting always
+ for (int f = 1200; f < 3600; f+=100)
+ for (int r = 0; r <= 30; r+=5) {
+ filter.reset();
+ filter.setResonance(r);
+ filter.setFrequency(f);
+ float[] data = sbuffer.array();
+ int len = sbuffer.getSize();
+ for (int i = 0; i < len; i++)
+ data[i] = random.nextFloat() - 0.5f;
+ filter.processAudio(sbuffer);
+ }
+
+ // Now we skip reseting
+ // to test how changing frequency and resonance
+ // affect active filter
+ for (int f = 100; f < 12800; f+=1200)
+ for (int r = 0; r <= 30; r+=5) {
+ filter.setResonance(r);
+ filter.setFrequency(f);
+ float[] data = sbuffer.array();
+ int len = sbuffer.getSize();
+ for (int i = 0; i < len; i++)
+ data[i] = random.nextFloat() - 0.5f;
+ filter.processAudio(sbuffer);
+ }
+ for (int f = 12800; f >= 100; f-=1200)
+ for (int r = 30; r >= 0; r-=5) {
+ filter.setResonance(r);
+ filter.setFrequency(f);
+ float[] data = sbuffer.array();
+ int len = sbuffer.getSize();
+ for (int i = 0; i < len; i++)
+ data[i] = random.nextFloat() - 0.5f;
+ filter.processAudio(sbuffer);
+ }
+ filter.reset();
+ }
+
+ }
+
+}
diff --git a/test/javax/sound/midi/Gervill/SoftLowFrequencyOscillator/TestProcessControlLogic.java b/test/javax/sound/midi/Gervill/SoftLowFrequencyOscillator/TestProcessControlLogic.java
new file mode 100644
index 0000000000000000000000000000000000000000..6289a88cd86c17de427922f783a620d5fb14a4ef
--- /dev/null
+++ b/test/javax/sound/midi/Gervill/SoftLowFrequencyOscillator/TestProcessControlLogic.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test SoftLowFrequencyOscillator processControlLogic method */
+
+import com.sun.media.sound.AudioSynthesizerPropertyInfo;
+import com.sun.media.sound.SoftLowFrequencyOscillator;
+import com.sun.media.sound.SoftSynthesizer;
+
+public class TestProcessControlLogic {
+
+ private static float control_rate = 147f;
+ private static SoftSynthesizer synth = new SoftSynthesizer();
+ private static SoftLowFrequencyOscillator lfo = new SoftLowFrequencyOscillator();
+
+ private static void testLFO(boolean shared, int instance, float freq, float delay,
+ float delay2) throws Exception {
+ SoftLowFrequencyOscillator lfo =
+ shared?TestProcessControlLogic.lfo:new SoftLowFrequencyOscillator();
+ lfo.reset();
+ double[] lfo_freq = lfo.get(instance, "freq");
+ double[] lfo_delay = lfo.get(instance, "delay");
+ double[] lfo_delay2 = lfo.get(instance, "delay2");
+ double[] lfo_output = lfo.get(instance, null);
+ lfo_freq[0] = freq;
+ lfo_delay[0] = delay;
+ lfo_delay2[0] = delay2;
+ lfo.init(synth);
+
+ // For delayCount amount time, the output LFO should be 0.5
+ int delayCount = (int) ((Math.pow(2, delay / 1200.0) * control_rate));
+ delayCount += (int) ((delay2 * control_rate) / 1000.0);
+ for (int i = 0; i < delayCount; i++) {
+ if (Math.abs(0.5 - lfo_output[0]) > 0.000001)
+ throw new Exception("Incorrect LFO output ("
+ +"0.5 != "+lfo_output[0]+")!");
+ lfo.processControlLogic();
+ }
+
+ // After the delay the LFO should start oscillate
+ // Let make sure output is accurate enough
+ double p_step = (440.0 / control_rate)
+ * Math.exp((freq - 6900.0) * (Math.log(2) / 1200.0));
+ double p = 0;
+ for (int i = 0; i < 30; i++) {
+ p += p_step;
+ double predicted_output = 0.5 + Math.sin(p * 2 * Math.PI) * 0.5;
+ if (Math.abs(predicted_output - lfo_output[0]) > 0.001)
+ throw new Exception("Incorrect LFO output ("
+ +predicted_output+" != "+lfo_output[0]+")!");
+ lfo.processControlLogic();
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ // Get default control rate from synthesizer
+ AudioSynthesizerPropertyInfo[] p = synth.getPropertyInfo(null);
+ for (int i = 0; i < p.length; i++) {
+ if (p[i].name.equals("control rate")) {
+ control_rate = ((Float) p[i].value).floatValue();
+ break;
+ }
+ }
+
+ // Test LFO under various configurations
+ for (int instance = 0; instance < 3; instance++)
+ for (int d1 = -3000; d1 < 0; d1 += 1000)
+ for (int d2 = 0; d2 < 5000; d2 += 1000)
+ for (int fr = -1000; fr < 1000; fr += 100) {
+ testLFO(true, instance,
+ (fr == -1000) ? Float.NEGATIVE_INFINITY : fr,
+ (d1 == -3000) ? Float.NEGATIVE_INFINITY : d1,
+ d2);
+ testLFO(false, instance,
+ (fr == -1000) ? Float.NEGATIVE_INFINITY : fr,
+ (d1 == -3000) ? Float.NEGATIVE_INFINITY : d1,
+ d2);
+ }
+
+ }
+}