Merge
This commit is contained in:
commit
33484a2710
20
jdk/README
20
jdk/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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
######################################################
|
||||
|
@ -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
|
||||
|
60
jdk/make/javax/swing/plaf/nimbus/Makefile
Normal file
60
jdk/make/javax/swing/plaf/nimbus/Makefile
Normal file
@ -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)
|
@ -51,6 +51,7 @@ SUBDIRS = \
|
||||
makeclasslist \
|
||||
strip_properties \
|
||||
spp \
|
||||
swing-nimbus \
|
||||
CharsetMapping
|
||||
|
||||
all build clean clobber::
|
||||
|
91
jdk/make/tools/swing-nimbus/Makefile
Normal file
91
jdk/make/tools/swing-nimbus/Makefile
Normal file
@ -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)
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>Here is a simple example bean that contains one property, foo, and the
|
||||
* proper pattern for implementing property change notification:
|
||||
* <pre><code>
|
||||
* 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;
|
||||
* }
|
||||
* }
|
||||
* </code></pre></p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>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()</p>
|
||||
*
|
||||
* <p><code>AbstractBean</code> also supports {@link VetoablePropertyChange} events.
|
||||
* These events are similar to <code>PropertyChange</code> 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:
|
||||
* <pre><code>
|
||||
* 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
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </code></pre></p>
|
||||
*
|
||||
* @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 <code>listener</code> 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 <code>listener</code> was added more than once to the same event
|
||||
* source, it will be notified one less time after being removed.
|
||||
* If <code>listener</code> 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().
|
||||
* <p>
|
||||
* If some listeners have been added with a named property, then
|
||||
* the returned array will be a mixture of PropertyChangeListeners
|
||||
* and <code>PropertyChangeListenerProxy</code>s. If the calling
|
||||
* method is interested in distinguishing the listeners then it must
|
||||
* test each element to see if it's a
|
||||
* <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
|
||||
* the parameter.
|
||||
*
|
||||
* <pre>
|
||||
* 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"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*</pre>
|
||||
*
|
||||
* @see java.beans.PropertyChangeListenerProxy
|
||||
* @return all of the <code>PropertyChangeListeners</code> 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 <code>propertyName</code> or <code>listener</code> 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 <code>listener</code> 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 <code>propertyName</code> is null, no exception is thrown and no
|
||||
* action is taken.
|
||||
* If <code>listener</code> 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 <code>PropertyChangeListeners</code> associated with
|
||||
* the named property. If no such listeners have been added,
|
||||
* or if <code>propertyName</code> 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.
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* No event is fired if old and new values are equal
|
||||
* and non-null.
|
||||
*
|
||||
* <p>
|
||||
* 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 <code>propertyName</code>
|
||||
* 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 <code>propertyName</code>
|
||||
* 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 <code>listener</code> 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 <code>listener</code> was added more than once to the same event
|
||||
* source, it will be notified one less time after being removed.
|
||||
* If <code>listener</code> 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
|
||||
* <p>
|
||||
* @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 <code>propertyName</code> or <code>listener</code> 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 <code>listener</code> 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 <code>propertyName</code> is null, no exception is thrown and no
|
||||
* action is taken.
|
||||
* If <code>listener</code> 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 <code>VetoableChangeListeners</code> associated with
|
||||
* the named property. If no such listeners have been added,
|
||||
* or if <code>propertyName</code> 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -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<ControlPoint> getControlPoints() {
|
||||
if (isSharpCorner()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
List<ControlPoint> points = new ArrayList<ControlPoint>();
|
||||
points.add(cp1);
|
||||
points.add(cp2);
|
||||
return points;
|
||||
}
|
||||
}
|
||||
|
||||
public HandleControlPoint getCp1() {
|
||||
return cp1;
|
||||
}
|
||||
|
||||
public HandleControlPoint getCp2() {
|
||||
return cp2;
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
// paint control line
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_LINE);
|
||||
g2.draw(new Line2D.Double(cp1.getX(), cp1.getY(), getX(), getY()));
|
||||
g2.draw(new Line2D.Double(getX(), getY(), cp2.getX(), cp2.getY()));
|
||||
// paint this control point
|
||||
Shape s;
|
||||
if (isSharpCorner()) {
|
||||
double size = pixelSize * 4d;
|
||||
GeneralPath path = new GeneralPath();
|
||||
path.moveTo(getX() - size, getY());
|
||||
path.lineTo(getX(), getY() + size);
|
||||
path.lineTo(getX() + size, getY());
|
||||
path.lineTo(getX(), getY() - size);
|
||||
path.closePath();
|
||||
s = path;
|
||||
} else {
|
||||
double size = pixelSize * 3d;
|
||||
s = new Ellipse2D.Double(getX() - size, getY() - size,
|
||||
size * 2, size * 2);
|
||||
}
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_FILL);
|
||||
g2.fill(s);
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_LINE);
|
||||
g2.draw(s);
|
||||
// paint child control points
|
||||
if (!isSharpCorner()) {
|
||||
cp1.paintControls(g2, pixelSize, true);
|
||||
cp2.paintControls(g2, pixelSize, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
makingChange = true;
|
||||
super.move(moveX, moveY, snapPixels);
|
||||
cp1.move(moveX, moveY, snapPixels);
|
||||
cp2.move(moveX, moveY, snapPixels);
|
||||
makingChange = false;
|
||||
}
|
||||
|
||||
public double getCp1X() {
|
||||
return cp1.getX();
|
||||
}
|
||||
|
||||
public void setCp1X(double v) {
|
||||
cp1.setX(v);
|
||||
}
|
||||
|
||||
public double getCp1Y() {
|
||||
return cp1.getY();
|
||||
}
|
||||
|
||||
public void setCp1Y(double v) {
|
||||
cp1.setY(v);
|
||||
}
|
||||
|
||||
public double getCp2X() {
|
||||
return cp2.getX();
|
||||
}
|
||||
|
||||
public void setCp2X(double v) {
|
||||
cp2.setX(v);
|
||||
}
|
||||
|
||||
public double getCp2Y() {
|
||||
return cp2.getY();
|
||||
}
|
||||
|
||||
public void setCp2Y(double v) {
|
||||
cp2.setY(v);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bezier handle control point
|
||||
|
||||
public class HandleControlPoint extends ControlPoint {
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
if (!isSharp()){
|
||||
double size = pixelSize * 3d;
|
||||
Shape s = new Ellipse2D.Double(getX() - size, getY() - size,
|
||||
size * 2, size * 2);
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_FILL);
|
||||
g2.fill(s);
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_LINE);
|
||||
g2.draw(s);
|
||||
g2.draw(new Rectangle2D.Double(getX() - (pixelSize / 2), getY() - (pixelSize / 2), pixelSize, pixelSize));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
return !isSharp() && super.isHit(p, pixelSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the line controled by this handle in or out of the parent BezierControlPoint sharp.
|
||||
*
|
||||
* @return <code>true</code> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
};
|
||||
}
|
@ -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 List<Layer> layers;
|
||||
private int nextLayerNameIndex = 1;
|
||||
private BufferedImage buffer;
|
||||
private boolean isValid = false;
|
||||
private Insets stretchingInsets = null;
|
||||
private Layer workingLayer = null;
|
||||
private PropertyChangeListener layersPropertyChangeListener;
|
||||
private UIDefaults canvasUIDefaults = null;
|
||||
private transient File resourcesDir;
|
||||
private transient File imagesDir;
|
||||
private transient File templatesDir;
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructor
|
||||
|
||||
/** Private constructor for JIBX */
|
||||
protected Canvas() {
|
||||
layersPropertyChangeListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
isValid = false;
|
||||
// pass on layer change
|
||||
int index = layers.indexOf((Layer) evt.getSource());
|
||||
if (index != -1) {
|
||||
firePropertyChange("layers[" + index + "]." + evt.getPropertyName(), evt.getOldValue(),
|
||||
evt.getNewValue());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Canvas(int width, int height) {
|
||||
this();
|
||||
stretchingInsets = new Insets(1, 1, 1, 1);
|
||||
layers = new ArrayList<Layer>();
|
||||
setSize(new Dimension(width, height));
|
||||
addLayer(new Layer());
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX before all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void preSet(IUnmarshallingContext context) {
|
||||
canvasUIDefaults = (UIDefaults) context.getUserContext();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
/**
|
||||
* Get the UIDefaults for this canvas. The UIDefaults is used to store default pallet of colors, fonts etc.
|
||||
*
|
||||
* @return Canvas UIDefaults
|
||||
*/
|
||||
public UIDefaults getUiDefaults() {
|
||||
return canvasUIDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UIDefaults for this canvas. The UIDefaults is used to store default pallet of colors, fonts etc.
|
||||
*
|
||||
* @param canvasUIDefaults Canvas UIDefaults
|
||||
*/
|
||||
public void setUiDefaults(UIDefaults canvasUIDefaults) {
|
||||
this.canvasUIDefaults = canvasUIDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current working layer, is is the layer that new shapes will be drawn into
|
||||
*
|
||||
* @return The current working layer, may be null if there is no working layer
|
||||
*/
|
||||
public Layer getWorkingLayer() {
|
||||
return workingLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current working layer, is is the layer that new shapes will be drawn into
|
||||
*
|
||||
* @param workingLayer the new working layer, must be a child of this canvas
|
||||
*/
|
||||
public void setWorkingLayer(Layer workingLayer) {
|
||||
Layer old = getWorkingLayer();
|
||||
this.workingLayer = workingLayer;
|
||||
firePropertyChange("workingLayer", old, getWorkingLayer());
|
||||
}
|
||||
|
||||
public int getNextLayerNameIndex() {
|
||||
return nextLayerNameIndex++;
|
||||
}
|
||||
|
||||
public Dimension getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Dimension size) {
|
||||
Dimension old = getSize();
|
||||
this.size = size;
|
||||
buffer = new BufferedImage(this.size.width, this.size.height, BufferedImage.TYPE_INT_ARGB);
|
||||
isValid = false;
|
||||
firePropertyChange("size", old, getSize());
|
||||
}
|
||||
|
||||
|
||||
public Insets getStretchingInsets() {
|
||||
return stretchingInsets;
|
||||
}
|
||||
|
||||
public void setStretchingInsets(Insets stretchingInsets) {
|
||||
Insets old = getStretchingInsets();
|
||||
this.stretchingInsets = stretchingInsets;
|
||||
firePropertyChange("stretchingInsets", old, getStretchingInsets());
|
||||
}
|
||||
|
||||
public BufferedImage getRenderedImage() {
|
||||
if (!isValid) {
|
||||
Graphics2D g2 = buffer.createGraphics();
|
||||
// clear
|
||||
g2.setComposite(AlphaComposite.Clear);
|
||||
g2.fillRect(0, 0, buffer.getWidth(), buffer.getHeight());
|
||||
// paint
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2.setComposite(AlphaComposite.SrcOver);
|
||||
for (int i = layers.size() - 1; i >= 0; i--) {
|
||||
layers.get(i).paint(g2, 1);
|
||||
}
|
||||
g2.dispose();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this Canvas has not been edited.
|
||||
* <p/>
|
||||
* TODO Currently this is not a bound property, but should be. That is, when the Canvas becomes edited
|
||||
* (usually due to the Layer having a shape added to it), then a property change event should be fired.
|
||||
*/
|
||||
public boolean isBlank() {
|
||||
return layers.size() == 0 || (layers.size() == 1 && layers.get(0).isEmpty());
|
||||
}
|
||||
|
||||
public File getResourcesDir() {
|
||||
return resourcesDir;
|
||||
}
|
||||
|
||||
public void setResourcesDir(File resourcesDir) {
|
||||
File old = getResourcesDir();
|
||||
this.resourcesDir = resourcesDir;
|
||||
firePropertyChange("resourcesDir", old, getResourcesDir());
|
||||
}
|
||||
|
||||
public File getImagesDir() {
|
||||
return imagesDir;
|
||||
}
|
||||
|
||||
public void setImagesDir(File imagesDir) {
|
||||
File old = getImagesDir();
|
||||
this.imagesDir = imagesDir;
|
||||
firePropertyChange("imagesDir", old, getImagesDir());
|
||||
}
|
||||
|
||||
public File getTemplatesDir() {
|
||||
return templatesDir;
|
||||
}
|
||||
|
||||
public void setTemplatesDir(File templatesDir) {
|
||||
File old = getTemplatesDir();
|
||||
this.templatesDir = templatesDir;
|
||||
firePropertyChange("templatesDir", old, getTemplatesDir());
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// LayerContainer Methods
|
||||
|
||||
public LayerContainer getParent() {
|
||||
// we are root so null
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addLayerToBottom(Layer layer) {
|
||||
layers.add(layer);
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(layersPropertyChangeListener);
|
||||
// no single layer changes so fire all changed event
|
||||
firePropertyChange("layers", null, layers);
|
||||
}
|
||||
|
||||
public void addLayer(int i, Layer layer) {
|
||||
layers.add(i, layer);
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(layersPropertyChangeListener);
|
||||
// no single layer changes so fire all changed event
|
||||
firePropertyChange("layers", null, layers);
|
||||
}
|
||||
|
||||
public void addLayer(Layer layer) {
|
||||
layers.add(0, layer);
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(layersPropertyChangeListener);
|
||||
// no single layer changes so fire all changed event
|
||||
firePropertyChange("layers", null, layers);
|
||||
}
|
||||
|
||||
public Layer getLayer(int index) {
|
||||
return layers.get(index);
|
||||
}
|
||||
|
||||
public int getLayerCount() {
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
public Iterator<Layer> getLayerIterator() {
|
||||
return Collections.unmodifiableList(layers).iterator();
|
||||
}
|
||||
|
||||
public Collection<Layer> getLayers() {
|
||||
return Collections.unmodifiableList(layers);
|
||||
}
|
||||
|
||||
public int indexOfLayer(Layer layer) {
|
||||
return layers.indexOf(layer);
|
||||
}
|
||||
|
||||
public void removeLayer(Layer layer) {
|
||||
int index = layers.indexOf(layer);
|
||||
if (index != -1) {
|
||||
layers.remove(layer);
|
||||
layer.removePropertyChangeListener(layersPropertyChangeListener);
|
||||
fireIndexedPropertyChange("layers", index, layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension getRootSize() {
|
||||
return getSize();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Helper Methods
|
||||
|
||||
/** Called by JIBX after "layers" has been filled so we can set parents and listeners */
|
||||
private void setupLayers() {
|
||||
for (Layer layer : layers) {
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(layersPropertyChangeListener);
|
||||
}
|
||||
// no single layer changes so fire all changed event
|
||||
firePropertyChange("layers", null, layers);
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ControlPoint
|
||||
*
|
||||
* @author Created by Jasper Potts (May 24, 2007)
|
||||
*/
|
||||
public class ControlPoint extends SimpleShape {
|
||||
protected Color fillColor;
|
||||
protected Color lineColor;
|
||||
protected DoubleBean x, y;
|
||||
|
||||
public ControlPoint() {
|
||||
this(new DoubleBean(), new DoubleBean());
|
||||
}
|
||||
|
||||
public ControlPoint(Color fillColor, Color lineColor) {
|
||||
this(new DoubleBean(), new DoubleBean(), fillColor, lineColor);
|
||||
}
|
||||
|
||||
public ControlPoint(double x, double y) {
|
||||
this(new DoubleBean(x), new DoubleBean(y));
|
||||
}
|
||||
|
||||
public ControlPoint(DoubleBean x, DoubleBean y) {
|
||||
this(x, y, GraphicsHelper.CONTROL_POINT_FILL, GraphicsHelper.CONTROL_POINT_LINE);
|
||||
}
|
||||
|
||||
public ControlPoint(DoubleBean x, DoubleBean y, Color fillColor, Color lineColor) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.fillColor = fillColor;
|
||||
this.lineColor = lineColor;
|
||||
x.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("position",
|
||||
new Point2D.Double((Double) evt.getOldValue(), getY()),
|
||||
getPosition());
|
||||
}
|
||||
});
|
||||
y.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("position",
|
||||
new Point2D.Double(getX(), (Double) evt.getOldValue()),
|
||||
getPosition());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x.getValue();
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y.getValue();
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x.setValue(x);
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y.setValue(y);
|
||||
}
|
||||
|
||||
public void setPosition(Point2D position) {
|
||||
x.setValue(position.getX());
|
||||
y.setValue(position.getY());
|
||||
}
|
||||
|
||||
public void setPosition(double x, double y) {
|
||||
setPosition(new Point2D.Double(x, y));
|
||||
}
|
||||
|
||||
public Point2D getPosition() {
|
||||
return new Point2D.Double(getX(), getY());
|
||||
}
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
double size = pixelSize * 4d;
|
||||
return new Rectangle2D.Double(getX() - size, getY() - size,
|
||||
size * 2, size * 2);
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
return getBounds(pixelSize).contains(p);
|
||||
}
|
||||
|
||||
|
||||
public Shape getShape() {
|
||||
return getBounds(0);
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g2, double pixelSize) {
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
Shape s = getBounds(pixelSize);
|
||||
g2.setColor(fillColor);
|
||||
g2.fill(s);
|
||||
g2.setColor(lineColor);
|
||||
g2.draw(s);
|
||||
}
|
||||
|
||||
public List<ControlPoint> getControlPoints() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
if (snapPixels) {
|
||||
setPosition(
|
||||
Math.round(x.getValue() + moveX),
|
||||
Math.round(y.getValue() + moveY));
|
||||
} else {
|
||||
setPosition(x.getValue() + moveX, y.getValue() + moveY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Copyright 1998-2004 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.
|
||||
-->
|
||||
|
||||
<!DOCTYPE binding SYSTEM "http://jibx.sourceforge.net">
|
||||
<binding>
|
||||
<!-- == PAINTS =========================================================================================== -->
|
||||
<mapping class="java.awt.Color"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.ColorMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.ColorMapper"/>
|
||||
<mapping name="matte" class="org.jdesktop.swingx.designer.paint.Matte" post-set="postSet">
|
||||
<value name="red" field="red" style="attribute"/>
|
||||
<value name="green" field="green" style="attribute"/>
|
||||
<value name="blue" field="blue" style="attribute"/>
|
||||
<value name="alpha" field="alpha" style="attribute"/>
|
||||
<value name="uiDefaultParentName" field="uiDefaultParentName" style="attribute" usage="optional"/>
|
||||
<value name="componentPropertyName" field="componentPropertyName" style="attribute" usage="optional"/>
|
||||
<value name="hueOffset" field="hueOffset" style="attribute"/>
|
||||
<value name="saturationOffset" field="saturationOffset" style="attribute"/>
|
||||
<value name="brightnessOffset" field="brightnessOffset" style="attribute"/>
|
||||
<value name="alphaOffset" field="alphaOffset" style="attribute"/>
|
||||
<value name="uiResource" field="uiResource" style="attribute" usage="optional" default="true"/>
|
||||
</mapping>
|
||||
<mapping class="org.jdesktop.swingx.designer.paint.AbstractGradient" abstract="true">
|
||||
<value name="cycleMethod" field="cycleMethod" style="attribute"/>
|
||||
<collection field="stops" set-method="setStops" pre-set="clear" create-type="java.util.ArrayList">
|
||||
<structure name="stop" type="org.jdesktop.swingx.designer.paint.GradientStop">
|
||||
<value name="position" field="position" style="attribute"/>
|
||||
<value name="midpoint" field="midpoint" style="attribute"/>
|
||||
<structure field="color" set-method="setColor"/>
|
||||
</structure>
|
||||
</collection>
|
||||
</mapping>
|
||||
<mapping name="gradient" class="org.jdesktop.swingx.designer.paint.Gradient"
|
||||
extends="org.jdesktop.swingx.designer.paint.AbstractGradient">
|
||||
<structure map-as="org.jdesktop.swingx.designer.paint.AbstractGradient"/>
|
||||
</mapping>
|
||||
<mapping name="radialGradient" class="org.jdesktop.swingx.designer.paint.RadialGradient"
|
||||
extends="org.jdesktop.swingx.designer.paint.AbstractGradient">
|
||||
<structure map-as="org.jdesktop.swingx.designer.paint.AbstractGradient"/>
|
||||
</mapping>
|
||||
<!-- == SHAPES =========================================================================================== -->
|
||||
<mapping class="org.jdesktop.swingx.designer.SimpleShape" abstract="true">
|
||||
<!--protected AffineTransform transform = new AffineTransform();-->
|
||||
</mapping>
|
||||
<mapping class="org.jdesktop.swingx.designer.PaintedShape" abstract="true"
|
||||
extends="org.jdesktop.swingx.designer.SimpleShape">
|
||||
<structure map-as="org.jdesktop.swingx.designer.SimpleShape"/>
|
||||
<structure field="paint"/>
|
||||
<structure name="paintPoints">
|
||||
<value name="x1" get-method="getPaintX1" set-method="setPaintX1" style="attribute"/>
|
||||
<value name="y1" get-method="getPaintY1" set-method="setPaintY1" style="attribute"/>
|
||||
<value name="x2" get-method="getPaintX2" set-method="setPaintX2" style="attribute"/>
|
||||
<value name="y2" get-method="getPaintY2" set-method="setPaintY2" style="attribute"/>
|
||||
</structure>
|
||||
</mapping>
|
||||
<mapping name="rectangle" class="org.jdesktop.swingx.designer.RectangleShape"
|
||||
extends="org.jdesktop.swingx.designer.PaintedShape">
|
||||
<structure map-as="org.jdesktop.swingx.designer.PaintedShape"/>
|
||||
<value name="x1" get-method="getX1" set-method="setX1" style="attribute"/>
|
||||
<value name="x2" get-method="getX2" set-method="setX2" style="attribute"/>
|
||||
<value name="y1" get-method="getY1" set-method="setY1" style="attribute"/>
|
||||
<value name="y2" get-method="getY2" set-method="setY2" style="attribute"/>
|
||||
<value name="rounding" get-method="getRounding" set-method="setRounding" style="attribute"/>
|
||||
</mapping>
|
||||
<mapping name="ellipse" class="org.jdesktop.swingx.designer.EllipseShape"
|
||||
extends="org.jdesktop.swingx.designer.PaintedShape">
|
||||
<structure map-as="org.jdesktop.swingx.designer.PaintedShape"/>
|
||||
<value name="x1" get-method="getX1" set-method="setX1" style="attribute"/>
|
||||
<value name="x2" get-method="getX2" set-method="setX2" style="attribute"/>
|
||||
<value name="y1" get-method="getY1" set-method="setY1" style="attribute"/>
|
||||
<value name="y2" get-method="getY2" set-method="setY2" style="attribute"/>
|
||||
</mapping>
|
||||
<mapping name="path" class="org.jdesktop.swingx.designer.PathShape"
|
||||
extends="org.jdesktop.swingx.designer.PaintedShape">
|
||||
<structure map-as="org.jdesktop.swingx.designer.PaintedShape"/>
|
||||
<collection name="points" get-method="getBezierControlPoints"
|
||||
set-method="setControlPoints" create-type="java.util.ArrayList">
|
||||
<structure name="point" type="org.jdesktop.swingx.designer.BezierControlPoint">
|
||||
<value name="x" get-method="getX" set-method="setX" style="attribute"/>
|
||||
<value name="y" get-method="getY" set-method="setY" style="attribute"/>
|
||||
<value name="cp1x" get-method="getCp1X" set-method="setCp1X" style="attribute"/>
|
||||
<value name="cp1y" get-method="getCp1Y" set-method="setCp1Y" style="attribute"/>
|
||||
<value name="cp2x" get-method="getCp2X" set-method="setCp2X" style="attribute"/>
|
||||
<value name="cp2y" get-method="getCp2Y" set-method="setCp2Y" style="attribute"/>
|
||||
</structure>
|
||||
</collection>
|
||||
</mapping>
|
||||
<!-- == EFFECTS =========================================================================================== -->
|
||||
<mapping class="org.jdesktop.swingx.designer.effects.ShadowEffect" abstract="true">
|
||||
<structure field="color"/>
|
||||
<value name="blendingMode" field="blendingMode" style="attribute"/>
|
||||
<value name="opacity" field="opacity" style="attribute"/>
|
||||
<value name="angle" field="angle" style="attribute"/>
|
||||
<value name="distance" field="distance" style="attribute"/>
|
||||
<value name="spread" field="spread" style="attribute"/>
|
||||
<value name="size" field="size" style="attribute"/>
|
||||
</mapping>
|
||||
<mapping name="dropShadow" class="org.jdesktop.swingx.designer.effects.DropShadowEffect"
|
||||
extends="org.jdesktop.swingx.designer.effects.ShadowEffect">
|
||||
<structure map-as="org.jdesktop.swingx.designer.effects.ShadowEffect"/>
|
||||
</mapping>
|
||||
<mapping name="innerShadow" class="org.jdesktop.swingx.designer.effects.InnerShadowEffect"
|
||||
extends="org.jdesktop.swingx.designer.effects.ShadowEffect">
|
||||
<structure map-as="org.jdesktop.swingx.designer.effects.ShadowEffect"/>
|
||||
</mapping>
|
||||
<mapping name="innerGlow" class="org.jdesktop.swingx.designer.effects.InnerGlowEffect"
|
||||
extends="org.jdesktop.swingx.designer.effects.ShadowEffect">
|
||||
<structure map-as="org.jdesktop.swingx.designer.effects.ShadowEffect"/>
|
||||
</mapping>
|
||||
<mapping name="outerGlow" class="org.jdesktop.swingx.designer.effects.OuterGlowEffect"
|
||||
extends="org.jdesktop.swingx.designer.effects.ShadowEffect">
|
||||
<structure map-as="org.jdesktop.swingx.designer.effects.ShadowEffect"/>
|
||||
</mapping>
|
||||
<!-- == TEMPLATE LAYER ================================================================================== -->
|
||||
<mapping name="templateLayer" class="org.jdesktop.swingx.designer.TemplateLayer"
|
||||
extends="org.jdesktop.swingx.designer.Layer" post-set="postInit">
|
||||
<structure map-as="org.jdesktop.swingx.designer.Layer"/>
|
||||
<value name="fileName" field="fileName" style="attribute"/>
|
||||
</mapping>
|
||||
<!-- == LAYER =========================================================================================== -->
|
||||
<mapping name="layer" class="org.jdesktop.swingx.designer.Layer"
|
||||
extends="org.jdesktop.swingx.designer.SimpleShape" post-set="postInit">
|
||||
<structure map-as="org.jdesktop.swingx.designer.SimpleShape"/>
|
||||
<value name="name" field="name" style="attribute"/>
|
||||
<value name="type" field="type" style="attribute" default="standard"/>
|
||||
<value name="opacity" field="opacity"/>
|
||||
<value name="fillOpacity" field="fillOpacity"/>
|
||||
<value name="blendingMode" field="blendingMode"/>
|
||||
<value name="locked" field="locked"/>
|
||||
<value name="visible" field="visible"/>
|
||||
<structure name="shapes">
|
||||
<collection field="shapes" create-type="java.util.ArrayList"/>
|
||||
</structure>
|
||||
<structure name="effects">
|
||||
<collection field="effects" create-type="java.util.ArrayList"/>
|
||||
</structure>
|
||||
</mapping>
|
||||
<!-- == CANVAS =========================================================================================== -->
|
||||
<mapping name="canvas" class="org.jdesktop.swingx.designer.Canvas" pre-set="preSet" post-set="setupLayers">
|
||||
<structure name="size" get-method="getSize" set-method="setSize"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.DimensionMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.DimensionMapper"/>
|
||||
<value name="nextLayerNameIndex" field="nextLayerNameIndex"/>
|
||||
<structure name="stretchingInsets" field="stretchingInsets"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"/>
|
||||
<collection field="layers" create-type="java.util.ArrayList"/>
|
||||
</mapping>
|
||||
</binding>
|
@ -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;
|
||||
|
||||
import org.jdesktop.beans.AbstractBean;
|
||||
|
||||
/**
|
||||
* DoubleBean - Simple bean for a observable double value
|
||||
*
|
||||
* @author Created by Jasper Potts (May 25, 2007)
|
||||
*/
|
||||
public class DoubleBean extends AbstractBean {
|
||||
private double value = 0;
|
||||
|
||||
public DoubleBean() {}
|
||||
|
||||
public DoubleBean(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(double value) {
|
||||
double old = this.value;
|
||||
this.value = value;
|
||||
firePropertyChange("value", old, this.value);
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DoubleBean that = (DoubleBean) o;
|
||||
|
||||
if (Double.compare(that.value, value) != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
long temp = value != +0.0d ? Double.doubleToLongBits(value) : 0L;
|
||||
return (int) (temp ^ (temp >>> 32));
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
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.List;
|
||||
|
||||
/**
|
||||
* EllipseShape
|
||||
*
|
||||
* @author Created by Jasper Potts (May 22, 2007)
|
||||
*/
|
||||
public class EllipseShape extends PaintedShape {
|
||||
|
||||
private DoubleBean x1 = new DoubleBean();
|
||||
private DoubleBean x2 = new DoubleBean();
|
||||
private DoubleBean y1 = new DoubleBean();
|
||||
private DoubleBean y2 = new DoubleBean();
|
||||
private ControlPoint tl = new ControlPoint(x1, y1);
|
||||
private ControlPoint tr = new ControlPoint(x2, y1);
|
||||
private ControlPoint bl = new ControlPoint(x1, y2);
|
||||
private ControlPoint br = new ControlPoint(x2, y2);
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
/** private noargs constructor for JIBX */
|
||||
private EllipseShape() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public EllipseShape(UIDefaults canvasUiDefaults) {
|
||||
super(canvasUiDefaults);
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("bounds", null, getBounds(0));
|
||||
}
|
||||
};
|
||||
x1.addPropertyChangeListener(listener);
|
||||
y1.addPropertyChangeListener(listener);
|
||||
x2.addPropertyChangeListener(listener);
|
||||
y2.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public EllipseShape(double x, double y, double w, double h) {
|
||||
this();
|
||||
x1.setValue(x);
|
||||
y1.setValue(y);
|
||||
x2.setValue(x + w);
|
||||
y2.setValue(y + h);
|
||||
}
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
double left = Math.min(x1.getValue(), x2.getValue());
|
||||
double right = Math.max(x1.getValue(), x2.getValue());
|
||||
double top = Math.min(y1.getValue(), y2.getValue());
|
||||
double bottom = Math.max(y1.getValue(), y2.getValue());
|
||||
return new Rectangle2D.Double(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
public Ellipse2D getShape() {
|
||||
double left = Math.min(x1.getValue(), x2.getValue());
|
||||
double right = Math.max(x1.getValue(), x2.getValue());
|
||||
double top = Math.min(y1.getValue(), y2.getValue());
|
||||
double bottom = Math.max(y1.getValue(), y2.getValue());
|
||||
return new Ellipse2D.Double(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
return getBounds(pixelSize).contains(p);
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g2, double pixelSize) {
|
||||
g2.setPaint(getPaint());
|
||||
g2.fill(getShape());
|
||||
}
|
||||
|
||||
public void setFrame(double x1, double y1, double x2, double y2) {
|
||||
this.x1.setValue(x1);
|
||||
this.y1.setValue(y1);
|
||||
this.x2.setValue(x2);
|
||||
this.y2.setValue(y2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Rectangle2D bounds = getBounds(0);
|
||||
return "ELLIPSE { x=" + bounds.getX() + ", y=" + bounds.getY() + ", w=" + bounds.getWidth() + ", h=" + bounds.getHeight() + " }";
|
||||
}
|
||||
|
||||
public List<ControlPoint> getControlPoints() {
|
||||
List<ControlPoint> points = new ArrayList<ControlPoint>();
|
||||
points.addAll(super.getControlPoints());
|
||||
points.add(tl);
|
||||
points.add(tr);
|
||||
points.add(bl);
|
||||
points.add(br);
|
||||
return points;
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
if (paintControlLines) {
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
g2.setColor(GraphicsHelper.CONTROL_LINE);
|
||||
g2.draw(getShape());
|
||||
}
|
||||
tl.paintControls(g2, pixelSize, true);
|
||||
tr.paintControls(g2, pixelSize, true);
|
||||
bl.paintControls(g2, pixelSize, true);
|
||||
br.paintControls(g2, pixelSize, true);
|
||||
// super.paintControls(g2, pixelSize, paintControlLines);
|
||||
}
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
if (snapPixels) {
|
||||
x1.setValue(Math.round(x1.getValue() + moveX));
|
||||
x2.setValue(Math.round(x2.getValue() + moveX));
|
||||
y1.setValue(Math.round(y1.getValue() + moveY));
|
||||
y2.setValue(Math.round(y2.getValue() + moveY));
|
||||
} else {
|
||||
x1.setValue(x1.getValue() + moveX);
|
||||
x2.setValue(x2.getValue() + moveX);
|
||||
y1.setValue(y1.getValue() + moveY);
|
||||
y2.setValue(y2.getValue() + moveY);
|
||||
}
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return x1.getValue();
|
||||
}
|
||||
|
||||
public void setX1(double x1) {
|
||||
this.x1.setValue(x1);
|
||||
}
|
||||
|
||||
public double getX2() {
|
||||
return x2.getValue();
|
||||
}
|
||||
|
||||
public void setX2(double x2) {
|
||||
this.x2.setValue(x2);
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return y1.getValue();
|
||||
}
|
||||
|
||||
public void setY1(double y1) {
|
||||
this.y1.setValue(y1);
|
||||
}
|
||||
|
||||
public double getY2() {
|
||||
return y2.getValue();
|
||||
}
|
||||
|
||||
public void setY2(double y2) {
|
||||
this.y2.setValue(y2);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.Color;
|
||||
|
||||
/**
|
||||
* GraphicsHelper
|
||||
*
|
||||
* @author Created by Jasper Potts (May 29, 2007)
|
||||
*/
|
||||
public class GraphicsHelper {
|
||||
public static final Color FILL_LINE = Color.BLUE;
|
||||
public static final Color FILL_CP_LINE = Color.BLUE;
|
||||
public static final Color FILL_CP_FILL = Color.WHITE;
|
||||
public static final Color CONTROL_LINE = Color.RED;
|
||||
public static final Color CONTROL_POINT_LINE = Color.RED;
|
||||
public static final Color CONTROL_POINT_FILL = Color.WHITE;
|
||||
public static final Color BEZIER_CONTROL_POINT_LINE = CONTROL_POINT_LINE;
|
||||
public static final Color BEZIER_CONTROL_POINT_FILL = CONTROL_POINT_FILL;
|
||||
public static final Color BEZIER_CONTROL_LINE = Color.DARK_GRAY;
|
||||
|
||||
}
|
@ -0,0 +1,443 @@
|
||||
/*
|
||||
* 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.swingx.designer.effects.Effect;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Layer
|
||||
*
|
||||
* @author Created by Jasper Potts (May 22, 2007)
|
||||
*/
|
||||
public class Layer extends SimpleShape implements Iterable<SimpleShape>, LayerContainer {
|
||||
public static enum LayerType {
|
||||
standard, template
|
||||
}
|
||||
|
||||
private String name;
|
||||
protected LayerType type = LayerType.standard;
|
||||
/** List of shapes in this layer, first shape is painted on top */
|
||||
private List<SimpleShape> shapes = new ArrayList<SimpleShape>();
|
||||
private List<Effect> effects = new ArrayList<Effect>();
|
||||
private double opacity = 1;
|
||||
private double fillOpacity = 1;
|
||||
private BlendingMode blendingMode = BlendingMode.NORMAL;
|
||||
private boolean locked = false;
|
||||
private boolean visible = true;
|
||||
private PropertyChangeListener shapeChangeListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
int index = shapes.indexOf((SimpleShape) evt.getSource());
|
||||
firePropertyChange("shapes[" + index + "]." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
private PropertyChangeListener effectChangeListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
int index = effects.indexOf((Effect) evt.getSource());
|
||||
System.out.println(
|
||||
"Layer.propertyChange EFFECT PROPERTY CHANGED " + evt.getSource() + " -- " + evt.getPropertyName());
|
||||
firePropertyChange("effects[" + index + "]." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
private BufferedImage buffer = null;
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
public Layer() {
|
||||
}
|
||||
|
||||
public Layer(String name) {
|
||||
this();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** Called by JIBX after populating this layer so we can add listeners to children */
|
||||
protected void postInit() {
|
||||
for (SimpleShape shape : shapes) {
|
||||
shape.addPropertyChangeListener(shapeChangeListener);
|
||||
shape.setParent(this);
|
||||
}
|
||||
for (Effect effect : effects) {
|
||||
effect.addPropertyChangeListener(effectChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
public LayerType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
boolean old = isLocked();
|
||||
this.locked = locked;
|
||||
firePropertyChange("locked", old, isLocked());
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
boolean old = isVisible();
|
||||
this.visible = visible;
|
||||
firePropertyChange("visible", old, isVisible());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
String old = getName();
|
||||
this.name = name;
|
||||
firePropertyChange("name", old, getName());
|
||||
}
|
||||
|
||||
public void setParent(LayerContainer parent) {
|
||||
super.setParent(parent);
|
||||
// generate a name if null
|
||||
if (name == null) {
|
||||
Canvas c = null;
|
||||
LayerContainer p = parent;
|
||||
while (true) {
|
||||
if (p instanceof Canvas) {
|
||||
c = (Canvas) p;
|
||||
break;
|
||||
} else if (p == null) {
|
||||
break;
|
||||
}
|
||||
p = p.getParent();
|
||||
}
|
||||
if (c != null) {
|
||||
setName("Layer " + c.getNextLayerNameIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add shape to top of layer so it paints above all other shapes
|
||||
*
|
||||
* @param shape The shape to add
|
||||
*/
|
||||
public void add(SimpleShape shape) {
|
||||
shapes.add(0, shape);
|
||||
shape.setParent(this);
|
||||
shape.addPropertyChangeListener(shapeChangeListener);
|
||||
fireIndexedPropertyChange("shapes", 0, null, shape);
|
||||
}
|
||||
|
||||
public void remove(SimpleShape shape) {
|
||||
int index = shapes.indexOf(shape);
|
||||
if (index != -1) {
|
||||
shapes.remove(shape);
|
||||
shape.setParent(null);
|
||||
fireIndexedPropertyChange("shapes", index, shape, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifianle iterator over a set of elements of type SimpleShape.
|
||||
*
|
||||
* @return an Iterator.
|
||||
*/
|
||||
public Iterator<SimpleShape> iterator() {
|
||||
return Collections.unmodifiableList(shapes).iterator();
|
||||
}
|
||||
|
||||
|
||||
public List<Effect> getEffects() {
|
||||
return Collections.unmodifiableList(effects);
|
||||
}
|
||||
|
||||
public void addEffect(Effect effect) {
|
||||
int index = effects.size();
|
||||
effects.add(effect);
|
||||
effect.addPropertyChangeListener(effectChangeListener);
|
||||
fireIndexedPropertyChange("effects", index, null, effects);
|
||||
}
|
||||
|
||||
public void removeEffect(Effect effect) {
|
||||
int index = effects.indexOf(effect);
|
||||
if (index != -1) {
|
||||
effects.remove(effect);
|
||||
effect.removePropertyChangeListener(effectChangeListener);
|
||||
fireIndexedPropertyChange("effects", index, effect, null);
|
||||
}
|
||||
}
|
||||
|
||||
public double getOpacity() {
|
||||
return opacity;
|
||||
}
|
||||
|
||||
public void setOpacity(double opacity) {
|
||||
if (opacity < 0 || opacity > 1) return;
|
||||
double old = getOpacity();
|
||||
this.opacity = opacity;
|
||||
firePropertyChange("opacity", old, getOpacity());
|
||||
}
|
||||
|
||||
public double getFillOpacity() {
|
||||
return fillOpacity;
|
||||
}
|
||||
|
||||
public void setFillOpacity(double fillOpacity) {
|
||||
if (fillOpacity < 0 || fillOpacity > 1) return;
|
||||
double old = getFillOpacity();
|
||||
this.fillOpacity = fillOpacity;
|
||||
firePropertyChange("fillOpacity", old, getFillOpacity());
|
||||
}
|
||||
|
||||
public BlendingMode getBlendingMode() {
|
||||
return blendingMode;
|
||||
}
|
||||
|
||||
public void setBlendingMode(BlendingMode blendingMode) {
|
||||
BlendingMode old = getBlendingMode();
|
||||
this.blendingMode = blendingMode;
|
||||
firePropertyChange("blendingMode", old, getBlendingMode());
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Layer Methods
|
||||
|
||||
/**
|
||||
* Get the parent canvas that contains this layer
|
||||
*
|
||||
* @return Parant canvas, or null if the layer is not in a canvas
|
||||
*/
|
||||
public Canvas getCanvas() {
|
||||
LayerContainer lc = this;
|
||||
while (lc != null) {
|
||||
if (lc instanceof Canvas) return (Canvas) lc;
|
||||
lc = lc.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<SimpleShape> getShapes() {
|
||||
return new ArrayList<SimpleShape>(shapes);
|
||||
}
|
||||
|
||||
public List<SimpleShape> getIntersectingShapes(Point2D p, double pixelSize) {
|
||||
if (isLocked() || !isVisible()) return Collections.emptyList();
|
||||
List<SimpleShape> intersectingShapes = new ArrayList<SimpleShape>();
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape instanceof Layer) {
|
||||
intersectingShapes.addAll(((Layer) shape).getIntersectingShapes(p, pixelSize));
|
||||
} else {
|
||||
if (shape.isHit(p, pixelSize)) intersectingShapes.add(shape);
|
||||
}
|
||||
}
|
||||
return intersectingShapes;
|
||||
}
|
||||
|
||||
public List<SimpleShape> getIntersectingShapes(Rectangle2D rect, double pixelSize) {
|
||||
if (isLocked() || !isVisible()) return Collections.emptyList();
|
||||
List<SimpleShape> intersectingShapes = new ArrayList<SimpleShape>();
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape instanceof Layer) {
|
||||
intersectingShapes.addAll(((Layer) shape).getIntersectingShapes(rect, pixelSize));
|
||||
} else {
|
||||
if (shape.intersects(rect, pixelSize)) intersectingShapes.add(shape);
|
||||
}
|
||||
}
|
||||
return intersectingShapes;
|
||||
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return shapes.isEmpty();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// SimpleShape Methods
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
Rectangle2D.Double rect = new Rectangle2D.Double();
|
||||
for (SimpleShape shape : shapes) {
|
||||
rect.add(shape.getBounds(pixelSize));
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
public Shape getShape() {
|
||||
return getBounds(0);
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
if (isLocked() || !isVisible()) return false;
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape.isHit(p, pixelSize)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean intersects(Rectangle2D rect, double pixelSize) {
|
||||
if (isLocked() || !isVisible()) return false;
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape.intersects(rect, pixelSize)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<ControlPoint> getControlPoints() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g2, double pixelSize) {
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// LayerContainer Methods
|
||||
|
||||
public void addLayer(int i, Layer layer) {
|
||||
// get existing layer at index i
|
||||
Layer existingLayer = getLayer(i);
|
||||
if (existingLayer == null) {
|
||||
addLayer(layer);
|
||||
} else {
|
||||
int index = indexOfLayer(existingLayer);
|
||||
shapes.add(index, layer);
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(shapeChangeListener);
|
||||
fireIndexedPropertyChange("layers", index, null, layer);
|
||||
}
|
||||
}
|
||||
|
||||
public void addLayer(Layer layer) {
|
||||
shapes.add(layer);
|
||||
layer.setParent(this);
|
||||
layer.addPropertyChangeListener(shapeChangeListener);
|
||||
int index = indexOfLayer(layer);
|
||||
fireIndexedPropertyChange("layers", index, null, layer);
|
||||
}
|
||||
|
||||
public Layer getLayer(int index) {
|
||||
int i = -1;
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape instanceof Layer) i++;
|
||||
if (i == index) return (Layer) shape;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getLayerCount() {
|
||||
int count = 0;
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape instanceof Layer) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
public Collection<Layer> getLayers() {
|
||||
List<Layer> layers = new ArrayList<Layer>();
|
||||
for (SimpleShape shape : shapes) {
|
||||
if (shape instanceof Layer) layers.add((Layer) shape);
|
||||
}
|
||||
return Collections.unmodifiableList(layers);
|
||||
}
|
||||
|
||||
public Iterator<Layer> getLayerIterator() {
|
||||
return new Iterator<Layer>() {
|
||||
private int index = 0;
|
||||
|
||||
public boolean hasNext() {
|
||||
for (int i = index; i < shapes.size(); i++) {
|
||||
if (shapes.get(i) instanceof Layer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Layer next() {
|
||||
for (; index < shapes.size(); index++) {
|
||||
if (shapes.get(index) instanceof Layer) {
|
||||
Layer nextLayer = (Layer) shapes.get(index);
|
||||
index++; // increment index so we don't find the same one again
|
||||
return nextLayer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int indexOfLayer(Layer layer) {
|
||||
int i = -1;
|
||||
for (SimpleShape s : shapes) {
|
||||
if (s instanceof Layer) i++;
|
||||
if (s == layer) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void removeLayer(Layer layer) {
|
||||
int index = indexOfLayer(layer);
|
||||
if (index != -1) {
|
||||
shapes.remove(layer);
|
||||
layer.removePropertyChangeListener(shapeChangeListener);
|
||||
fireIndexedPropertyChange("layers", index, layer, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Dimension getRootSize() {
|
||||
return getParent().getRootSize();
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.Dimension;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* LayerContainer
|
||||
*
|
||||
* @author Created by Jasper Potts (May 31, 2007)
|
||||
*/
|
||||
public interface LayerContainer {
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
public LayerContainer getParent();
|
||||
|
||||
public void addLayer(Layer layer);
|
||||
|
||||
public void addLayer(int i, Layer layer);
|
||||
|
||||
public void removeLayer(Layer layer);
|
||||
|
||||
public int getLayerCount();
|
||||
|
||||
public Layer getLayer(int index);
|
||||
|
||||
public int indexOfLayer(Layer layer);
|
||||
|
||||
public Iterator<Layer> getLayerIterator();
|
||||
|
||||
public Collection<Layer> getLayers();
|
||||
|
||||
/**
|
||||
* Get the size in pixels of the root of the layer tree, this is usualy a canvas
|
||||
*
|
||||
* @return The size of the whole layer tree
|
||||
*/
|
||||
public Dimension getRootSize();
|
||||
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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.swingx.designer.paint.Matte;
|
||||
import org.jdesktop.swingx.designer.paint.PaintModel;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.Paint;
|
||||
import java.awt.RadialGradientPaint;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
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.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PaintedShape
|
||||
*
|
||||
* @author Created by Jasper Potts (May 22, 2007)
|
||||
*/
|
||||
public abstract class PaintedShape extends SimpleShape {
|
||||
|
||||
private PaintModel paint;
|
||||
// control points for paint control types
|
||||
private DoubleBean px1 = new DoubleBean(0.25);
|
||||
private DoubleBean px2 = new DoubleBean(0.75);
|
||||
private DoubleBean py1 = new DoubleBean(0);
|
||||
private DoubleBean py2 = new DoubleBean(1);
|
||||
private ControlPoint ptl = new PaintControlPoint(px1, py1);
|
||||
private ControlPoint ptr = new PaintControlPoint(px2, py1);
|
||||
private ControlPoint pbl = new PaintControlPoint(px1, py2);
|
||||
private ControlPoint pbr = new PaintControlPoint(px2, py2);
|
||||
private PropertyChangeListener paintListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("paint." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
|
||||
protected PaintedShape() {
|
||||
px1.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("x1", evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
py1.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("y1", evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
px2.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("x2", evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
py2.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("y2", evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected PaintedShape(UIDefaults canvasUiDefaults) {
|
||||
this();
|
||||
setPaintModel(new Matte(Color.ORANGE, canvasUiDefaults));
|
||||
}
|
||||
|
||||
public PaintModel getPaintModel() {
|
||||
return paint;
|
||||
}
|
||||
|
||||
public void setPaintModel(PaintModel paint) {
|
||||
PaintModel old = getPaintModel();
|
||||
if (old != null) old.removePropertyChangeListener(paintListener);
|
||||
this.paint = paint;
|
||||
this.paint.addPropertyChangeListener(paintListener);
|
||||
firePropertyChange("paintModel", old, getPaintModel());
|
||||
}
|
||||
|
||||
public Paint getPaint() {
|
||||
Paint p = getPaintModel().getPaint();
|
||||
if (p instanceof Color) {
|
||||
return p;
|
||||
}
|
||||
//resize p as necessary to fit the bounds of this PaintedShape
|
||||
Rectangle2D bounds = getBounds(0);
|
||||
if (p instanceof LinearGradientPaint) {
|
||||
LinearGradientPaint lgp = (LinearGradientPaint) p;
|
||||
return new LinearGradientPaint(
|
||||
convertLocalPoint(ptl.getPosition(), bounds),
|
||||
convertLocalPoint(pbr.getPosition(), bounds),
|
||||
lgp.getFractions(),
|
||||
lgp.getColors());
|
||||
} else if (p instanceof RadialGradientPaint) {
|
||||
RadialGradientPaint rgp = (RadialGradientPaint) p;
|
||||
Point2D outer = convertLocalPoint(ptl.getPosition(), bounds);
|
||||
Point2D center = convertLocalPoint(pbr.getPosition(), bounds);
|
||||
double deltaX = Math.abs(center.getX() - outer.getX());
|
||||
double deltaY = Math.abs(center.getY() - outer.getY());
|
||||
float radius = (float) Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
|
||||
return new RadialGradientPaint(
|
||||
center,
|
||||
radius,
|
||||
rgp.getFractions(),
|
||||
rgp.getColors());
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends ControlPoint> getControlPoints() {
|
||||
switch (paint.getPaintControlType()) {
|
||||
case control_line:
|
||||
return Arrays.asList(ptl, pbr);
|
||||
case control_rect:
|
||||
return Arrays.asList(ptl, ptr, pbl, pbr);
|
||||
default:
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public void paintFillControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
switch (paint.getPaintControlType()) {
|
||||
case control_line:
|
||||
Point2D p1 = convertLocalPoint(ptl.getPosition(), PaintedShape.this.getBounds(0));
|
||||
Point2D p2 = convertLocalPoint(pbr.getPosition(), PaintedShape.this.getBounds(0));
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
g2.setColor(GraphicsHelper.FILL_LINE);
|
||||
g2.draw(new Line2D.Double(p1.getX(), p1.getY(), p2.getX(), p2.getY()));
|
||||
ptl.paintControls(g2, pixelSize, true);
|
||||
pbr.paintControls(g2, pixelSize, true);
|
||||
break;
|
||||
case control_rect:
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
g2.setColor(GraphicsHelper.FILL_LINE);
|
||||
g2.draw(new Rectangle2D.Double(
|
||||
px1.getValue(),
|
||||
py1.getValue(),
|
||||
px2.getValue() - px1.getValue(),
|
||||
py2.getValue() - py1.getValue()));
|
||||
ptl.paintControls(g2, pixelSize, true);
|
||||
ptr.paintControls(g2, pixelSize, true);
|
||||
pbl.paintControls(g2, pixelSize, true);
|
||||
pbr.paintControls(g2, pixelSize, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
for (ControlPoint controlPoint : getControlPoints()) {
|
||||
if (!(controlPoint instanceof PaintControlPoint)) controlPoint.move(moveX, moveY, snapPixels);
|
||||
}
|
||||
}
|
||||
|
||||
public double getPaintX1() {
|
||||
return px1.getValue();
|
||||
}
|
||||
|
||||
public void setPaintX1(double x1) {
|
||||
this.px1.setValue(x1);
|
||||
}
|
||||
|
||||
public double getPaintX2() {
|
||||
return px2.getValue();
|
||||
}
|
||||
|
||||
public void setPaintX2(double x2) {
|
||||
this.px2.setValue(x2);
|
||||
}
|
||||
|
||||
public double getPaintY1() {
|
||||
return py1.getValue();
|
||||
}
|
||||
|
||||
public void setPaintY1(double y1) {
|
||||
this.py1.setValue(y1);
|
||||
}
|
||||
|
||||
public double getPaintY2() {
|
||||
return py2.getValue();
|
||||
}
|
||||
|
||||
public void setPaintY2(double y2) {
|
||||
this.py2.setValue(y2);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Private helper methods
|
||||
|
||||
private Point2D convertLocalPoint(Point2D point, Rectangle2D bounds) {
|
||||
point.setLocation(
|
||||
bounds.getX() + (point.getX() * bounds.getWidth()),
|
||||
bounds.getY() + (point.getY() * bounds.getHeight())
|
||||
);
|
||||
return point;
|
||||
}
|
||||
|
||||
private Point2D convertScreenPoint(Point2D point, Rectangle2D bounds) {
|
||||
return new Point2D.Double(
|
||||
(point.getX() - bounds.getX()) / bounds.getWidth(),
|
||||
(point.getY() - bounds.getY()) / bounds.getHeight()
|
||||
);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Gradient ControlPoint
|
||||
|
||||
/**
|
||||
* A Special ControlPoint thats internal values are in coordinates relative to the shapes bounds. With 0,0 being the
|
||||
* top left of the shape and 1.0X == shape width and 1.0Y == shapes height.
|
||||
*/
|
||||
public class PaintControlPoint extends ControlPoint {
|
||||
public PaintControlPoint() {
|
||||
super(GraphicsHelper.FILL_CP_FILL, GraphicsHelper.FILL_CP_LINE);
|
||||
}
|
||||
|
||||
public PaintControlPoint(DoubleBean x, DoubleBean y) {
|
||||
super(x, y, GraphicsHelper.FILL_CP_FILL, GraphicsHelper.FILL_CP_LINE);
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
Point2D p = convertLocalPoint(getPosition(), PaintedShape.this.getBounds(0));
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
double size = pixelSize * 4d;
|
||||
Shape s = new Ellipse2D.Double(p.getX() - size, p.getY() - size,
|
||||
size * 2, size * 2);
|
||||
g2.setPaint(new GradientPaint(
|
||||
(float) p.getX(), (float) (p.getY() - size), Color.CYAN,
|
||||
(float) p.getX(), (float) (p.getY() + size), Color.WHITE
|
||||
));
|
||||
g2.fill(s);
|
||||
g2.setColor(GraphicsHelper.FILL_CP_LINE);
|
||||
g2.draw(s);
|
||||
}
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
Rectangle2D bounds = PaintedShape.this.getBounds(0);
|
||||
moveX = moveX / bounds.getWidth();
|
||||
moveY = moveY / bounds.getHeight();
|
||||
if (snapPixels) {
|
||||
// snap to neareast 0.5
|
||||
double newX = Math.round((x.getValue() + moveX) * 2d) / 2d;
|
||||
double newY = Math.round((y.getValue() + moveY) * 2d) / 2d;
|
||||
setPosition(newX, newY);
|
||||
} else {
|
||||
setPosition(x.getValue() + moveX, y.getValue() + moveY);
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
Point2D p = convertLocalPoint(getPosition(), PaintedShape.this.getBounds(0));
|
||||
double size = pixelSize * 4d;
|
||||
return new Rectangle2D.Double(p.getX() - size, p.getY() - size,
|
||||
size * 2, size * 2);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
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.List;
|
||||
|
||||
/**
|
||||
* PathShape
|
||||
*
|
||||
* @author Created by Jasper Potts (May 29, 2007)
|
||||
*/
|
||||
public class PathShape extends PaintedShape {
|
||||
|
||||
private Shape cachedShape = null;
|
||||
private List<BezierControlPoint> controlPoints = new ArrayList<BezierControlPoint>();
|
||||
private PropertyChangeListener cpListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
rebuildShape();
|
||||
}
|
||||
};
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
/** private noargs constructor for JIBX */
|
||||
private PathShape() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public PathShape(UIDefaults canvasUiDefaults) {
|
||||
super(canvasUiDefaults);
|
||||
}
|
||||
|
||||
public BezierControlPoint addPoint(double x, double y) {
|
||||
BezierControlPoint cp = new BezierControlPoint(x, y);
|
||||
controlPoints.add(cp);
|
||||
cp.addPropertyChangeListener(cpListener);
|
||||
// update shape
|
||||
rebuildShape();
|
||||
// return new control point
|
||||
return cp;
|
||||
}
|
||||
|
||||
public Shape getShape() {
|
||||
if (cachedShape == null) {
|
||||
rebuildShape();
|
||||
}
|
||||
return cachedShape;
|
||||
}
|
||||
|
||||
private void rebuildShape() {
|
||||
GeneralPath path = new GeneralPath();
|
||||
BezierControlPoint first, last;
|
||||
first = last = controlPoints.get(0);
|
||||
path.moveTo((float) first.getX(), (float) first.getY());
|
||||
for (int i = 0; i < controlPoints.size(); i++) {
|
||||
BezierControlPoint controlPoint = controlPoints.get(i);
|
||||
if (last.getCp2().isSharp() && controlPoint.getCp1().isSharp()) {
|
||||
path.lineTo(controlPoint.getX(), controlPoint.getY());
|
||||
} else {
|
||||
path.curveTo(
|
||||
(float) last.getCp2().getX(), (float) last.getCp2().getY(),
|
||||
(float) controlPoint.getCp1().getX(), (float) controlPoint.getCp1().getY(),
|
||||
(float) controlPoint.getX(), (float) controlPoint.getY()
|
||||
);
|
||||
}
|
||||
last = controlPoint;
|
||||
}
|
||||
// close path
|
||||
if (last.getCp2().isSharp() && first.getCp1().isSharp()) {
|
||||
path.lineTo(first.getX(), first.getY());
|
||||
} else {
|
||||
path.curveTo(
|
||||
(float) last.getCp2().getX(), (float) last.getCp2().getY(),
|
||||
(float) first.getCp1().getX(), (float) first.getCp1().getY(),
|
||||
(float) first.getX(), (float) first.getY()
|
||||
);
|
||||
}
|
||||
path.closePath();
|
||||
// fire change
|
||||
cachedShape = path;
|
||||
firePropertyChange("shape", null, cachedShape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String p = "PATH {\n";
|
||||
BezierControlPoint first, last;
|
||||
first = last = controlPoints.get(0);
|
||||
p += " path.moveTo(" + first.getX() + "," + first.getY() + ");";
|
||||
for (int i = 0; i < controlPoints.size(); i++) {
|
||||
BezierControlPoint controlPoint = controlPoints.get(i);
|
||||
p += " path.curveTo(" +
|
||||
(float) last.getCp2().getX() + "," + (float) last.getCp2().getY() + "," +
|
||||
(float) controlPoint.getCp1().getX() + "," + (float) controlPoint.getCp1().getY() + "," +
|
||||
(float) controlPoint.getX() + "," + (float) controlPoint.getY() +
|
||||
");\n";
|
||||
last = controlPoint;
|
||||
}
|
||||
// close path
|
||||
p += " path.curveTo(" +
|
||||
(float) last.getCp2().getX() + "," + (float) last.getCp2().getY() + "," +
|
||||
(float) first.getCp1().getX() + "," + (float) first.getCp1().getY() + "," +
|
||||
(float) first.getX() + "," + (float) first.getY() +
|
||||
");\n";
|
||||
p += "}\n";
|
||||
return p;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Shape Methods
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
return getShape().getBounds2D();
|
||||
}
|
||||
|
||||
public List<? extends ControlPoint> getControlPoints() {
|
||||
List<ControlPoint> pts = new ArrayList<ControlPoint>();
|
||||
for (BezierControlPoint controlPoint : controlPoints) {
|
||||
pts.add(controlPoint);
|
||||
}
|
||||
for (ControlPoint controlPoint : super.getControlPoints()) {
|
||||
pts.add(controlPoint);
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
public void setControlPoints(List<BezierControlPoint> controlPoints) {
|
||||
List<BezierControlPoint> old = this.controlPoints;
|
||||
for (BezierControlPoint cp : old) {
|
||||
cp.removePropertyChangeListener(cpListener);
|
||||
}
|
||||
this.controlPoints = controlPoints;
|
||||
for (BezierControlPoint cp : this.controlPoints) {
|
||||
cp.addPropertyChangeListener(cpListener);
|
||||
}
|
||||
// update shape
|
||||
rebuildShape();
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
return getShape().contains(p);
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g2, double pixelSize) {
|
||||
g2.setPaint(getPaint());
|
||||
g2.fill(getShape());
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
if (paintControlLines) {
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
g2.setColor(GraphicsHelper.CONTROL_LINE);
|
||||
g2.draw(getShape());
|
||||
}
|
||||
for (BezierControlPoint controlPoint : controlPoints) {
|
||||
if (!controlPoint.isSharpCorner()) controlPoint.paintControls(g2, pixelSize, true);
|
||||
}
|
||||
}
|
||||
|
||||
public List<BezierControlPoint> getBezierControlPoints() {
|
||||
return controlPoints;
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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 javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* RectangleShape
|
||||
*
|
||||
* @author Created by Jasper Potts (May 22, 2007)
|
||||
*/
|
||||
public class RectangleShape extends PaintedShape {
|
||||
|
||||
private DoubleBean x1 = new DoubleBean();
|
||||
private DoubleBean x2 = new DoubleBean();
|
||||
private DoubleBean y1 = new DoubleBean();
|
||||
private DoubleBean y2 = new DoubleBean();
|
||||
private ControlPoint tl = new ControlPoint(x1, y1);
|
||||
private ControlPoint tr = new ControlPoint(x2, y1);
|
||||
private ControlPoint bl = new ControlPoint(x1, y2);
|
||||
private ControlPoint br = new ControlPoint(x2, y2);
|
||||
private DoubleBean roundingX = new DoubleBean() {
|
||||
public void setValue(double value) {
|
||||
// contrain y = y1 and x is between x1+1 and (x2-x1)/2
|
||||
boolean x1isLess = x1.getValue() < x2.getValue();
|
||||
double min = x1isLess ? x1.getValue() + 1 : x1.getValue() - 1;
|
||||
double max = x1isLess ? x1.getValue() + ((x2.getValue() - x1.getValue()) / 2) :
|
||||
x2.getValue() + ((x1.getValue() - x2.getValue()) / 2);
|
||||
double newX = value;
|
||||
if (newX < min) newX = min;
|
||||
if (newX > max) newX = max;
|
||||
super.setValue(newX);
|
||||
}
|
||||
};
|
||||
private ControlPoint rounding = new ControlPoint(roundingX, y1) {
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
double size = pixelSize * 3d;
|
||||
Shape s = new Ellipse2D.Double(getX() - size, getY() - size,
|
||||
size * 2, size * 2);
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_FILL);
|
||||
g2.fill(s);
|
||||
g2.setColor(GraphicsHelper.BEZIER_CONTROL_POINT_LINE);
|
||||
g2.draw(s);
|
||||
}
|
||||
|
||||
public void setPosition(Point2D position) {
|
||||
// only alow X to change
|
||||
x.setValue(position.getX());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
/** private noargs constructor for JIBX */
|
||||
private RectangleShape() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public RectangleShape(UIDefaults canvasUiDefaults) {
|
||||
super(canvasUiDefaults);
|
||||
x1.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
// keep rounding point in sync
|
||||
roundingX.setValue(roundingX.getValue() +
|
||||
((Double) evt.getNewValue() - (Double) evt.getOldValue()));
|
||||
firePropertyChange("bounds", null, getBounds(0));
|
||||
}
|
||||
});
|
||||
x2.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
// keep rounding point in sync
|
||||
double distanceFromX1 = Math.abs(roundingX.getValue() - x1.getValue());
|
||||
roundingX.setValue(
|
||||
(x1.getValue() < x2.getValue()) ? x1.getValue() + distanceFromX1 :
|
||||
x1.getValue() - distanceFromX1
|
||||
);
|
||||
firePropertyChange("bounds", null, getBounds(0));
|
||||
}
|
||||
});
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("bounds", null, getBounds(0));
|
||||
}
|
||||
};
|
||||
y1.addPropertyChangeListener(listener);
|
||||
y2.addPropertyChangeListener(listener);
|
||||
rounding.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public RectangleShape(double x, double y, double w, double h) {
|
||||
this();
|
||||
x1.setValue(x);
|
||||
y1.setValue(y);
|
||||
x2.setValue(x + w);
|
||||
y2.setValue(y + h);
|
||||
}
|
||||
|
||||
public Shape getShape() {
|
||||
double rounding = getRounding();
|
||||
double left = Math.min(x1.getValue(), x2.getValue());
|
||||
double right = Math.max(x1.getValue(), x2.getValue());
|
||||
double top = Math.min(y1.getValue(), y2.getValue());
|
||||
double bottom = Math.max(y1.getValue(), y2.getValue());
|
||||
if (rounding > 0) {
|
||||
return new RoundRectangle2D.Double(
|
||||
left, top, right - left, bottom - top, rounding, rounding
|
||||
);
|
||||
} else {
|
||||
return new Rectangle2D.Double(left, top, right - left, bottom - top);
|
||||
}
|
||||
}
|
||||
|
||||
public double getRounding() {
|
||||
double rounding = Math.abs(roundingX.getValue() - x1.getValue()) * 2;
|
||||
return rounding > 2 ? rounding : 0;
|
||||
}
|
||||
|
||||
public void setRounding(double rounding) {
|
||||
if (rounding > 0 && rounding < 2) rounding = 0;
|
||||
roundingX.setValue((rounding / 2d) + x1.getValue());
|
||||
}
|
||||
|
||||
public boolean isRounded() {
|
||||
return getRounding() > 0;
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return x1.getValue();
|
||||
}
|
||||
|
||||
public void setX1(double x1) {
|
||||
this.x1.setValue(x1);
|
||||
}
|
||||
|
||||
public double getX2() {
|
||||
return x2.getValue();
|
||||
}
|
||||
|
||||
public void setX2(double x2) {
|
||||
this.x2.setValue(x2);
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return y1.getValue();
|
||||
}
|
||||
|
||||
public void setY1(double y1) {
|
||||
this.y1.setValue(y1);
|
||||
}
|
||||
|
||||
public double getY2() {
|
||||
return y2.getValue();
|
||||
}
|
||||
|
||||
public void setY2(double y2) {
|
||||
this.y2.setValue(y2);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// SimpleShape Methods
|
||||
|
||||
public Rectangle2D getBounds(double pixelSize) {
|
||||
double left = Math.min(x1.getValue(), x2.getValue());
|
||||
double right = Math.max(x1.getValue(), x2.getValue());
|
||||
double top = Math.min(y1.getValue(), y2.getValue());
|
||||
double bottom = Math.max(y1.getValue(), y2.getValue());
|
||||
return new Rectangle2D.Double(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
public boolean isHit(Point2D p, double pixelSize) {
|
||||
return getShape().contains(p);
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g2, double pixelSize) {
|
||||
g2.setPaint(getPaint());
|
||||
g2.fill(getShape());
|
||||
}
|
||||
|
||||
public void setFrame(double x1, double y1, double x2, double y2) {
|
||||
this.x1.setValue(x1);
|
||||
this.y1.setValue(y1);
|
||||
this.x2.setValue(x2);
|
||||
this.y2.setValue(y2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Rectangle2D bounds = getBounds(0);
|
||||
if (isRounded()) {
|
||||
return "ROUND RECT { x=" + bounds.getX() + ", y=" + bounds.getY() + ", w=" + bounds.getWidth() + ", h=" + bounds.getHeight() + ", rounding=" + getRounding() + " }";
|
||||
} else {
|
||||
return "ROUND RECT { x=" + bounds.getX() + ", y=" + bounds.getY() + ", w=" + bounds.getWidth() + ", h=" + bounds.getHeight() + " }";
|
||||
}
|
||||
}
|
||||
|
||||
public List<ControlPoint> getControlPoints() {
|
||||
List<ControlPoint> points = new ArrayList<ControlPoint>();
|
||||
points.addAll(super.getControlPoints());
|
||||
points.add(tl);
|
||||
points.add(tr);
|
||||
points.add(bl);
|
||||
points.add(br);
|
||||
points.add(rounding);
|
||||
return points;
|
||||
}
|
||||
|
||||
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
|
||||
if (paintControlLines) {
|
||||
g2.setStroke(new BasicStroke((float) pixelSize));
|
||||
g2.setColor(GraphicsHelper.CONTROL_LINE);
|
||||
g2.draw(getShape());
|
||||
}
|
||||
tl.paintControls(g2, pixelSize, true);
|
||||
tr.paintControls(g2, pixelSize, true);
|
||||
bl.paintControls(g2, pixelSize, true);
|
||||
br.paintControls(g2, pixelSize, true);
|
||||
rounding.paintControls(g2, pixelSize, true);
|
||||
}
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
if (snapPixels) {
|
||||
x1.setValue(Math.round(x1.getValue() + moveX));
|
||||
x2.setValue(Math.round(x2.getValue() + moveX));
|
||||
y1.setValue(Math.round(y1.getValue() + moveY));
|
||||
y2.setValue(Math.round(y2.getValue() + moveY));
|
||||
} else {
|
||||
x1.setValue(x1.getValue() + moveX);
|
||||
x2.setValue(x2.getValue() + moveX);
|
||||
y1.setValue(y1.getValue() + moveY);
|
||||
y2.setValue(y2.getValue() + moveY);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SimpleShape
|
||||
*
|
||||
* @author Created by Jasper Potts (May 22, 2007)
|
||||
*/
|
||||
public abstract class SimpleShape extends AbstractBean {
|
||||
|
||||
protected AffineTransform transform = new AffineTransform();
|
||||
protected LayerContainer parent = null;
|
||||
|
||||
public void applyTransform(AffineTransform t) {
|
||||
transform.concatenate(t);
|
||||
}
|
||||
|
||||
public abstract Rectangle2D getBounds(double pixelSize);
|
||||
|
||||
public abstract void paint(Graphics2D g2, double pixelSize);
|
||||
|
||||
public abstract boolean isHit(Point2D p, double pixelSize);
|
||||
|
||||
public boolean intersects(Rectangle2D rect, double pixelSize) {
|
||||
return getBounds(pixelSize).intersects(rect);
|
||||
}
|
||||
|
||||
public abstract List<? extends ControlPoint> getControlPoints();
|
||||
|
||||
public abstract void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines);
|
||||
|
||||
public void move(double moveX, double moveY, boolean snapPixels) {
|
||||
for (ControlPoint controlPoint : getControlPoints()) {
|
||||
controlPoint.move(moveX, moveY, snapPixels);
|
||||
}
|
||||
}
|
||||
|
||||
public LayerContainer getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(LayerContainer parent) {
|
||||
LayerContainer old = getParent();
|
||||
this.parent = parent;
|
||||
firePropertyChange("parent", old, getParent());
|
||||
}
|
||||
|
||||
public abstract Shape getShape();
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.swingx.designer.effects.Effect;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* TemplateLayer
|
||||
*
|
||||
* @author Created by Jasper Potts (Jul 2, 2007)
|
||||
*/
|
||||
public class TemplateLayer extends Layer {
|
||||
|
||||
private String fileName;
|
||||
private transient SoftReference<BufferedImage> imgRef = null;
|
||||
|
||||
public TemplateLayer() {
|
||||
type = LayerType.template;
|
||||
}
|
||||
|
||||
public TemplateLayer(String fileName, BufferedImage templateImage) {
|
||||
super("Template");
|
||||
this.fileName = fileName;
|
||||
type = LayerType.template;
|
||||
if (templateImage != null) {
|
||||
imgRef = new SoftReference<BufferedImage>(templateImage);
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Methods
|
||||
|
||||
public String getName() {
|
||||
return super.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* template layers are always locked
|
||||
*
|
||||
* @return <code>true</code>
|
||||
*/
|
||||
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 SoftReference<BufferedImage>(img);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// create error image
|
||||
img = new BufferedImage(getCanvas().getSize().width, getCanvas().getSize().height,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2 = img.createGraphics();
|
||||
g2.setColor(Color.RED);
|
||||
g2.fillRect(0, 0, img.getWidth(), img.getHeight());
|
||||
g2.setColor(Color.WHITE);
|
||||
g2.setFont(g2.getFont().deriveFont(8f));
|
||||
FontMetrics fontMetrics = g2.getFontMetrics();
|
||||
Rectangle2D stringBounds = fontMetrics.getStringBounds("Missing Image", g2);
|
||||
int offsetX = (int) ((img.getWidth() - stringBounds.getWidth()) / 2d);
|
||||
int offsetY = (int) (((img.getHeight() - stringBounds.getHeight()) / 2d) - stringBounds.getY());
|
||||
g2.drawString("Missing Image", offsetX, offsetY);
|
||||
g2.dispose();
|
||||
imgRef = new SoftReference<BufferedImage>(img);
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* DropShadowEffect
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public class DropShadowEffect extends ShadowEffect {
|
||||
|
||||
protected DropShadowEffect() {}
|
||||
|
||||
;
|
||||
|
||||
public DropShadowEffect(UIDefaults uiDefaults) {
|
||||
color = new Matte(Color.BLACK, uiDefaults);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Effect Methods
|
||||
|
||||
/**
|
||||
* Get the display name for this effect
|
||||
*
|
||||
* @return The user displayable name
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return "Drop Shadow";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public 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 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
|
||||
*/
|
||||
public BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h) {
|
||||
// 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 = offsetY + size;
|
||||
int tmpW = w + offsetX + size + size;
|
||||
int tmpH = h + offsetY + size + size;
|
||||
// create tmp buffers
|
||||
int[] lineBuf = getTmpIntArray(w);
|
||||
byte[] tmpBuf1 = getTmpByteArray1(tmpW * tmpH);
|
||||
Arrays.fill(tmpBuf1, (byte) 0x00);
|
||||
byte[] tmpBuf2 = 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.beans.AbstractBean;
|
||||
import org.jdesktop.swingx.designer.BlendingMode;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Effect
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public abstract class Effect extends AbstractBean {
|
||||
protected boolean visible = true;
|
||||
|
||||
public enum EffectType {
|
||||
UNDER, BLENDED, OVER
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
boolean old = isVisible();
|
||||
this.visible = visible;
|
||||
firePropertyChange("visible", old, isVisible());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getDisplayName();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Abstract Methods
|
||||
|
||||
/**
|
||||
* Get the display name for this effect
|
||||
*
|
||||
* @return The user displayable name
|
||||
*/
|
||||
public abstract String getDisplayName();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public abstract EffectType getEffectType();
|
||||
|
||||
/**
|
||||
* Get the blending mode to use to paint the result effected image if the EffectType is UNDER or OVER.
|
||||
*
|
||||
* @return The blending mode for the effect
|
||||
*/
|
||||
public abstract BlendingMode getBlendingMode();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public abstract BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h);
|
||||
|
||||
// =================================================================================================================
|
||||
// Static data cache
|
||||
|
||||
private static SoftReference<int[]> tmpIntArray = null;
|
||||
private static SoftReference<byte[]> tmpByteArray1 = null;
|
||||
private static SoftReference<byte[]> tmpByteArray2 = null;
|
||||
private static SoftReference<byte[]> tmpByteArray3 = null;
|
||||
|
||||
protected static int[] getTmpIntArray(int size) {
|
||||
int[] tmp;
|
||||
if (tmpIntArray == null || (tmp = tmpIntArray.get()) == null || tmp.length < size) {
|
||||
// create new array
|
||||
tmp = new int[size];
|
||||
tmpIntArray = new SoftReference<int[]>(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
protected static byte[] getTmpByteArray1(int size) {
|
||||
byte[] tmp;
|
||||
if (tmpByteArray1 == null || (tmp = tmpByteArray1.get()) == null || tmp.length < size) {
|
||||
// create new array
|
||||
tmp = new byte[size];
|
||||
tmpByteArray1 = new SoftReference<byte[]>(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
protected static byte[] getTmpByteArray2(int size) {
|
||||
byte[] tmp;
|
||||
if (tmpByteArray2 == null || (tmp = tmpByteArray2.get()) == null || tmp.length < size) {
|
||||
// create new array
|
||||
tmp = new byte[size];
|
||||
tmpByteArray2 = new SoftReference<byte[]>(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
protected static byte[] getTmpByteArray3(int size) {
|
||||
byte[] tmp;
|
||||
if (tmpByteArray3 == null || (tmp = tmpByteArray3.get()) == null || tmp.length < size) {
|
||||
// create new array
|
||||
tmp = new byte[size];
|
||||
tmpByteArray3 = new SoftReference<byte[]>(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
|
||||
/**
|
||||
* EffectUtils
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public class EffectUtils {
|
||||
|
||||
/**
|
||||
* <p>Blurs the source pixels into the destination pixels. The force of the blur is specified by the radius which
|
||||
* must be greater than 0.</p> <p>The source and destination pixels arrays are expected to be in the BYTE_GREY
|
||||
* format.</p> <p>After this method is executed, dstPixels contains a transposed and filtered copy of
|
||||
* srcPixels.</p>
|
||||
*
|
||||
* @param srcPixels the source pixels
|
||||
* @param dstPixels the destination pixels
|
||||
* @param width the width of the source picture
|
||||
* @param height the height of the source picture
|
||||
* @param kernel the kernel of the blur effect
|
||||
* @param radius the radius of the blur effect
|
||||
*/
|
||||
public static void blur(byte[] srcPixels, byte[] dstPixels,
|
||||
int width, int height,
|
||||
float[] kernel, int radius) {
|
||||
float p;
|
||||
int cp;
|
||||
for (int y = 0; y < height; y++) {
|
||||
int index = y;
|
||||
int offset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
p = 0.0f;
|
||||
for (int i = -radius; i <= radius; i++) {
|
||||
int subOffset = x + i;
|
||||
if (subOffset < 0 || subOffset >= width) {
|
||||
subOffset = (x + width) % width;
|
||||
}
|
||||
int pixel = srcPixels[offset + subOffset] & 0xFF;
|
||||
float blurFactor = kernel[radius + i];
|
||||
p += blurFactor * pixel;
|
||||
}
|
||||
cp = (int) (p + 0.5f);
|
||||
dstPixels[index] = (byte) (cp > 255 ? 255 : cp);
|
||||
index += height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float[] createGaussianKernel(int radius) {
|
||||
if (radius < 1) {
|
||||
throw new IllegalArgumentException("Radius must be >= 1");
|
||||
}
|
||||
|
||||
float[] data = new float[radius * 2 + 1];
|
||||
|
||||
float sigma = radius / 3.0f;
|
||||
float twoSigmaSquare = 2.0f * sigma * sigma;
|
||||
float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
|
||||
float total = 0.0f;
|
||||
|
||||
for (int i = -radius; i <= radius; i++) {
|
||||
float distance = i * i;
|
||||
int index = i + radius;
|
||||
data[index] = (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
|
||||
total += data[index];
|
||||
}
|
||||
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] /= total;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import java.awt.Composite;
|
||||
import java.awt.CompositeContext;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
/**
|
||||
* EffectUtilsTemp - effect utils methods that are not being used for now but we might want later
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public class EffectUtilsTemp {
|
||||
|
||||
/**
|
||||
* Extract the alpha channel of a image into new greyscale buffered image
|
||||
*
|
||||
* @param src Must but INT_ARGB buffered image
|
||||
* @return new TYPE_BYTE_GRAY image of just the alpha channel
|
||||
*/
|
||||
public static BufferedImage extractAlpha(BufferedImage src) {
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
// extract image alpha channel as greyscale image
|
||||
final BufferedImage greyImg = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
|
||||
Graphics2D g2 = greyImg.createGraphics();
|
||||
g2.setComposite(new Composite() {
|
||||
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
|
||||
RenderingHints hints) {
|
||||
return new CompositeContext() {
|
||||
public void dispose() {}
|
||||
|
||||
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
|
||||
int width = Math.min(src.getWidth(), dstIn.getWidth());
|
||||
int height = Math.min(src.getHeight(), dstIn.getHeight());
|
||||
int[] srcPixels = new int[width];
|
||||
byte[] dstPixels = new byte[width];
|
||||
for (int y = 0; y < height; y++) {
|
||||
src.getDataElements(0, y, width, 1, srcPixels);
|
||||
for (int x = 0; x < width; x++) {
|
||||
dstPixels[x] = (byte) ((srcPixels[x] & 0xFF000000) >>> 24);
|
||||
}
|
||||
dstOut.setDataElements(0, y, width, 1, dstPixels);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
g2.drawImage(src, 0, 0, null);
|
||||
g2.dispose();
|
||||
return greyImg;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* InnerGlowEffect
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 21, 2007)
|
||||
*/
|
||||
public class InnerGlowEffect extends InnerShadowEffect {
|
||||
|
||||
protected InnerGlowEffect() {
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
public InnerGlowEffect(UIDefaults uiDefaults) {
|
||||
color = new Matte(new Color(255, 255, 211), uiDefaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name for this effect
|
||||
*
|
||||
* @return The user displayable name
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return "Inner Glow";
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* InnerShadowEffect
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public class InnerShadowEffect extends ShadowEffect {
|
||||
|
||||
protected InnerShadowEffect() {}
|
||||
|
||||
;
|
||||
|
||||
public InnerShadowEffect(UIDefaults uiDefaults) {
|
||||
color = new Matte(Color.BLACK, uiDefaults);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Effect Methods
|
||||
|
||||
/**
|
||||
* Get the display name for this effect
|
||||
*
|
||||
* @return The user displayable name
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return "Inner Shadow";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public 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 The result of appl
|
||||
*/
|
||||
public BufferedImage applyEffect(BufferedImage src, BufferedImage dst, int w, int h) {
|
||||
// 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 = offsetY + size;
|
||||
int tmpW = w + offsetX + size + size;
|
||||
int tmpH = h + offsetY + size + size;
|
||||
// create tmp buffers
|
||||
int[] lineBuf = getTmpIntArray(w);
|
||||
byte[] srcAlphaBuf = getTmpByteArray1(tmpW * tmpH);
|
||||
Arrays.fill(srcAlphaBuf, (byte) 0xFF);
|
||||
byte[] tmpBuf1 = getTmpByteArray2(tmpW * tmpH);
|
||||
byte[] tmpBuf2 = 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* OuterGlowEffect
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 21, 2007)
|
||||
*/
|
||||
public class OuterGlowEffect extends DropShadowEffect {
|
||||
|
||||
protected OuterGlowEffect() {
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
public OuterGlowEffect(UIDefaults uiDefaults) {
|
||||
color = new Matte(new Color(255, 255, 211), uiDefaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name for this effect
|
||||
*
|
||||
* @return The user displayable name
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return "Outer Glow";
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.effects;
|
||||
|
||||
import org.jdesktop.swingx.designer.BlendingMode;
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* ShadowEffect - base class with all the standard properties for shadow effects
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 18, 2007)
|
||||
*/
|
||||
public abstract class ShadowEffect extends Effect {
|
||||
protected Matte color;
|
||||
protected BlendingMode blendingMode = BlendingMode.NORMAL;
|
||||
/** Opacity a float 0-1 for percentage */
|
||||
protected float opacity = 0.75f;
|
||||
/** Angle in degrees between 0-360 */
|
||||
protected int angle = 135;
|
||||
/** Distance in pixels */
|
||||
protected int distance = 5;
|
||||
/** The shadow spread between 0-100 % */
|
||||
protected int spread = 0;
|
||||
/** Size in pixels */
|
||||
protected int size = 5;
|
||||
|
||||
protected ShadowEffect() {}
|
||||
|
||||
;
|
||||
|
||||
public ShadowEffect(UIDefaults uiDefaults) {
|
||||
color = new Matte(Color.BLACK, uiDefaults);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean methods
|
||||
|
||||
public Matte getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Matte color) {
|
||||
Matte old = getColor();
|
||||
this.color = color;
|
||||
firePropertyChange("color", old, getColor());
|
||||
}
|
||||
|
||||
public BlendingMode getBlendingMode() {
|
||||
return blendingMode;
|
||||
}
|
||||
|
||||
public void setBlendingMode(BlendingMode blendingMode) {
|
||||
BlendingMode old = getBlendingMode();
|
||||
this.blendingMode = blendingMode;
|
||||
firePropertyChange("blendingMode", old, getBlendingMode());
|
||||
}
|
||||
|
||||
public float getOpacity() {
|
||||
return opacity;
|
||||
}
|
||||
|
||||
public void setOpacity(float opacity) {
|
||||
float old = getOpacity();
|
||||
this.opacity = opacity;
|
||||
firePropertyChange("opacity", old, getOpacity());
|
||||
}
|
||||
|
||||
public int getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
public void setAngle(int angle) {
|
||||
int old = getAngle();
|
||||
this.angle = angle;
|
||||
firePropertyChange("angle", old, getAngle());
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(int distance) {
|
||||
int old = getDistance();
|
||||
this.distance = distance;
|
||||
firePropertyChange("distance", old, getDistance());
|
||||
}
|
||||
|
||||
public int getSpread() {
|
||||
return spread;
|
||||
}
|
||||
|
||||
public void setSpread(int spread) {
|
||||
int old = getSpread();
|
||||
this.spread = spread;
|
||||
firePropertyChange("spread", old, getSpread());
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
int old = getSize();
|
||||
this.size = size;
|
||||
firePropertyChange("size", old, getSize());
|
||||
}
|
||||
}
|
@ -0,0 +1,484 @@
|
||||
/*
|
||||
* 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.font;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.UIDefaults;
|
||||
import org.jdesktop.beans.AbstractBean;
|
||||
import org.jdesktop.swingx.designer.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
/**
|
||||
* I don't think the name is technically correct (ie: a typeface is not a font),
|
||||
* but I wanted something besides "font" so, here it is.
|
||||
*
|
||||
* This is a mutable font, much like Matte is a mutable color. Also like Matte,
|
||||
* Typeface can be derived.
|
||||
*
|
||||
* @author rbair
|
||||
*/
|
||||
public class Typeface extends AbstractBean {
|
||||
//specifies whether to derive bold, or italic.
|
||||
//Default means, get my value from my parent.
|
||||
//Off means, leave bold/italic off.
|
||||
//On means, make bold/italic on.
|
||||
public enum DeriveStyle { Default, Off, On }
|
||||
|
||||
private String uiDefaultParentName;
|
||||
/** This is a local UIDefaults that contains all the UIDefaults in the Model. */
|
||||
private transient UIDefaults uiDefaults = new UIDefaults();
|
||||
private PropertyChangeListener uiDefaultsChangeListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (uiDefaultParentName != null && uiDefaultParentName.equals(evt.getPropertyName())) {
|
||||
updateFontFromOffsets();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the font. If uiDefaultParentName is specified, then this name
|
||||
* will be set to be equal to the name of the parent font.
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* The size of the font. If uiDefaultParentName is set, then this value is
|
||||
* updated to reflect the size of the parent font * the sizeOffset.
|
||||
*/
|
||||
private int size;
|
||||
|
||||
//this field is not publically accessible. Rather, it is updated based on
|
||||
//"bold" and "italic" as necessary.
|
||||
private int style = Font.PLAIN;
|
||||
private DeriveStyle bold = DeriveStyle.Default;
|
||||
private DeriveStyle italic = DeriveStyle.Default;
|
||||
|
||||
/**
|
||||
* The size offset. Only used if uiDefaultParentName is specified. This offset
|
||||
* will be multiplied with the parent font's size to determine the size of this
|
||||
* typeface. The offset is specified as a percentage, either positive or negative.
|
||||
*
|
||||
* The reason a percentage was used, was so that things would look correctly
|
||||
* when scaled, such as with high DPI situations.
|
||||
*/
|
||||
private float sizeOffset;
|
||||
|
||||
/**
|
||||
* Create a new Typeface. Note that, without specifying the uiDefaults,
|
||||
* you cannot have font derivation. Thus, this constructor should never
|
||||
* be called, except for the XML binding stuff.
|
||||
*/
|
||||
public Typeface() { }
|
||||
|
||||
/**
|
||||
* Creates a new Typeface.
|
||||
*
|
||||
* @param f The font from which to get the font name, size, and style to use
|
||||
* to initialize this typeface. Note that this font is not used as a parent
|
||||
* font for derivation purposes. Rather, it is used as a source from which to
|
||||
* copy initial settings.
|
||||
*
|
||||
* @param uiDefaults The uiDefaults to use for font derivation purposes.
|
||||
* When the uiDefaultParentName is specified, then this Typeface will inspect
|
||||
* the given UIDefaults for that parent <em>font</em>. Note that the UIDefaults
|
||||
* should be populated with a font, and not with a typeface.
|
||||
*/
|
||||
public Typeface(Font f, UIDefaults uiDefaults) {
|
||||
if (f != null) {
|
||||
this.name = f.getName();
|
||||
this.size = f.getSize();
|
||||
this.style = f.getStyle();
|
||||
}
|
||||
setUiDefaults(uiDefaults);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
protected void postSet(IUnmarshallingContext context) {
|
||||
// walk up till we get synth model
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIDefaults) {
|
||||
UIDefaults uiDefaults = ((HasUIDefaults) context.getStackObject(i)).getUiDefaults();
|
||||
if (uiDefaults != null) {
|
||||
setUiDefaults(uiDefaults);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Typeface methods
|
||||
|
||||
/**
|
||||
* Is the Typeface an absolute Font not derived from a parent ui default
|
||||
*
|
||||
* @return <code>true</code> 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 <code>src</code> 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 <em>only</em> works if
|
||||
* <code>isAbsolute</code> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the size of the font. THis method call will work whether
|
||||
* <code>isAbsolute</code> 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.</p>
|
||||
*
|
||||
* <p>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".</p>
|
||||
*
|
||||
* @param size the new size for this typeface.
|
||||
*/
|
||||
public void setSize(int size) {
|
||||
int old = this.size;
|
||||
Font oldF = getFont();
|
||||
this.size = size;
|
||||
firePropertyChange("size", old, this.size);
|
||||
firePropertyChange("font", oldF, getFont());
|
||||
updateOffsetsFromFont();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size offset
|
||||
*/
|
||||
public final float getSizeOffset() {
|
||||
return sizeOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the percentage by which the size of this font should be different
|
||||
* from its parent font. This property is kept in synch with the size property.
|
||||
*
|
||||
* @param sizeOffset the size offset. May be any float. The value "1" means,
|
||||
* 100%. -1 means "-100%". 2 means "200%", and so on.
|
||||
*/
|
||||
public void setSizeOffset(float sizeOffset) {
|
||||
float old = this.sizeOffset;
|
||||
Font oldF = getFont();
|
||||
this.sizeOffset = sizeOffset;
|
||||
firePropertyChange("sizeOffset", old, this.sizeOffset);
|
||||
firePropertyChange("font", oldF, getFont());
|
||||
updateFontFromOffsets();
|
||||
}
|
||||
|
||||
public DeriveStyle getBold() {
|
||||
return bold;
|
||||
}
|
||||
|
||||
public void setBold(DeriveStyle bold) {
|
||||
DeriveStyle old = this.bold;
|
||||
this.bold = bold == null ? DeriveStyle.Default : bold;
|
||||
firePropertyChange("bold", old, this.bold);
|
||||
updateFontFromOffsets();
|
||||
}
|
||||
|
||||
public DeriveStyle getItalic() {
|
||||
return italic;
|
||||
}
|
||||
|
||||
public void setItalic(DeriveStyle italic) {
|
||||
DeriveStyle old = this.italic;
|
||||
this.italic = italic == null ? DeriveStyle.Default : italic;
|
||||
firePropertyChange("italic", old, this.italic);
|
||||
updateFontFromOffsets();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether or not the font represented by this typeface is supported
|
||||
* on this operating system platform.
|
||||
*/
|
||||
public boolean isFontSupported() {
|
||||
return true;//Font.getFont(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the font associated with this Typeface. If font derivation is
|
||||
* being used, then the Font returned is the result of that derivation.
|
||||
*/
|
||||
public Font getFont() {
|
||||
return new Font(name, style, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font from which this Typeface should extract the font name, style,
|
||||
* and size. If font derivation is being used, then the font name will be ignored,
|
||||
* the style will be used (and always override the parent font), and the size
|
||||
* will be set and the sizeOffset updated appropriately.
|
||||
*
|
||||
* @param f the Font
|
||||
*/
|
||||
public void setFont(Font f) {
|
||||
Font oldFont = getFont();
|
||||
String oldName = name;
|
||||
int oldSize = size;
|
||||
DeriveStyle oldBold = bold, oldItalic = italic;
|
||||
name = f.getName();
|
||||
size = f.getSize();
|
||||
style = f.getStyle();
|
||||
updateOffsetsFromFont();
|
||||
firePropertyChange("name", oldName, name);
|
||||
firePropertyChange("size", oldSize, size);
|
||||
firePropertyChange("bold", oldBold, bold);
|
||||
firePropertyChange("italic", oldItalic, italic);
|
||||
firePropertyChange("font", oldFont, getFont());
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @return A formatted string representing this Typeface. This String should
|
||||
* not be considered public API, as it may change in a future release.
|
||||
*/
|
||||
@Override public String toString() {
|
||||
Font f = getFont();
|
||||
String strStyle;
|
||||
if (f.isBold()) {
|
||||
strStyle = f.isItalic() ? "bolditalic" : "bold";
|
||||
} else {
|
||||
strStyle = f.isItalic() ? "italic" : "plain";
|
||||
}
|
||||
|
||||
if (isAbsolute()) {
|
||||
return Typeface.class.getName() + "[name=" + name + ", size=" + size + ", style=" + strStyle + "]";
|
||||
} else {
|
||||
return Typeface.class.getName() + "[base=" + uiDefaultParentName +
|
||||
", name=" + name + ", size=" + size + "(offset " + sizeOffset + ")" +
|
||||
", style=" + strStyle + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Typeface typeface = (Typeface) o;
|
||||
if (!typeface.name.equals(name)) return false;
|
||||
if (size != typeface.size) return false;
|
||||
if (bold != typeface.bold) return false;
|
||||
if (italic != typeface.italic) return false;
|
||||
if (sizeOffset != typeface.sizeOffset) return false;
|
||||
if (uiDefaultParentName != null ? !uiDefaultParentName.equals(typeface.uiDefaultParentName) :
|
||||
typeface.uiDefaultParentName != null) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result;
|
||||
result = name.hashCode();
|
||||
result = 31 * result + size;
|
||||
result = 31 * result + bold.ordinal();
|
||||
result = 31 * result + italic.ordinal();
|
||||
result = 31 * result + (int)(sizeOffset*100);
|
||||
result = 31 * result + (uiDefaultParentName != null ? uiDefaultParentName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public Typeface clone() {
|
||||
Typeface clone = new Typeface();
|
||||
clone.name = name;
|
||||
clone.size = size;
|
||||
clone.style = style;
|
||||
clone.bold = bold;
|
||||
clone.italic = italic;
|
||||
clone.sizeOffset = sizeOffset;
|
||||
clone.uiDefaultParentName = uiDefaultParentName;
|
||||
clone.setUiDefaults(uiDefaults);
|
||||
return clone;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Private Helper Methods
|
||||
|
||||
private void updateOffsetsFromFont() {
|
||||
if (!isAbsolute()) {
|
||||
float oldSizeOffset = sizeOffset;
|
||||
Font parentFont = uiDefaults.getFont(uiDefaultParentName);
|
||||
if (parentFont != null) {
|
||||
float s = size;
|
||||
float p = parentFont.getSize();
|
||||
sizeOffset = (s/p) - 1f;
|
||||
firePropertyChange("sizeOffset", oldSizeOffset, sizeOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFontFromOffsets() {
|
||||
if (!isAbsolute()) {
|
||||
Font oldFont = getFont();
|
||||
// get parent font data
|
||||
Font parentFont = uiDefaults.getFont(uiDefaultParentName);
|
||||
if (parentFont != null) {
|
||||
String oldName = name;
|
||||
int oldSize = size;
|
||||
|
||||
name = parentFont.getName();
|
||||
size = Math.round(parentFont.getSize() * (1f + sizeOffset));
|
||||
|
||||
boolean isBold = (bold == DeriveStyle.Default && parentFont.isBold()) || bold == DeriveStyle.On;
|
||||
boolean isItalic = (italic == DeriveStyle.Default && parentFont.isItalic()) || italic == DeriveStyle.On;
|
||||
style = Font.PLAIN;
|
||||
if (isBold) style = style | Font.BOLD;
|
||||
if (isItalic) style = style | Font.ITALIC;
|
||||
|
||||
// update fire events
|
||||
firePropertyChange("name", oldName, name);
|
||||
firePropertyChange("size", oldSize, size);
|
||||
firePropertyChange("font", oldFont, getFont());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jdesktop.swingx.designer.Canvas;
|
||||
import org.jdesktop.swingx.designer.utils.HasPath;
|
||||
import org.jdesktop.swingx.designer.utils.HasResources;
|
||||
import org.jdesktop.swingx.designer.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.BindingDirectory;
|
||||
import org.jibx.runtime.IBindingFactory;
|
||||
import org.jibx.runtime.IMarshallable;
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* CanvasMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 12, 2007)
|
||||
*/
|
||||
public class CanvasMapper implements IMarshaller, IUnmarshaller {
|
||||
private static final String ELEMENT_NAME = "canvas";
|
||||
private IBindingFactory bindingFactory;
|
||||
|
||||
|
||||
public CanvasMapper() {
|
||||
try {
|
||||
bindingFactory = BindingDirectory.getFactory(Canvas.class);
|
||||
} catch (JiBXException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Canvas)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
// version found, create marshaller for the associated binding
|
||||
// IBindingFactory bindingFactory = BindingDirectory.getFactory(object.getClass());
|
||||
MarshallingContext context = (MarshallingContext) bindingFactory.createMarshallingContext();
|
||||
// configure marshaller for writing document
|
||||
context.setXmlWriter(iMarshallingContext.getXmlWriter());
|
||||
// output object as document
|
||||
((IMarshallable) object).marshal(context);
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(null, ELEMENT_NAME)) {
|
||||
ctx.throwStartTagNameError(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
// IBindingFactory bindingFactory = BindingDirectory.getFactory(Canvas.class);
|
||||
UnmarshallingContext uctx = (UnmarshallingContext) bindingFactory.createUnmarshallingContext();
|
||||
uctx.setFromContext(ctx);
|
||||
// get the uiDefaults from SynthModel and set them as user context
|
||||
UIDefaults uiDefaults = ((HasUIDefaults) ctx.getStackObject(ctx.getStackDepth() - 1)).getUiDefaults();
|
||||
uctx.setUserContext(uiDefaults);
|
||||
// get has resources
|
||||
HasResources hasResources = (HasResources) ctx.getStackObject(ctx.getStackDepth() - 1);
|
||||
// get path
|
||||
HasPath hasPath = null;
|
||||
for (int i = 0; i < ctx.getStackDepth(); i++) {
|
||||
if (ctx.getStackObject(i) instanceof HasPath) {
|
||||
hasPath = (HasPath) ctx.getStackObject(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Unmarshal the Canvas
|
||||
Canvas canvas = (Canvas) uctx.unmarshalElement();
|
||||
// set canvas's ui defaults
|
||||
canvas.setUiDefaults(uiDefaults);
|
||||
// get canvas path
|
||||
String canvasPath = hasPath.getPath();
|
||||
// calc and set resources
|
||||
canvas.setResourcesDir(new File(hasResources.getResourcesDir(), canvasPath));
|
||||
canvas.setTemplatesDir(new File(hasResources.getTemplatesDir(), canvasPath));
|
||||
canvas.setImagesDir(new File(hasResources.getImagesDir(), canvasPath));
|
||||
// return canvas
|
||||
return canvas;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* ColorMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 8, 2007)
|
||||
*/
|
||||
public class ColorMapper implements IMarshaller, IUnmarshaller {
|
||||
private static final String ELEMENT_NAME = "color";
|
||||
private static final String RED_NAME = "red";
|
||||
private static final String GREEN_NAME = "green";
|
||||
private static final String BLUE_NAME = "blue";
|
||||
private static final String ALPHA_NAME = "alpha";
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Color)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
Color color = (Color) object;
|
||||
ctx.startTagAttributes(0, ELEMENT_NAME).
|
||||
attribute(0, RED_NAME, color.getRed()).
|
||||
attribute(0, GREEN_NAME, color.getGreen()).
|
||||
attribute(0, BLUE_NAME, color.getBlue()).
|
||||
attribute(0, ALPHA_NAME, color.getAlpha()).
|
||||
closeStartEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(null, ELEMENT_NAME)) {
|
||||
ctx.throwStartTagNameError(null, ELEMENT_NAME);
|
||||
}
|
||||
// get values
|
||||
int red = ctx.attributeInt(null, RED_NAME, 0);
|
||||
int green = ctx.attributeInt(null, GREEN_NAME, 0);
|
||||
int blue = ctx.attributeInt(null, BLUE_NAME, 0);
|
||||
int alpha = ctx.attributeInt(null, ALPHA_NAME, 0);
|
||||
ctx.parsePastEndTag(null, ELEMENT_NAME);
|
||||
// create
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IAliasable;
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
/**
|
||||
* DimensionMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 12, 2007)
|
||||
*/
|
||||
public class DimensionMapper implements IMarshaller, IUnmarshaller, IAliasable {
|
||||
private static final String ELEMENT_NAME = "dimension";
|
||||
private static final String WIDTH_NAME = "width";
|
||||
private static final String HEIGHT_NAME = "height";
|
||||
|
||||
private String uri;
|
||||
private int index;
|
||||
private String name;
|
||||
|
||||
public DimensionMapper() {
|
||||
uri = null;
|
||||
index = 0;
|
||||
name = ELEMENT_NAME;
|
||||
}
|
||||
|
||||
public DimensionMapper(String uri, int index, String name) {
|
||||
this.uri = uri;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(uri, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Dimension)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
Dimension dimension = (Dimension) object;
|
||||
ctx.startTagAttributes(index, name).
|
||||
attribute(index, WIDTH_NAME, dimension.width).
|
||||
attribute(index, HEIGHT_NAME, dimension.height).
|
||||
closeStartEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(uri, name)) {
|
||||
ctx.throwStartTagNameError(uri, name);
|
||||
}
|
||||
// get values
|
||||
int width = ctx.attributeInt(uri, WIDTH_NAME, index);
|
||||
int height = ctx.attributeInt(uri, HEIGHT_NAME, index);
|
||||
// state finished parsing
|
||||
ctx.parsePastEndTag(uri, name);
|
||||
// create
|
||||
return new Dimension(width, height);
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IAliasable;
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
import java.awt.Insets;
|
||||
|
||||
/**
|
||||
* InsetsMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 8, 2007)
|
||||
*/
|
||||
public class InsetsMapper implements IMarshaller, IUnmarshaller, IAliasable {
|
||||
private static final String ELEMENT_NAME = "insets";
|
||||
private static final String TOP_NAME = "top";
|
||||
private static final String BOTTOM_NAME = "bottom";
|
||||
private static final String LEFT_NAME = "left";
|
||||
private static final String RIGHT_NAME = "right";
|
||||
|
||||
private String uri;
|
||||
private int index;
|
||||
private String name;
|
||||
|
||||
public InsetsMapper() {
|
||||
uri = null;
|
||||
index = 0;
|
||||
name = ELEMENT_NAME;
|
||||
}
|
||||
|
||||
public InsetsMapper(String uri, int index, String name) {
|
||||
this.uri = uri;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
// System.out.println("InsetsMapper.CONSTRCUTED with uri="+uri+" index="+index+" name="+name);
|
||||
}
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(uri, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Insets)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
// System.out.println("InsetsMapper.marshal name="+name);
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
Insets insets = (Insets) object;
|
||||
ctx.startTagAttributes(index, name).
|
||||
attribute(index, TOP_NAME, insets.top).
|
||||
attribute(index, BOTTOM_NAME, insets.bottom).
|
||||
attribute(index, LEFT_NAME, insets.left).
|
||||
attribute(index, RIGHT_NAME, insets.right).
|
||||
closeStartEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(uri, name)) {
|
||||
// System.out.println("InsetsMapper.unmarshal name="+name+" uri="+uri+" currentNode="+ctx.getName());
|
||||
ctx.throwStartTagNameError(uri, name);
|
||||
} else {
|
||||
// System.out.println("InsetsMapper.unmarshal name="+name+" uri="+uri+" currentNode="+ctx.getName());
|
||||
}
|
||||
// get values
|
||||
int top = ctx.attributeInt(uri, TOP_NAME, index);
|
||||
int bottom = ctx.attributeInt(uri, BOTTOM_NAME, index);
|
||||
int left = ctx.attributeInt(uri, LEFT_NAME, index);
|
||||
int right = ctx.attributeInt(uri, RIGHT_NAME, index);
|
||||
// create new hashmap if needed
|
||||
Insets insets = (Insets) object;
|
||||
if (insets == null) {
|
||||
insets = new Insets(top, left, bottom, right);
|
||||
} else {
|
||||
insets.set(top, left, bottom, right);
|
||||
}
|
||||
ctx.parsePastEndTag(uri, name);
|
||||
return insets;
|
||||
}
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* 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.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/** @author rbair */
|
||||
public abstract class AbstractGradient extends PaintModel {
|
||||
private final Comparator<GradientStop> sorter = new Comparator<GradientStop>() {
|
||||
public int compare(GradientStop s1, GradientStop s2) {
|
||||
//since a float value may be -.001 or .001, and since casting
|
||||
//this to an int will round off to 0, I have to do a more direct
|
||||
//comparison
|
||||
float v = s1.getPosition() - s2.getPosition();
|
||||
|
||||
if (v < 0) return -1;
|
||||
else if (v == 0) return 0;
|
||||
else return 1;
|
||||
}
|
||||
};
|
||||
private PropertyChangeListener stopListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals("position")) {
|
||||
if (stops.contains((GradientStop) evt.getSource())) {
|
||||
resortModel(true);
|
||||
} else {
|
||||
System.err.println("[WARNING] The position of an orphaned stop was changed.");
|
||||
}
|
||||
} else {
|
||||
firePropertyChange("paint", null, getPaint());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private List<GradientStop> stops = new ArrayList<GradientStop>();
|
||||
private List<GradientStop> unmodifiable;
|
||||
private CycleMethod cycleMethod;
|
||||
|
||||
protected AbstractGradient() {
|
||||
unmodifiable = Collections.unmodifiableList(stops);
|
||||
cycleMethod = CycleMethod.NO_CYCLE;
|
||||
setStops(new GradientStop(0, new Matte(Color.BLUE, null)),
|
||||
new GradientStop(1, new Matte(Color.WHITE, null)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy stops and cycleMethod from src to dst
|
||||
*
|
||||
* @param dst The gradient to update to same stops and cycle method as this gradient
|
||||
*/
|
||||
protected void copyTo(AbstractGradient dst) {
|
||||
dst.stops.clear();
|
||||
List<GradientStop> stops = new ArrayList<GradientStop>();
|
||||
for (GradientStop stop : this.stops) {
|
||||
stops.add(stop.clone());
|
||||
}
|
||||
dst.setStops(stops);
|
||||
dst.cycleMethod = this.cycleMethod;
|
||||
}
|
||||
|
||||
|
||||
public PaintControlType getPaintControlType() {
|
||||
return PaintControlType.control_line;
|
||||
}
|
||||
|
||||
public void setCycleMethod(CycleMethod method) {
|
||||
CycleMethod old = cycleMethod;
|
||||
Paint oldp = getPaint();
|
||||
cycleMethod = method == null ? CycleMethod.NO_CYCLE : method;
|
||||
firePropertyChange("cycleMethod", old, cycleMethod);
|
||||
firePropertyChange("paint", oldp, getPaint());
|
||||
}
|
||||
|
||||
public final CycleMethod getCycleMethod() {
|
||||
return cycleMethod;
|
||||
}
|
||||
|
||||
public void setStops(GradientStop... stops) {
|
||||
if (stops == null || stops.length < 1) {
|
||||
throw new IllegalArgumentException("Must have more than one stop");
|
||||
}
|
||||
List<GradientStop> old = new ArrayList<GradientStop>(this.stops);
|
||||
for (GradientStop stop : old) {
|
||||
stop.removePropertyChangeListener(stopListener);
|
||||
}
|
||||
Paint oldp = getPaint();
|
||||
this.stops.clear();
|
||||
Collections.addAll(this.stops, stops);
|
||||
for (GradientStop stop : this.stops) {
|
||||
stop.addPropertyChangeListener(stopListener);
|
||||
}
|
||||
resortModel(false);
|
||||
firePropertyChange("stops", old, getStops());
|
||||
firePropertyChange("paint", oldp, getPaint());
|
||||
}
|
||||
|
||||
public final void setStops(List<GradientStop> stops) {
|
||||
setStops(stops == null ? null : stops.toArray(new GradientStop[0]));
|
||||
}
|
||||
|
||||
public final List<GradientStop> getStops() {
|
||||
return unmodifiable;
|
||||
}
|
||||
|
||||
private void resortModel(boolean fireEvent) {
|
||||
Collections.sort(this.stops, sorter);
|
||||
if (fireEvent) {
|
||||
Paint oldp = getPaint();
|
||||
firePropertyChange("stops", null, getStops());
|
||||
firePropertyChange("paint", oldp, getPaint());
|
||||
}
|
||||
}
|
||||
|
||||
//adds a new stop, and interoplates the proper color to use based on
|
||||
//its position
|
||||
public GradientStop addStop(float position) {
|
||||
GradientStop prevStop = null;
|
||||
GradientStop nextStop = null;
|
||||
for (GradientStop stop : stops) {
|
||||
if (stop.getPosition() <= position) {
|
||||
prevStop = stop;
|
||||
} else if (stop.getPosition() >= position) {
|
||||
nextStop = stop;
|
||||
}
|
||||
}
|
||||
|
||||
Matte c = null;
|
||||
if (prevStop != null && nextStop != null) {
|
||||
//interpolate the value of c
|
||||
c = interpolate(prevStop.getColor(), nextStop.getColor(),
|
||||
position / (nextStop.getPosition() - prevStop.getPosition()));
|
||||
} else if (prevStop != null) {
|
||||
c = prevStop.getColor().clone();
|
||||
} else if (nextStop != null) {
|
||||
c = nextStop.getColor().clone();
|
||||
}
|
||||
|
||||
return addStop(position, c);
|
||||
}
|
||||
|
||||
public GradientStop addStop(float position, Matte color) {
|
||||
GradientStop s = new GradientStop(position, color);
|
||||
s.addPropertyChangeListener(stopListener);
|
||||
List<GradientStop> old = new ArrayList<GradientStop>(stops);
|
||||
Paint oldp = getPaint();
|
||||
stops.add(s);
|
||||
resortModel(false);
|
||||
firePropertyChange("stops", old, getStops());
|
||||
firePropertyChange("paint", oldp, getPaint());
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public GradientStop removeStop(GradientStop s) {
|
||||
List<GradientStop> old = new ArrayList<GradientStop>(stops);
|
||||
Paint oldp = getPaint();
|
||||
stops.remove(s);
|
||||
s.removePropertyChangeListener(stopListener);
|
||||
resortModel(false);
|
||||
firePropertyChange("stops", old, getStops());
|
||||
firePropertyChange("paint", oldp, getPaint());
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override public Paint getPaint() {
|
||||
if (stops.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//there are stops.size() number of main stops. Between each is
|
||||
//a fractional stop. Thus, there are:
|
||||
//stops.size() + stops.size() - 1
|
||||
//number of fractions and colors.
|
||||
|
||||
float[] fractions = new float[stops.size() + stops.size() - 1];
|
||||
Matte[] colors = new Matte[fractions.length];
|
||||
|
||||
//for each stop, create the stop and it's associated fraction
|
||||
int index = 0; // the index into fractions and colors
|
||||
for (int i = 0; i < stops.size(); i++) {
|
||||
GradientStop s = stops.get(i);
|
||||
//copy over the stop's data
|
||||
colors[index] = s.getColor();
|
||||
fractions[index] = s.getPosition();
|
||||
|
||||
//If this isn't the last stop, then add in the fraction
|
||||
if (index < fractions.length - 1) {
|
||||
float f1 = s.getPosition();
|
||||
float f2 = stops.get(i + 1).getPosition();
|
||||
|
||||
index++;
|
||||
fractions[index] = f1 + (f2 - f1) * s.getMidpoint();
|
||||
colors[index] = interpolate(colors[index - 1], stops.get(i + 1).getColor(), .5f);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
for (int i = 1; i < fractions.length; i++) {
|
||||
//to avoid an error with LinearGradientPaint where two fractions
|
||||
//are identical, bump up the fraction value by a miniscule amount
|
||||
//if it is identical to the previous one
|
||||
//NOTE: The <= is critical because the previous value may already
|
||||
//have been bumped up
|
||||
if (fractions[i] <= fractions[i - 1]) {
|
||||
fractions[i] = fractions[i - 1] + .000001f;
|
||||
}
|
||||
}
|
||||
|
||||
//another boundary condition where multiple stops are all at the end. The
|
||||
//previous loop bumped all but one of these past 1.0, which is bad.
|
||||
//so remove any fractions (and their colors!) that are beyond 1.0
|
||||
int outOfBoundsIndex = -1;
|
||||
for (int i = 0; i < fractions.length; i++) {
|
||||
if (fractions[i] > 1) {
|
||||
outOfBoundsIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outOfBoundsIndex >= 0) {
|
||||
float[] f = fractions;
|
||||
Matte[] c = colors;
|
||||
fractions = new float[outOfBoundsIndex];
|
||||
colors = new Matte[outOfBoundsIndex];
|
||||
System.arraycopy(f, 0, fractions, 0, outOfBoundsIndex);
|
||||
System.arraycopy(c, 0, colors, 0, outOfBoundsIndex);
|
||||
}
|
||||
|
||||
return createPaint(fractions, colors, cycleMethod);
|
||||
}
|
||||
|
||||
protected abstract Paint createPaint(float[] fractions, Matte[] colors, CycleMethod method);
|
||||
|
||||
protected static Matte interpolate(Matte v0, Matte v1, float fraction) {
|
||||
return new Matte(interpolate(v0.getColor(), v1.getColor(), fraction), v0.getUiDefaults());
|
||||
}
|
||||
|
||||
protected static Color interpolate(Color v0, Color v1, float fraction) {
|
||||
int r = v0.getRed() +
|
||||
(int) ((v1.getRed() - v0.getRed()) * fraction + 0.5f);
|
||||
int g = v0.getGreen() +
|
||||
(int) ((v1.getGreen() - v0.getGreen()) * fraction + 0.5f);
|
||||
int b = v0.getBlue() +
|
||||
(int) ((v1.getBlue() - v0.getBlue()) * fraction + 0.5f);
|
||||
int a = v0.getAlpha() +
|
||||
(int) ((v1.getAlpha() - v0.getAlpha()) * fraction + 0.5f);
|
||||
return new Color(r, g, b, a);
|
||||
}
|
||||
}
|
@ -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.LinearGradientPaint;
|
||||
import java.awt.MultipleGradientPaint.CycleMethod;
|
||||
import java.awt.Paint;
|
||||
|
||||
/**
|
||||
* Represents a GradientPaint or LinearGradientPaint.
|
||||
*
|
||||
* @author rbair
|
||||
*/
|
||||
public class Gradient extends AbstractGradient implements Cloneable {
|
||||
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 LinearGradientPaint(0, 0, 1, 0, fractions, colors, method);
|
||||
}
|
||||
|
||||
@Override public Gradient clone() {
|
||||
Gradient gradient = new Gradient();
|
||||
copyTo(gradient);
|
||||
return gradient;
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/** Each stop is defined linearly, at positions between 0 and 1. */
|
||||
public final class GradientStop extends AbstractBean implements Cloneable {
|
||||
private float position;
|
||||
private Matte color;
|
||||
private PropertyChangeListener matteListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("color", null, color);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The midpoint to the right of the stop. Must be 0 <= midpoint <= 1. The midpoint value of the last Stop is
|
||||
* ignored.
|
||||
*/
|
||||
private float midpoint;
|
||||
|
||||
public GradientStop() {}
|
||||
|
||||
public GradientStop(float position, Matte color) {
|
||||
if (color == null) {
|
||||
throw new IllegalArgumentException("Color must not be null");
|
||||
}
|
||||
|
||||
this.position = clamp(0, 1, position);
|
||||
this.color = color;
|
||||
this.midpoint = .5f;
|
||||
|
||||
if (this.color != null) {
|
||||
this.color.addPropertyChangeListener("color", matteListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public GradientStop clone() {
|
||||
GradientStop clone = new GradientStop(this.position, this.color.clone());
|
||||
clone.midpoint = midpoint;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public final float getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public final void setPosition(float position) {
|
||||
float old = this.position;
|
||||
this.position = clamp(0, 1, position);
|
||||
firePropertyChange("position", old, this.position);
|
||||
}
|
||||
|
||||
public final Matte getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public final void setColor(Matte c) {
|
||||
if (c == null) throw new IllegalArgumentException("Color must not be null");
|
||||
Matte old = this.color;
|
||||
if (old != null) old.removePropertyChangeListener(matteListener);
|
||||
this.color = c;
|
||||
if (this.color != null) this.color.addPropertyChangeListener(matteListener);
|
||||
firePropertyChange("color", old, c);
|
||||
}
|
||||
|
||||
public final void setOpacity(int opacity) {
|
||||
int old = getOpacity();
|
||||
color.setAlpha(opacity);
|
||||
firePropertyChange("opacity", old, getOpacity());
|
||||
}
|
||||
|
||||
public final int getOpacity() {
|
||||
return color.getAlpha();
|
||||
}
|
||||
|
||||
public final float getMidpoint() {
|
||||
return midpoint;
|
||||
}
|
||||
|
||||
public final void setMidpoint(float midpoint) {
|
||||
float old = this.midpoint;
|
||||
this.midpoint = clamp(0, 1, midpoint);
|
||||
firePropertyChange("midpoint", old, this.midpoint);
|
||||
}
|
||||
|
||||
private float clamp(float lo, float hi, float value) {
|
||||
if (value < lo) {
|
||||
return lo;
|
||||
} else if (value > hi) {
|
||||
return hi;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,610 @@
|
||||
/*
|
||||
* 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.swingx.designer.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
import java.awt.Paint;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
* Representing a single uniform color. Basically, it represents the java.awt.Color. It can either be absolute or
|
||||
* derived from a UIDefault color.
|
||||
*
|
||||
* @author rbair & jasper potts
|
||||
*/
|
||||
public class Matte extends PaintModel implements HasUIDefaults {
|
||||
private float[] tmpf1 = new float[3];
|
||||
private float[] tmpf2 = new float[3];
|
||||
|
||||
private int red;
|
||||
private int green;
|
||||
private int blue;
|
||||
private int alpha;
|
||||
private Color cached = null;
|
||||
|
||||
/**
|
||||
* The name of the ui default key to derive this color from.
|
||||
*/
|
||||
private String uiDefaultParentName = null;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private String componentPropertyName = null;
|
||||
private float hueOffset = 0, saturationOffset = 0, brightnessOffset = 0;
|
||||
private int alphaOffset = 0;
|
||||
/**
|
||||
* When true this color will become a UIResource in the UIManager defaults
|
||||
* table. If false, then it will not be a UIResource. This is sometimes
|
||||
* required, such as with colors installed on renderers.
|
||||
*/
|
||||
private boolean uiResource = true;
|
||||
|
||||
/** This is a local UIDefaults that contains all the UIDefaults in the Model. */
|
||||
private transient UIDefaults uiDefaults = new UIDefaults();
|
||||
private PropertyChangeListener uiDefaultsChangeListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (uiDefaultParentName != null && uiDefaultParentName.equals(evt.getPropertyName())) {
|
||||
updateARGBFromOffsets();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
/** propected constructor for JIBX */
|
||||
protected Matte() {}
|
||||
|
||||
public Matte(Color c, UIDefaults uiDefaults) {
|
||||
if (c != null) {
|
||||
this.red = c.getRed();
|
||||
this.green = c.getGreen();
|
||||
this.blue = c.getBlue();
|
||||
this.alpha = c.getAlpha();
|
||||
}
|
||||
setUiDefaults(uiDefaults);
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
protected void postSet(IUnmarshallingContext context) {
|
||||
// walk up till we get synth model
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIDefaults) {
|
||||
UIDefaults uiDefaults = ((HasUIDefaults) context.getStackObject(i)).getUiDefaults();
|
||||
if (uiDefaults != null) {
|
||||
setUiDefaults(uiDefaults);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Matte methods
|
||||
|
||||
/**
|
||||
* Is the matte an absolute color ot derived from a parent ui default
|
||||
*
|
||||
* @return <code>true</code> 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 <code>srcMatte</code> 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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
* <p/>
|
||||
* 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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
@ -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
|
||||
* <p/>
|
||||
* 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 <code>d.put("activeCaption", new
|
||||
* ColorUIResource(123, 45, 200));</code>
|
||||
* @param styleInit The buffer to write out code to generate Synth Style populating the styles map <code>m
|
||||
* = new HashMap<Key, LazyStyle>()</code>
|
||||
* @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,
|
||||
Map<String, String> variables, String packageNamePrefix,
|
||||
File painterPackageRoot) {
|
||||
// write color palette
|
||||
uiDefaultInit.append(" //Color palette\n");
|
||||
writeColorPalette(uiDefaultInit, model.getColorPalette());
|
||||
uiDefaultInit.append("\n");
|
||||
// write fonts palette
|
||||
uiDefaultInit.append(" //Font palette\n");
|
||||
uiDefaultInit.append(" d.put(\"defaultFont\", new FontUIResource(defaultFont));\n");
|
||||
writeFontPalette(uiDefaultInit, model.getFontPalette());
|
||||
uiDefaultInit.append("\n");
|
||||
// TODO: Other palettes
|
||||
uiDefaultInit.append(" //Border palette\n");
|
||||
uiDefaultInit.append("\n");
|
||||
// write global style
|
||||
uiDefaultInit.append(" //The global style definition\n");
|
||||
writeStyle(model.getStyle(), uiDefaultInit, "");
|
||||
uiDefaultInit.append("\n");
|
||||
// write components
|
||||
for (UIComponent c : model.getComponents()) {
|
||||
String prefix = escape(c.getKey());
|
||||
uiDefaultInit.append(" //Initialize ").append(prefix)
|
||||
.append("\n");
|
||||
writeRegion(c, c, prefix, uiDefaultInit,
|
||||
styleInit, variables, packageNamePrefix, painterPackageRoot);
|
||||
uiDefaultInit.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeColorPalette(StringBuilder uiDefaultInit, List<UIPaint> colors) {
|
||||
for (UIPaint color : colors) {
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(color.getName())
|
||||
.append("\",")
|
||||
.append(convertPaint(color.getValue()))
|
||||
.append(");\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeFontPalette(StringBuilder uiDefaultInit, List<UIFont> fonts) {
|
||||
for (UIFont font : fonts) {
|
||||
// We have no way of doing CSS style font lists yet so will just
|
||||
// just the first font
|
||||
if (!font.getFonts().isEmpty()){
|
||||
Typeface t = font.getFonts().get(0);
|
||||
if (t.isAbsolute()){
|
||||
Font f = t.getFont();
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(font.getName())
|
||||
.append("\", new javax.swing.plaf.FontUIResource(\"")
|
||||
.append(f.getName())
|
||||
.append("\", ")
|
||||
.append(f.getStyle())
|
||||
.append(", ")
|
||||
.append(f.getSize())
|
||||
.append("));\n");
|
||||
} else {
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(font.getName())
|
||||
.append("\", new DerivedFont(\"")
|
||||
.append(t.getUiDefaultParentName())
|
||||
.append("\", ")
|
||||
.append(t.getSizeOffset())
|
||||
.append("f, ");
|
||||
switch (t.getBold()){
|
||||
case Default:
|
||||
uiDefaultInit.append("null");
|
||||
break;
|
||||
case On:
|
||||
uiDefaultInit.append("true");
|
||||
break;
|
||||
case Off:
|
||||
uiDefaultInit.append("false");
|
||||
break;
|
||||
}
|
||||
uiDefaultInit.append(", ");
|
||||
switch (t.getItalic()){
|
||||
case Default:
|
||||
uiDefaultInit.append("null");
|
||||
break;
|
||||
case On:
|
||||
uiDefaultInit.append("true");
|
||||
break;
|
||||
case Off:
|
||||
uiDefaultInit.append("false");
|
||||
break;
|
||||
}
|
||||
uiDefaultInit.append("));\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the UIDefaults entries for a style
|
||||
*
|
||||
* @param style The style to write defaults entries for
|
||||
* @param uiDefaultInit The buffer to write ui default put methods of the form <code>d.put("activeCaption", new
|
||||
* ColorUIResource(123, 45, 200));</code>
|
||||
* @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 <code>reg</code> 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
|
||||
* <code>reg</code> 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, Map<String, String> variables,
|
||||
String packageNamePrefix, File painterPackageRoot) {
|
||||
// register component with LAF
|
||||
String regionCode = GeneratorUtils.getRegionNameCaps(region.getName());
|
||||
if (regionCode == null) {
|
||||
throw new IllegalStateException("We were asked to encode a region we know nothing about: " + region.getName());
|
||||
} else {
|
||||
regionCode = "Region." + regionCode;
|
||||
}
|
||||
|
||||
//construct the list of States that accompany this registration.
|
||||
StringBuffer regString = new StringBuffer(); //like: Enabled,Disabled,Foo,Default,Etc
|
||||
List<UIStateType> types = comp.getStateTypes(); //state types are only defined on the UIComponent level
|
||||
if (types != null && types.size() > 0) {
|
||||
for (UIStateType type : types) {
|
||||
regString.append(type.getKey());
|
||||
regString.append(",");
|
||||
}
|
||||
//remove the last ","
|
||||
regString.deleteCharAt(regString.length()-1);
|
||||
}
|
||||
|
||||
styleInit.append(" register(")
|
||||
.append(regionCode)
|
||||
.append(", \"")
|
||||
.append(prefix);
|
||||
styleInit.append("\"");
|
||||
styleInit.append(");\n");
|
||||
|
||||
// write content margins
|
||||
Insets i = (Insets) region.getContentMargins();
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(prefix)
|
||||
.append(".contentMargins")
|
||||
.append("\", new InsetsUIResource(")
|
||||
.append(i.top).append(", ").append(i.left).append(", ").append(i.bottom).append(", ").append(i.right)
|
||||
.append("));\n");
|
||||
// write opaque if true
|
||||
if (region instanceof UIComponent && ((UIComponent)region).isOpaque()) {
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(prefix)
|
||||
.append(".opaque")
|
||||
.append("\", Boolean.TRUE);\n");
|
||||
}
|
||||
//write the State, if necessary
|
||||
if (!regString.equals("Enabled,MouseOver,Pressed,Disabled,Focused,Selected,Default") && types.size() > 0) {
|
||||
//there were either custom states, or the normal states were in a custom order
|
||||
//so go ahead and write out prefix.State
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(prefix)
|
||||
.append(".States")
|
||||
.append("\", \"")
|
||||
.append(regString)
|
||||
.append("\");\n");
|
||||
}
|
||||
//write out any custom states, if necessary
|
||||
for (UIStateType type : types) {
|
||||
String synthState = type.getKey();
|
||||
if (!"Enabled".equals(synthState) &&
|
||||
!"MouseOver".equals(synthState) &&
|
||||
!"Pressed".equals(synthState) &&
|
||||
!"Disabled".equals(synthState) &&
|
||||
!"Focused".equals(synthState) &&
|
||||
!"Selected".equals(synthState) &&
|
||||
!"Default".equals(synthState)) {
|
||||
//what we have here, gentlemen, is a bona-fide custom state.
|
||||
try {
|
||||
//if the type is not one of the standard types, then construct a name for
|
||||
//the new type, and write out a new subclass of State.
|
||||
java.lang.String className = makePretty(prefix) + synthState + "State";
|
||||
java.lang.String body = type.getCodeSnippet();
|
||||
variables.put("STATE_NAME", className);
|
||||
variables.put("STATE_KEY", synthState);
|
||||
variables.put("BODY", body);
|
||||
|
||||
writeSrcFile(getStateTypeTemplate(), variables, new java.io.File(painterPackageRoot, className + ".java"));
|
||||
|
||||
variables.remove("STATE_NAME");
|
||||
variables.remove("STATE_KEY");
|
||||
variables.remove("BODY");
|
||||
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(prefix)
|
||||
.append(".")
|
||||
.append(synthState)
|
||||
.append("\", new ")
|
||||
.append(className)
|
||||
.append("());\n");
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
// write region style
|
||||
writeStyle(region.getStyle(), uiDefaultInit, prefix + ".");
|
||||
|
||||
try {
|
||||
boolean hasCanvas = hasCanvas(region);
|
||||
if (hasCanvas) {
|
||||
PainterGenerator.writePainter(region, variables, painterPackageRoot, prefix);
|
||||
}
|
||||
String fileNamePrefix = makePretty(prefix) + "Painter";
|
||||
// write states ui defaults
|
||||
for (UIState state : region.getBackgroundStates()) {
|
||||
String statePrefix = prefix + "[" + state.getName() + "]";
|
||||
// write state style
|
||||
writeStyle(state.getStyle(), uiDefaultInit, statePrefix + ".");
|
||||
// write painter
|
||||
if (hasCanvas) {
|
||||
writeLazyPainter(state, uiDefaultInit, statePrefix, packageNamePrefix, fileNamePrefix, "background");
|
||||
}
|
||||
}
|
||||
for (UIState state : region.getForegroundStates()) {
|
||||
String statePrefix = prefix + "[" + state.getName() + "]";
|
||||
// write state style
|
||||
writeStyle(state.getStyle(), uiDefaultInit, statePrefix + ".");
|
||||
// write painter
|
||||
if (hasCanvas) {
|
||||
writeLazyPainter(state, uiDefaultInit, statePrefix, packageNamePrefix, fileNamePrefix, "foreground");
|
||||
}
|
||||
}
|
||||
for (UIState state : region.getBorderStates()) {
|
||||
String statePrefix = prefix + "[" + state.getName() + "]";
|
||||
// write state style
|
||||
writeStyle(state.getStyle(), uiDefaultInit, statePrefix + ".");
|
||||
// write painter
|
||||
if (hasCanvas) {
|
||||
writeLazyPainter(state, uiDefaultInit, statePrefix, packageNamePrefix, fileNamePrefix, "border");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// handle sub regions
|
||||
for (UIRegion subRegion : region.getSubRegions()) {
|
||||
String subregionName = prefix + ":" + escape(subRegion.getKey());
|
||||
if (subRegion instanceof UIIconRegion) {
|
||||
writeIconRegion(comp, (UIIconRegion) subRegion, prefix, uiDefaultInit,
|
||||
variables, packageNamePrefix, painterPackageRoot);
|
||||
} else if (subRegion instanceof UIComponent) {
|
||||
// inner named component
|
||||
UIComponent subComponent = (UIComponent) subRegion;
|
||||
writeRegion(subComponent, subRegion, subregionName,
|
||||
uiDefaultInit, styleInit, variables, packageNamePrefix, painterPackageRoot);
|
||||
} else {
|
||||
writeRegion(comp, subRegion, subregionName, uiDefaultInit, styleInit, variables,
|
||||
packageNamePrefix, painterPackageRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeLazyPainter(UIState state, StringBuilder uiDefaultInit, String statePrefix, String packageNamePrefix, String fileNamePrefix, String painterSuffix) {
|
||||
Canvas canvas = state.getCanvas();
|
||||
if (!canvas.isBlank()) {
|
||||
Insets si = canvas.getStretchingInsets();
|
||||
boolean inverted = state.isInverted();
|
||||
UIStyle.CacheMode cache = state.getStyle().getCacheMode();
|
||||
String cacheModeString = null;
|
||||
switch (cache) {
|
||||
case NO_CACHING: cacheModeString = "AbstractRegionPainter.PaintContext.CacheMode.NO_CACHING"; break;
|
||||
case FIXED_SIZES: cacheModeString = "AbstractRegionPainter.PaintContext.CacheMode.FIXED_SIZES"; break;
|
||||
case NINE_SQUARE_SCALE: cacheModeString = "AbstractRegionPainter.PaintContext.CacheMode.NINE_SQUARE_SCALE"; break;
|
||||
}
|
||||
double maxH = state.getStyle().getMaxHozCachedImgScaling();
|
||||
double maxV = state.getStyle().getMaxVertCachedImgScaling();
|
||||
String stateConstant = toConstantName(painterSuffix + "_" + UIState.keysToString(state.getStateKeys()));
|
||||
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(statePrefix)
|
||||
.append(".").append(painterSuffix).append("Painter\", new LazyPainter(\"")
|
||||
.append(packageNamePrefix).append(".").append(fileNamePrefix)
|
||||
.append("\", ")
|
||||
.append(fileNamePrefix).append(".").append(stateConstant).append(", ")
|
||||
.append(convert(si)).append(", ")
|
||||
.append(convert(canvas.getSize())).append(", ")
|
||||
.append(inverted).append(", ")
|
||||
.append(cacheModeString).append(", ")
|
||||
.append(maxH == Double.POSITIVE_INFINITY ? "Double.POSITIVE_INFINITY" : maxH).append(", ")
|
||||
.append(maxV == Double.POSITIVE_INFINITY ? "Double.POSITIVE_INFINITY" : maxV).append("));\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write out code for a IconRegion
|
||||
*
|
||||
* @param comp This may be the same as the region <code>region</code> 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<String, String> variables,
|
||||
String packageNamePrefix, File painterPackageRoot) {
|
||||
|
||||
Dimension size = null;
|
||||
String fileNamePrefix = makePretty(prefix) + "Painter";
|
||||
// write states ui defaults
|
||||
for (UIState state : region.getBackgroundStates()) {// TODO: Handle Background,Foreground and Borders States Lists? Actually not sure that IconRegions need support borders or foregrounds
|
||||
Canvas canvas = state.getCanvas();
|
||||
if (!canvas.isBlank()) {
|
||||
String statePrefix = prefix + "[" + state.getName() + "]";
|
||||
// Put Painter in UiDefaults
|
||||
writeLazyPainter(state, uiDefaultInit, statePrefix, packageNamePrefix, fileNamePrefix, region.getKey());
|
||||
size = canvas.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
if (size != null) {
|
||||
// Put SynthIconImpl wrapper in UiDefaults
|
||||
String key = region.getBasicKey() == null ? prefix + "." + region.getKey() : region.getBasicKey();
|
||||
uiDefaultInit.append(" d.put(\"")
|
||||
.append(key)
|
||||
.append("\", new NimbusIcon(\"") //TODO should this be wrapped in an IconUIResource?
|
||||
.append(prefix)
|
||||
.append("\", \"")
|
||||
.append(region.getKey())
|
||||
.append("Painter")
|
||||
.append("\", ")
|
||||
.append(size.width)
|
||||
.append(", ")
|
||||
.append(size.height)
|
||||
.append("));\n");
|
||||
}
|
||||
|
||||
// handle sub regions
|
||||
if (region.getSubRegions().length > 0) {
|
||||
// there is no meaning to a sub region inside a IconRegion
|
||||
throw new IllegalStateException("You can not have sub regions inside UiIconRegions. \"" +
|
||||
comp.getSubRegions()[0].getName() + "\" is inside \""
|
||||
+ prefix.substring(0, prefix.length() - 1) + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for escaping all double quotes with backslash double-quote.
|
||||
*/
|
||||
private static String escape(String s) {
|
||||
return s.replace("\"", "\\\"");
|
||||
}
|
||||
|
||||
private static String convertPaint(PaintModel paint){
|
||||
if (paint instanceof Matte){
|
||||
Matte matte = (Matte)paint;
|
||||
if (matte.isAbsolute()){
|
||||
String colorParams = convert(matte.getColor());
|
||||
if (matte.isUiResource()) {
|
||||
return "new ColorUIResource(" + colorParams + ")";
|
||||
} else {
|
||||
return colorParams;
|
||||
}
|
||||
} else {
|
||||
String s = "getDerivedColor(\"" +
|
||||
matte.getUiDefaultParentName()+"\","+
|
||||
matte.getHueOffset()+"f,"+matte.getSaturationOffset()+
|
||||
"f,"+matte.getBrightnessOffset()+"f,"+
|
||||
matte.getAlphaOffset();
|
||||
if (matte.isUiResource()) {
|
||||
return s + ")";
|
||||
} else {
|
||||
return s + ",false)";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//TODO: What about gradients etc here?
|
||||
System.err.println("Error: Could not write paint in " +
|
||||
"DefaultsGenerator as it was not a Matte. = "+
|
||||
paint.getClass().getName());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertBorder(Border val) {
|
||||
StringBuilder uiDefaultInit = new StringBuilder();
|
||||
Insets i;
|
||||
if (val instanceof PainterBorder) {
|
||||
PainterBorder pb = (PainterBorder) val;
|
||||
i = pb.getBorderInsets();
|
||||
uiDefaultInit.append("new PainterBorder(\"")
|
||||
.append(pb.getPainterName())
|
||||
.append("\", new Insets(")
|
||||
.append(i.top).append(", ")
|
||||
.append(i.left).append(", ")
|
||||
.append(i.bottom).append(", ")
|
||||
.append(i.right)
|
||||
.append("))");
|
||||
} else if (val instanceof EmptyBorder) {
|
||||
i = ((EmptyBorder) val).getBorderInsets();
|
||||
uiDefaultInit.append("BorderFactory.createEmptyBorder(")
|
||||
.append(i.top).append(", ")
|
||||
.append(i.left).append(", ")
|
||||
.append(i.bottom).append(", ")
|
||||
.append(i.right)
|
||||
.append(")");
|
||||
} else if (val instanceof LineBorder) {
|
||||
LineBorder border = (LineBorder) val;
|
||||
uiDefaultInit.append("BorderFactory.createLineBorder(")
|
||||
.append(convert(border.getLineColor()))
|
||||
.append(",")
|
||||
.append(border.getThickness())
|
||||
.append(")");
|
||||
} else if (val instanceof EtchedBorder) {
|
||||
EtchedBorder border = (EtchedBorder) val;
|
||||
uiDefaultInit.append("BorderFactory.createEtchedBorder(")
|
||||
.append(border.getEtchType())
|
||||
.append(",")
|
||||
.append(convert(border.getHighlightColor()))
|
||||
.append(",")
|
||||
.append(convert(border.getShadowColor()))
|
||||
.append(")");
|
||||
} else if (val instanceof BevelBorder) {
|
||||
BevelBorder border = (BevelBorder) val;
|
||||
uiDefaultInit.append("BorderFactory.createEtchedBorder(")
|
||||
.append(border.getBevelType())
|
||||
.append(",")
|
||||
.append(convert(border.getHighlightOuterColor()))
|
||||
.append(",")
|
||||
.append(convert(border.getHighlightInnerColor()))
|
||||
.append(",")
|
||||
.append(convert(border.getShadowOuterColor()))
|
||||
.append(",")
|
||||
.append(convert(border.getShadowInnerColor()))
|
||||
.append(")");
|
||||
} else if (val instanceof MatteBorder) {
|
||||
MatteBorder border = (MatteBorder) val;
|
||||
i = border.getBorderInsets();
|
||||
uiDefaultInit.append("BorderFactory.createEmptyBorder(")
|
||||
.append(i.top).append(", ")
|
||||
.append(i.left).append(", ")
|
||||
.append(i.bottom).append(", ")
|
||||
.append(i.right).append(", ")
|
||||
.append(convert(border.getMatteColor()))
|
||||
.append(")");
|
||||
} else if (val instanceof CompoundBorder) {
|
||||
CompoundBorder border = (CompoundBorder) val;
|
||||
uiDefaultInit.append("BorderFactory.createEmptyBorder(")
|
||||
.append(convertBorder(border.getOutsideBorder()))
|
||||
.append(",")
|
||||
.append(convertBorder(border.getInsideBorder()))
|
||||
.append(")");
|
||||
}
|
||||
return uiDefaultInit.toString();
|
||||
}
|
||||
|
||||
private static boolean hasCanvas(UIRegion region) {
|
||||
for (UIState s : region.getBackgroundStates()) {
|
||||
if (!s.getCanvas().isBlank()) return true;
|
||||
}
|
||||
for (UIState s : region.getBorderStates()) {
|
||||
if (!s.getCanvas().isBlank()) return true;
|
||||
}
|
||||
for (UIState s : region.getForegroundStates()) {
|
||||
if (!s.getCanvas().isBlank()) return true;
|
||||
}
|
||||
for (UIRegion subregion : region.getSubRegions()) {
|
||||
if (hasCanvas(subregion)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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 static org.jdesktop.synthdesigner.generator.TemplateWriter.read;
|
||||
import static org.jdesktop.synthdesigner.generator.TemplateWriter.writeSrcFile;
|
||||
import org.jdesktop.synthdesigner.synthmodel.SynthModel;
|
||||
import org.jibx.runtime.BindingDirectory;
|
||||
import org.jibx.runtime.IBindingFactory;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Generates the various Java artifacts based on a SynthModel.
|
||||
* <p/>
|
||||
* Generated source files are split up among two different locations. There are those source files that are meant to be
|
||||
* edited (generally, only the LookAndFeel class itself) and those that are autogenerated (everything else).
|
||||
* <p/>
|
||||
* All autogenerated files are placed in "buildPackageRoot" and are package private. A LAF author (one who has access to
|
||||
* the generated sources) will be able to access any of the generated classes. Those referencing the library, however,
|
||||
* will only be able to access the main LookAndFeel class itself (since everything else is package private).
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class Generator {
|
||||
/** A map of variables that are used for variable substitution in the template files. */
|
||||
private Map<String, String> variables;
|
||||
|
||||
private boolean full = false;
|
||||
private File buildPackageRoot;
|
||||
private File srcPackageRoot;
|
||||
private String packageNamePrefix;
|
||||
private String lafName;
|
||||
private SynthModel model;
|
||||
|
||||
/**
|
||||
* MAIN APPLICATION
|
||||
* <p/>
|
||||
* This is for using the generator as part of the java build process
|
||||
*
|
||||
* @param args The commandline arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0 || (args.length % 2) != 0) {
|
||||
System.out.println("Usage: generator [-options]\n" +
|
||||
" -full <true|false> True if we should build the whole LAF or false for building just states and painters.\n" +
|
||||
" -skinFile <value> Path to the skin.laf file for the LAF to be generated from.\n" +
|
||||
" -buildDir <value> The directory beneath which the build-controlled artifacts (such as the Painters) should\n" +
|
||||
" be placed. This is the root directory beneath which the necessary packages and source\n" +
|
||||
" files will be created.\n" +
|
||||
" -srcDir <value> The directory beneath which the normal user-controlled artifacts (such as the core\n" +
|
||||
" LookAndFeel file) should be placed. These are one-time generated files. This is the root\n" +
|
||||
" directory beneath which the necessary packages and source files will be created.\n" +
|
||||
" -resourcesDir <value> The resources directory containing templates and images.\n" +
|
||||
" -packagePrefix <value> The package name associated with this synth look and feel. For example,\n" +
|
||||
" \"org.mypackage.mylaf\"\n" +
|
||||
" -lafName <value> The name of the laf, such as \"MyLAF\".\n");
|
||||
} else {
|
||||
boolean full = false;
|
||||
File skinFile = new File(System.getProperty("user.dir"));
|
||||
File buildDir = new File(System.getProperty("user.dir"));
|
||||
File srcDir = new File(System.getProperty("user.dir"));
|
||||
File resourcesDir = new File(System.getProperty("user.dir"));
|
||||
String packagePrefix = "org.mypackage.mylaf";
|
||||
String lafName = "MyLAF";
|
||||
for (int i = 0; i < args.length; i += 2) {
|
||||
String key = args[i].trim().toLowerCase();
|
||||
String value = args[i + 1].trim();
|
||||
if ("-full".equals(key)) {
|
||||
full = Boolean.parseBoolean(value);
|
||||
} else if ("-skinfile".equals(key)) {
|
||||
skinFile = new File(value);
|
||||
} else if ("-builddir".equals(key)) {
|
||||
buildDir = new File(value);
|
||||
} else if ("-srcdir".equals(key)) {
|
||||
srcDir = new File(value);
|
||||
} else if ("-resourcesdir".equals(key)) {
|
||||
resourcesDir = new File(value);
|
||||
} else if ("-packageprefix".equals(key)) {
|
||||
packagePrefix = value;
|
||||
} else if ("-lafname".equals(key)) {
|
||||
lafName = value;
|
||||
}
|
||||
}
|
||||
System.out.println("### GENERATING LAF CODE ################################");
|
||||
System.out.println(" full :" + full);
|
||||
System.out.println(" skinFile :" + skinFile.getAbsolutePath());
|
||||
System.out.println(" buildDir :" + buildDir.getAbsolutePath());
|
||||
System.out.println(" srcDir :" + srcDir.getAbsolutePath());
|
||||
System.out.println(" resourcesDir :" + resourcesDir.getAbsolutePath());
|
||||
System.out.println(" packagePrefix :" +packagePrefix);
|
||||
System.out.println(" lafName :" +lafName);
|
||||
try {
|
||||
// LOAD SKIN MODEL
|
||||
IBindingFactory bindingFactory = BindingDirectory.getFactory(SynthModel.class);
|
||||
IUnmarshallingContext mctx = bindingFactory.createUnmarshallingContext();
|
||||
mctx.setDocument(new FileInputStream(skinFile), "UTF-8");
|
||||
// pass resources directory in as user context so it can be used in SynthModel preSet
|
||||
mctx.setUserContext(resourcesDir);
|
||||
SynthModel model = (SynthModel) mctx.unmarshalElement();
|
||||
// create and run generator
|
||||
Generator generator = new Generator(full, buildDir, srcDir, packagePrefix, lafName, model);
|
||||
generator.generate();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error loading skin and generating java src:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Generator, capable of outputting the source code artifacts related to a given SynthModel. It is
|
||||
* capable of generating the one-time artifacts in addition to the regeneration of build-controlled artifacts.
|
||||
*
|
||||
* @param full True if we should build the whole LAF or false for building just states and painters.
|
||||
* @param buildDir The directory beneath which the build-controlled artifacts (such as the Painters) should
|
||||
* be placed. This is the root directory beneath which the necessary packages and source
|
||||
* files will be created.
|
||||
* @param srcDir The directory beneath which the normal user-controlled artifacts (such as the core
|
||||
* LookAndFeel file) should be placed. These are one-time generated files. This is the root
|
||||
* directory beneath which the necessary packages and source files will be created.
|
||||
* @param packageNamePrefix The package name associated with this synth look and feel. For example,
|
||||
* org.mypackage.mylaf
|
||||
* @param lafName The name of the laf, such as MyLAF.
|
||||
* @param model The actual SynthModel to base these generated files on.
|
||||
*/
|
||||
public Generator(boolean full, File buildDir, File srcDir, String packageNamePrefix, String lafName,
|
||||
SynthModel model) {
|
||||
this.full = full;
|
||||
//validate the input variables
|
||||
if (packageNamePrefix == null) {
|
||||
throw new IllegalArgumentException("You must specify a package name prefix");
|
||||
}
|
||||
if (buildDir == null) {
|
||||
throw new IllegalArgumentException("You must specify the build directory");
|
||||
}
|
||||
if (srcDir == null) {
|
||||
throw new IllegalArgumentException("You must specify the source directory");
|
||||
}
|
||||
if (model == null) {
|
||||
throw new IllegalArgumentException("You must specify the SynthModel");
|
||||
}
|
||||
if (lafName == null) {
|
||||
throw new IllegalArgumentException("You must specify the name of the look and feel");
|
||||
}
|
||||
|
||||
//construct the map which is used to do variable substitution of the template
|
||||
//files
|
||||
variables = new HashMap<String, String>();
|
||||
variables.put("PACKAGE", packageNamePrefix);
|
||||
variables.put("LAF_NAME", lafName);
|
||||
|
||||
//generate and save references to the package-root directories.
|
||||
//(That is, given the buildDir and srcDir, generate references to the
|
||||
//org.mypackage.mylaf subdirectories)
|
||||
buildPackageRoot = new File(buildDir, packageNamePrefix.replaceAll("\\.", "\\/"));
|
||||
buildPackageRoot.mkdirs();
|
||||
srcPackageRoot = new File(srcDir, packageNamePrefix.replaceAll("\\.", "\\/"));
|
||||
srcPackageRoot.mkdirs();
|
||||
|
||||
//save the variables
|
||||
this.packageNamePrefix = packageNamePrefix;
|
||||
this.lafName = lafName;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
//Generate the one-time files. If these files already exist, skip the
|
||||
//ones that exist and create the missing ones. Register warnings for the
|
||||
//already existing files.
|
||||
|
||||
//TODO Skip existing files, send warnings, etc.
|
||||
if (full) {
|
||||
try {
|
||||
//create the LookAndFeel file
|
||||
String template = read("resources/LookAndFeel.template");
|
||||
writeSrcFile(template, variables, new File(srcPackageRoot, lafName + "LookAndFeel.java"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//create the painters and such.
|
||||
regenerate();
|
||||
}
|
||||
|
||||
public void regenerate() {
|
||||
try {
|
||||
if (full) {
|
||||
//first, create the AbstractRegionPainter.java file.
|
||||
String template = read("resources/AbstractRegionPainter.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "AbstractRegionPainter.java"));
|
||||
|
||||
//write out BlendingMode.java
|
||||
template = read("resources/BlendingMode.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "BlendingMode.java"));
|
||||
|
||||
//create the SynthPainterImpl class
|
||||
template = read("resources/SynthPainterImpl.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "SynthPainterImpl.java"));
|
||||
|
||||
//create the IconImpl class
|
||||
template = read("resources/IconImpl.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, lafName + "Icon.java"));
|
||||
|
||||
//create the StyleImpl class
|
||||
template = read("resources/StyleImpl.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, lafName + "Style.java"));
|
||||
|
||||
//write out Effect.java
|
||||
template = read("resources/Effect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "Effect.java"));
|
||||
|
||||
//write out EffectUtils.java
|
||||
template = read("resources/EffectUtils.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "EffectUtils.java"));
|
||||
|
||||
//write out ShadowEffect.java
|
||||
template = read("resources/ShadowEffect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "ShadowEffect.java"));
|
||||
|
||||
//write out DropShadowEffect.java
|
||||
template = read("resources/DropShadowEffect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "DropShadowEffect.java"));
|
||||
|
||||
//write out InnerShadowEffect.java
|
||||
template = read("resources/InnerShadowEffect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "InnerShadowEffect.java"));
|
||||
|
||||
//write out InnerGlowEffect.java
|
||||
template = read("resources/InnerGlowEffect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "InnerGlowEffect.java"));
|
||||
|
||||
//write out OuterGlowEffect.java
|
||||
template = read("resources/OuterGlowEffect.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "OuterGlowEffect.java"));
|
||||
|
||||
//write out State.java
|
||||
template = read("resources/State.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "State.java"));
|
||||
|
||||
template = read("resources/ImageCache.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "ImageCache.java"));
|
||||
|
||||
template = read("resources/ImageScalingHelper.template");
|
||||
writeSrcFile(template, variables, new File(buildPackageRoot, "ImageScalingHelper.java"));
|
||||
}
|
||||
//next, populate the first set of ui defaults based on what is in the
|
||||
//various palettes of the synth model
|
||||
StringBuilder uiDefaultInit = new StringBuilder();
|
||||
StringBuilder styleInit = new StringBuilder();
|
||||
DefaultsGenerator.generateDefaults(uiDefaultInit, styleInit, model, variables, packageNamePrefix,
|
||||
buildPackageRoot);
|
||||
variables.put("UI_DEFAULT_INIT", uiDefaultInit.toString());
|
||||
variables.put("STYLE_INIT", styleInit.toString());
|
||||
writeSrcFile(read("resources/Defaults.template"), variables,
|
||||
new File(buildPackageRoot, lafName + "Defaults.java"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* 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 javax.swing.plaf.synth.Region;
|
||||
import javax.swing.plaf.synth.SynthConstants;
|
||||
|
||||
/**
|
||||
* GeneratorUtils
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
class GeneratorUtils {
|
||||
private GeneratorUtils() {}
|
||||
|
||||
/**
|
||||
* Given a synth state, create the appropriate name as it would be used for a ui default key.
|
||||
* <p/>
|
||||
* For example:
|
||||
* <p/>
|
||||
* enabled enabled+over enabled+over+selected
|
||||
*/
|
||||
static String toUIDefaultKey(int state) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if ((state & SynthConstants.DEFAULT) == SynthConstants.DEFAULT) {
|
||||
buffer.append("default");
|
||||
}
|
||||
if ((state & SynthConstants.DISABLED) == SynthConstants.DISABLED) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("disabled");
|
||||
}
|
||||
if ((state & SynthConstants.ENABLED) == SynthConstants.ENABLED) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("enabled");
|
||||
}
|
||||
if ((state & SynthConstants.FOCUSED) == SynthConstants.FOCUSED) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("focused");
|
||||
}
|
||||
if ((state & SynthConstants.MOUSE_OVER) == SynthConstants.MOUSE_OVER) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("over");
|
||||
}
|
||||
if ((state & SynthConstants.PRESSED) == SynthConstants.PRESSED) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("down");
|
||||
}
|
||||
if ((state & SynthConstants.SELECTED) == SynthConstants.SELECTED) {
|
||||
if (buffer.length() > 0) buffer.append("+");
|
||||
buffer.append("selected");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
//takes a states string of the form Enabled+Foo+Bar.
|
||||
//removes any whitespace. Replaces the + signs with And.
|
||||
static String toClassName(String states) {
|
||||
String s = states.replace(" ", "");
|
||||
s = states.replace("+", "And");
|
||||
return s;
|
||||
}
|
||||
|
||||
//takes a states string of the form Enabled+Foo+Bar.
|
||||
//removes any whitespace. Replaces the + signs with _.
|
||||
//capitalizes the whole lot
|
||||
static String toConstantName(String states) {
|
||||
String s = states.replace(" ", "");
|
||||
s = states.replace("+", "_");
|
||||
return s.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string "s" of the form:
|
||||
*
|
||||
* A.\"A.a\".B
|
||||
*
|
||||
* Make it such that:
|
||||
*
|
||||
* AAAB
|
||||
*
|
||||
* For example, ComboBox.\"ComboBox.arrowButton\" would become
|
||||
* ComboBoxComboBoxArrowButton
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
static String makePretty(String s) {
|
||||
char[] src = s.toCharArray();
|
||||
char[] dst = new char[src.length];
|
||||
int dstIndex = 0;
|
||||
for (int i=0; i<src.length; i++) {
|
||||
//if the src char is a period and there is a following character,
|
||||
//make sure the character is capitalized.
|
||||
if ((src[i] == '.' || src[i] == ':') && i < src.length -1) {
|
||||
src[i+1] = Character.toUpperCase(src[i+1]);
|
||||
continue;
|
||||
}
|
||||
//if the src char is one that is to be removed, skip it.
|
||||
if (src[i] == '.' || src[i] == ':' || src[i] == '\\' || src[i] == '"') {
|
||||
continue;
|
||||
}
|
||||
//copy over the current char.
|
||||
dst[dstIndex++] = src[i];
|
||||
}
|
||||
//at this point, dstIndex is 1 greater than the last valid index position in dst
|
||||
//or in other words it represents the count.
|
||||
return new String(dst, 0, dstIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given synth state as if it were specified in java code, such as
|
||||
* <p/>
|
||||
* SynthConstants.ENABLED | SynthConstants.MOUSE_OVER
|
||||
*/
|
||||
static String toJavaList(int state) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if ((state & SynthConstants.DEFAULT) == SynthConstants.DEFAULT) {
|
||||
buffer.append("SynthConstants.DEFAULT");
|
||||
}
|
||||
if ((state & SynthConstants.DISABLED) == SynthConstants.DISABLED) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.DISABLED");
|
||||
}
|
||||
if ((state & SynthConstants.ENABLED) == SynthConstants.ENABLED) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.ENABLED");
|
||||
}
|
||||
if ((state & SynthConstants.FOCUSED) == SynthConstants.FOCUSED) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.FOCUSED");
|
||||
}
|
||||
if ((state & SynthConstants.MOUSE_OVER) == SynthConstants.MOUSE_OVER) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.MOUSE_OVER");
|
||||
}
|
||||
if ((state & SynthConstants.PRESSED) == SynthConstants.PRESSED) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.PRESSED");
|
||||
}
|
||||
if ((state & SynthConstants.SELECTED) == SynthConstants.SELECTED) {
|
||||
if (buffer.length() > 0) buffer.append(" | ");
|
||||
buffer.append("SynthConstants.SELECTED");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given region name to discover if it is one of the standard synth regions. If so, return the name in
|
||||
* caps and such. Otherwise, return a big fat null.
|
||||
* <p/>
|
||||
* I have to do this because, unfortunately, synth's Region doesn't implement equals.
|
||||
*/
|
||||
static String getRegionNameCaps(String regionName) {
|
||||
if (Region.ARROW_BUTTON.getName().equals(regionName)) {
|
||||
return "ARROW_BUTTON";
|
||||
} else if (Region.BUTTON.getName().equals(regionName)) {
|
||||
return "BUTTON";
|
||||
} else if (Region.CHECK_BOX.getName().equals(regionName)) {
|
||||
return "CHECK_BOX";
|
||||
} else if (Region.CHECK_BOX_MENU_ITEM.getName().equals(regionName)) {
|
||||
return "CHECK_BOX_MENU_ITEM";
|
||||
} else if (Region.COLOR_CHOOSER.getName().equals(regionName)) {
|
||||
return "COLOR_CHOOSER";
|
||||
} else if (Region.COMBO_BOX.getName().equals(regionName)) {
|
||||
return "COMBO_BOX";
|
||||
} else if (Region.DESKTOP_ICON.getName().equals(regionName)) {
|
||||
return "DESKTOP_ICON";
|
||||
} else if (Region.DESKTOP_PANE.getName().equals(regionName)) {
|
||||
return "DESKTOP_PANE";
|
||||
} else if (Region.EDITOR_PANE.getName().equals(regionName)) {
|
||||
return "EDITOR_PANE";
|
||||
} else if (Region.FILE_CHOOSER.getName().equals(regionName)) {
|
||||
return "FILE_CHOOSER";
|
||||
} else if (Region.FORMATTED_TEXT_FIELD.getName().equals(regionName)) {
|
||||
return "FORMATTED_TEXT_FIELD";
|
||||
} else if (Region.INTERNAL_FRAME.getName().equals(regionName)) {
|
||||
return "INTERNAL_FRAME";
|
||||
} else if (Region.INTERNAL_FRAME_TITLE_PANE.getName().equals(regionName)) {
|
||||
return "INTERNAL_FRAME_TITLE_PANE";
|
||||
} else if (Region.LABEL.getName().equals(regionName)) {
|
||||
return "LABEL";
|
||||
} else if (Region.LIST.getName().equals(regionName)) {
|
||||
return "LIST";
|
||||
} else if (Region.MENU.getName().equals(regionName)) {
|
||||
return "MENU";
|
||||
} else if (Region.MENU_BAR.getName().equals(regionName)) {
|
||||
return "MENU_BAR";
|
||||
} else if (Region.MENU_ITEM.getName().equals(regionName)) {
|
||||
return "MENU_ITEM";
|
||||
} else if (Region.MENU_ITEM_ACCELERATOR.getName().equals(regionName)) {
|
||||
return "MENU_ITEM_ACCELERATOR";
|
||||
} else if (Region.OPTION_PANE.getName().equals(regionName)) {
|
||||
return "OPTION_PANE";
|
||||
} else if (Region.PANEL.getName().equals(regionName)) {
|
||||
return "PANEL";
|
||||
} else if (Region.PASSWORD_FIELD.getName().equals(regionName)) {
|
||||
return "PASSWORD_FIELD";
|
||||
} else if (Region.POPUP_MENU.getName().equals(regionName)) {
|
||||
return "POPUP_MENU";
|
||||
} else if (Region.POPUP_MENU_SEPARATOR.getName().equals(regionName)) {
|
||||
return "POPUP_MENU_SEPARATOR";
|
||||
} else if (Region.PROGRESS_BAR.getName().equals(regionName)) {
|
||||
return "PROGRESS_BAR";
|
||||
} else if (Region.RADIO_BUTTON.getName().equals(regionName)) {
|
||||
return "RADIO_BUTTON";
|
||||
} else if (Region.RADIO_BUTTON_MENU_ITEM.getName().equals(regionName)) {
|
||||
return "RADIO_BUTTON_MENU_ITEM";
|
||||
} else if (Region.ROOT_PANE.getName().equals(regionName)) {
|
||||
return "ROOT_PANE";
|
||||
} else if (Region.SCROLL_BAR.getName().equals(regionName)) {
|
||||
return "SCROLL_BAR";
|
||||
} else if (Region.SCROLL_BAR_THUMB.getName().equals(regionName)) {
|
||||
return "SCROLL_BAR_THUMB";
|
||||
} else if (Region.SCROLL_BAR_TRACK.getName().equals(regionName)) {
|
||||
return "SCROLL_BAR_TRACK";
|
||||
} else if (Region.SCROLL_PANE.getName().equals(regionName)) {
|
||||
return "SCROLL_PANE";
|
||||
} else if (Region.SEPARATOR.getName().equals(regionName)) {
|
||||
return "SEPARATOR";
|
||||
} else if (Region.SLIDER.getName().equals(regionName)) {
|
||||
return "SLIDER";
|
||||
} else if (Region.SLIDER_THUMB.getName().equals(regionName)) {
|
||||
return "SLIDER_THUMB";
|
||||
} else if (Region.SLIDER_TRACK.getName().equals(regionName)) {
|
||||
return "SLIDER_TRACK";
|
||||
} else if (Region.SPINNER.getName().equals(regionName)) {
|
||||
return "SPINNER";
|
||||
} else if (Region.SPLIT_PANE.getName().equals(regionName)) {
|
||||
return "SPLIT_PANE";
|
||||
} else if (Region.SPLIT_PANE_DIVIDER.getName().equals(regionName)) {
|
||||
return "SPLIT_PANE_DIVIDER";
|
||||
} else if (Region.TABBED_PANE.getName().equals(regionName)) {
|
||||
return "TABBED_PANE";
|
||||
} else if (Region.TABBED_PANE_CONTENT.getName().equals(regionName)) {
|
||||
return "TABBED_PANE_CONTENT";
|
||||
} else if (Region.TABBED_PANE_TAB.getName().equals(regionName)) {
|
||||
return "TABBED_PANE_TAB";
|
||||
} else if (Region.TABBED_PANE_TAB_AREA.getName().equals(regionName)) {
|
||||
return "TABBED_PANE_TAB_AREA";
|
||||
} else if (Region.TABLE.getName().equals(regionName)) {
|
||||
return "TABLE";
|
||||
} else if (Region.TABLE_HEADER.getName().equals(regionName)) {
|
||||
return "TABLE_HEADER";
|
||||
} else if (Region.TEXT_AREA.getName().equals(regionName)) {
|
||||
return "TEXT_AREA";
|
||||
} else if (Region.TEXT_FIELD.getName().equals(regionName)) {
|
||||
return "TEXT_FIELD";
|
||||
} else if (Region.TEXT_PANE.getName().equals(regionName)) {
|
||||
return "TEXT_PANE";
|
||||
} else if (Region.TOGGLE_BUTTON.getName().equals(regionName)) {
|
||||
return "TOGGLE_BUTTON";
|
||||
} else if (Region.TOOL_BAR.getName().equals(regionName)) {
|
||||
return "TOOL_BAR";
|
||||
} else if (Region.TOOL_BAR_CONTENT.getName().equals(regionName)) {
|
||||
return "TOOL_BAR_CONTENT";
|
||||
} else if (Region.TOOL_BAR_DRAG_WINDOW.getName().equals(regionName)) {
|
||||
return "TOOL_BAR_DRAG_WINDOW";
|
||||
} else if (Region.TOOL_BAR_SEPARATOR.getName().equals(regionName)) {
|
||||
return "TOOL_BAR_SEPARATOR";
|
||||
} else if (Region.TOOL_TIP.getName().equals(regionName)) {
|
||||
return "TOOL_TIP";
|
||||
} else if (Region.TREE.getName().equals(regionName)) {
|
||||
return "TREE";
|
||||
} else if (Region.TREE_CELL.getName().equals(regionName)) {
|
||||
return "TREE_CELL";
|
||||
} else if (Region.VIEWPORT.getName().equals(regionName)) {
|
||||
return "VIEWPORT";
|
||||
}
|
||||
System.err.println("[Info] Couldn't find a Region for " + regionName);
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 java.awt.*;
|
||||
|
||||
/**
|
||||
* ObjectCodeConvertors
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class ObjectCodeConvertors {
|
||||
static java.math.MathContext ctx = new java.math.MathContext(3);
|
||||
|
||||
/**
|
||||
* Given a value (x), encode it such that 0 -> 1 is to the left of a, 1 -> 2 is between a and b, and 2 -> 3
|
||||
* is to the right of b.
|
||||
*
|
||||
* @param w width in the case of the x axis, height in the case of the y axis.
|
||||
*/
|
||||
static float encode(float x, float a, float b, float w) {
|
||||
float r = 0;
|
||||
if (x < a) {
|
||||
r = (x / a);
|
||||
} else if (x > b) {
|
||||
r = 2 + ((x - b) / (w - b));
|
||||
} else if (x == a && x == b) {
|
||||
return 1.5f;
|
||||
} else {
|
||||
r = 1 + ((x - a) / (b - a));
|
||||
}
|
||||
|
||||
if (Float.isNaN(r)) {
|
||||
System.err.println("[Error] Encountered NaN: encode(" + x + ", " + a + ", " + b + ", " + w + ")");
|
||||
return 0;
|
||||
} else if (Float.isInfinite(r)) {
|
||||
System.err.println("[Error] Encountered Infinity: encode(" + x + ", " + a + ", " + b + ", " + w + ")");
|
||||
return 0;
|
||||
} else if (r < 0) {
|
||||
System.err.println("[Error] encoded value was less than 0: encode(" + x + ", " + a + ", " + b + ", " + w + ")");
|
||||
return 0;
|
||||
} else if (r > 3) {
|
||||
System.err.println("[Error] encoded value was greater than 3: encode(" + x + ", " + a + ", " + b + ", " + w + ")");
|
||||
return 3;
|
||||
} else {
|
||||
//for prettyness sake (and since we aren't really going to miss
|
||||
//any accuracy here) I'm rounding this to 3 decimal places
|
||||
// return java.math.BigDecimal.valueOf(r).round(ctx).doubleValue();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
static String convert(Paint paint) {
|
||||
//TODO need to support writing out other Paints, such as gradients
|
||||
if (paint instanceof Color) {
|
||||
return convert((Color) paint);
|
||||
} else {
|
||||
System.err.println("[WARNING] Unable to encode a paint in the encode(Paint) method: " + paint);
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Color, write out the java code required to create a new Color.
|
||||
*
|
||||
* @param color The color to convert
|
||||
* @return String of the code for the color
|
||||
*/
|
||||
static String convert(Color color) {
|
||||
return "new Color(" +
|
||||
color.getRed() + ", " +
|
||||
color.getGreen() + ", " +
|
||||
color.getBlue() + ", " +
|
||||
color.getAlpha() + ")";
|
||||
}
|
||||
|
||||
static String convert(Insets i) {
|
||||
return "new Insets(" + i.top + ", " + i.left + ", " + i.bottom + ", " + i.right + ")";
|
||||
}
|
||||
|
||||
static String convert(Dimension d) {
|
||||
return "new Dimension(" + d.width + ", " + d.height + ")";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,758 @@
|
||||
/*
|
||||
* 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.BezierControlPoint;
|
||||
import org.jdesktop.swingx.designer.Canvas;
|
||||
import org.jdesktop.swingx.designer.EllipseShape;
|
||||
import org.jdesktop.swingx.designer.Layer;
|
||||
import org.jdesktop.swingx.designer.PaintedShape;
|
||||
import org.jdesktop.swingx.designer.PathShape;
|
||||
import org.jdesktop.swingx.designer.RectangleShape;
|
||||
import org.jdesktop.swingx.designer.SimpleShape;
|
||||
import org.jdesktop.swingx.designer.TemplateLayer;
|
||||
import org.jdesktop.swingx.designer.paint.Gradient;
|
||||
import org.jdesktop.swingx.designer.paint.Matte;
|
||||
import org.jdesktop.swingx.designer.paint.PaintModel;
|
||||
import org.jdesktop.swingx.designer.paint.RadialGradient;
|
||||
import org.jdesktop.swingx.designer.paint.GradientStop;
|
||||
import org.jdesktop.swingx.designer.paint.AbstractGradient;
|
||||
import static org.jdesktop.synthdesigner.generator.GeneratorUtils.makePretty;
|
||||
import static org.jdesktop.synthdesigner.generator.GeneratorUtils.toClassName;
|
||||
import static org.jdesktop.synthdesigner.generator.GeneratorUtils.toConstantName;
|
||||
import static org.jdesktop.synthdesigner.generator.TemplateWriter.read;
|
||||
import static org.jdesktop.synthdesigner.generator.TemplateWriter.writeSrcFile;
|
||||
import org.jdesktop.synthdesigner.synthmodel.UIIconRegion;
|
||||
import org.jdesktop.synthdesigner.synthmodel.UIRegion;
|
||||
import org.jdesktop.synthdesigner.synthmodel.UIState;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.beans.Beans;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
/**
|
||||
* PainterGenerator - Class for generating Painter class java source from a Canvas
|
||||
*
|
||||
* Following in the general theory that is used to generate a Painter file.
|
||||
*
|
||||
* Each Painter file represents a Region. So there is one painter file per region. In
|
||||
* skin.laf we support Icon subregions, which are really just hacked versions of the
|
||||
* parent region.
|
||||
*
|
||||
* In order to generate the most compact and efficient bytecode possible for the
|
||||
* Painters, we actually perform the generation sequence in two steps. The first
|
||||
* step is the analysis phase, where we walk through the SynthModel for the region
|
||||
* and discover commonality among the different states in the region. For example,
|
||||
* do they have common paths? Do they have common colors? Gradients? Is the painting
|
||||
* code for the different states identical other than for colors?
|
||||
*
|
||||
* We gather this information up. On the second pass, we use this data to determine the
|
||||
* methods that need to be generated, and the class variables that need to be generated.
|
||||
* We try to keep the actual bytecode count as small as possible so that we may reduce
|
||||
* the overall size of the look and feel significantly.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class PainterGenerator {
|
||||
private static String painterImplTemplate;
|
||||
private static String getPainterImplTemplate() {
|
||||
if (painterImplTemplate == null) {
|
||||
//load the painter template file into an in-memory string to improve performance
|
||||
//when generating a lot of classes
|
||||
try {
|
||||
painterImplTemplate = read("resources/PainterImpl.template");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to read template files.");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return painterImplTemplate;
|
||||
}
|
||||
|
||||
|
||||
//a handful of counters, incremented whenever the associated object type is encounted.
|
||||
//These counters form the basis of the field and method suffixes.
|
||||
//These are all 1 based, because I felt like it :-)
|
||||
private int colorCounter = 1;
|
||||
private int gradientCounter = 1;
|
||||
private int radialCounter = 1;
|
||||
private int pathCounter = 1;
|
||||
private int rectCounter = 1;
|
||||
private int roundRectCounter = 1;
|
||||
private int ellipseCounter = 1;
|
||||
|
||||
private int stateTypeCounter = 1;
|
||||
|
||||
//during the first pass, we will construct these maps
|
||||
private Map<String, String> colors = new HashMap<String, String>();
|
||||
/**
|
||||
* Code=>method name.
|
||||
*/
|
||||
private Map<String, String> methods = new HashMap<String, String>();
|
||||
|
||||
//these variables hold the generated code
|
||||
/**
|
||||
* The source code in this variable will be used to define the various state types
|
||||
*/
|
||||
private StringBuilder stateTypeCode = new StringBuilder();
|
||||
/**
|
||||
* The source code in this variable will be used to define the switch statement for painting
|
||||
*/
|
||||
private StringBuilder switchCode = new StringBuilder();
|
||||
/**
|
||||
* The source code in this variable will be used to define the methods for painting each state
|
||||
*/
|
||||
private StringBuilder paintingCode = new StringBuilder();
|
||||
/**
|
||||
* The source code in this variable will be used to add getExtendedCacheKeys
|
||||
* implementation if needed.
|
||||
*/
|
||||
private StringBuilder getExtendedCacheKeysCode = new StringBuilder();
|
||||
/**
|
||||
* The source code in this variable will be used to define the methods for decoding gradients
|
||||
* and shapes.
|
||||
*/
|
||||
private StringBuilder gradientsCode = new StringBuilder();
|
||||
private StringBuilder colorCode = new StringBuilder();
|
||||
private StringBuilder shapesCode = new StringBuilder();
|
||||
/**
|
||||
* Map of component colors keyed by state constant name
|
||||
*/
|
||||
private Map<String, List<ComponentColor>> componentColorsMap =
|
||||
new LinkedHashMap<String, List<ComponentColor>>();
|
||||
/**
|
||||
* For the current state the list of all component colors used by this
|
||||
* painter, the index in this list is also the index in the runtime array
|
||||
* of defaults and keys.
|
||||
*/
|
||||
private List<ComponentColor> componentColors = null;
|
||||
|
||||
PainterGenerator(UIRegion r) {
|
||||
generate(r);
|
||||
}
|
||||
|
||||
private void generate(UIRegion r) {
|
||||
for (UIState state : r.getBackgroundStates()) {
|
||||
System.out.println("------>" + state.getName());
|
||||
|
||||
Canvas canvas = state.getCanvas();
|
||||
String type = r instanceof UIIconRegion ? ((UIIconRegion)r).getKey() : "Background";
|
||||
generate(state, canvas, type);
|
||||
}
|
||||
for (UIState state : r.getForegroundStates()) {
|
||||
Canvas canvas = state.getCanvas();
|
||||
generate(state, canvas, "Foreground");
|
||||
}
|
||||
for (UIState state : r.getBorderStates()) {
|
||||
Canvas canvas = state.getCanvas();
|
||||
generate(state, canvas, "Border");
|
||||
}
|
||||
//now check for any uiIconRegions, since these are collapsed together.
|
||||
for (UIRegion sub : r.getSubRegions()) {
|
||||
if (sub instanceof UIIconRegion) {
|
||||
generate(sub);
|
||||
}
|
||||
}
|
||||
//generate all the code for component colors
|
||||
if (!componentColorsMap.isEmpty()) {
|
||||
getExtendedCacheKeysCode
|
||||
.append(" protected Object[] getExtendedCacheKeys(JComponent c) {\n")
|
||||
.append(" Object[] extendedCacheKeys = null;\n")
|
||||
.append(" switch(state) {\n");
|
||||
for (Map.Entry<String, List<ComponentColor>> entry : componentColorsMap.entrySet()) {
|
||||
getExtendedCacheKeysCode
|
||||
.append(" case ")
|
||||
.append(entry.getKey()).append(":\n")
|
||||
.append(" extendedCacheKeys = new Object[] {\n");
|
||||
for (int i=0; i<entry.getValue().size(); i++) {
|
||||
ComponentColor cc = entry.getValue().get(i);
|
||||
getExtendedCacheKeysCode
|
||||
.append(" getComponentColor(c, \"")
|
||||
.append(cc.propertyName).append("\", ")
|
||||
.append(cc.defaultColorVariableName).append(", ")
|
||||
.append(cc.saturationOffset).append("f, ")
|
||||
.append(cc.brightnessOffset).append("f, ")
|
||||
.append(cc.alphaOffset);
|
||||
if (i + 1 < entry.getValue().size()) {
|
||||
getExtendedCacheKeysCode.append("),\n");
|
||||
} else {
|
||||
getExtendedCacheKeysCode.append(")");
|
||||
}
|
||||
}
|
||||
getExtendedCacheKeysCode.append("};\n")
|
||||
.append(" break;\n");
|
||||
}
|
||||
getExtendedCacheKeysCode
|
||||
.append(" }\n")
|
||||
.append(" return extendedCacheKeys;\n")
|
||||
.append(" }");
|
||||
}
|
||||
}
|
||||
|
||||
//type is background, foreground, border, upArrowIcon, etc.
|
||||
private void generate(UIState state, Canvas canvas, String type) {
|
||||
String states = UIState.keysToString(state.getStateKeys());
|
||||
String stateType = toConstantName(type + "_" + states);
|
||||
String paintMethodName = "paint" + type + toClassName(states);
|
||||
//create new array for component colors for this state
|
||||
componentColors = new ArrayList<ComponentColor>();
|
||||
|
||||
stateTypeCode.append(" static final int ").append(stateType).append(" = ").append(stateTypeCounter++).append(";\n");
|
||||
|
||||
if (canvas.isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switchCode.append(" case ").append(stateType).append(": ").append(paintMethodName).append("(g); break;\n");
|
||||
paintingCode.append(" private void ").append(paintMethodName).append("(Graphics2D g) {\n");
|
||||
|
||||
//start by setting up common info needed to encode the control points
|
||||
Insets in = canvas.getStretchingInsets();
|
||||
float a = in.left;
|
||||
float b = canvas.getSize().width - in.right;
|
||||
float c = in.top;
|
||||
float d = canvas.getSize().height - in.bottom;
|
||||
float width = canvas.getSize().width;
|
||||
float height = canvas.getSize().height;
|
||||
float cw = b - a;
|
||||
float ch = d - c;
|
||||
|
||||
Layer[] layers = canvas.getLayers().toArray(new Layer[0]);
|
||||
for (int index=layers.length-1; index >= 0; index--) {
|
||||
Layer layer = layers[index];
|
||||
if (layer instanceof TemplateLayer) {
|
||||
continue;
|
||||
}
|
||||
//shapes must be painted in reverse order
|
||||
List<SimpleShape> shapes = layer.getShapes();
|
||||
for (int i=shapes.size()-1; i>=0; i--) {
|
||||
SimpleShape s = shapes.get(i);
|
||||
if (s instanceof PaintedShape) {
|
||||
PaintedShape shape = (PaintedShape)s;
|
||||
PaintModel paint = shape.getPaintModel();
|
||||
|
||||
/*
|
||||
We attempt to write the minimal number of bytecodes as possible when
|
||||
generating code. Due to the inherit complexities in determining what
|
||||
is extraneous, we use the following system:
|
||||
|
||||
We first generate the code for the shape. Then, we check to see if
|
||||
this shape has already been generated. If so, then we defer to an
|
||||
existing method. If not, then we will create a new methods, stick
|
||||
the code in it, and refer to that method.
|
||||
*/
|
||||
|
||||
String shapeMethodName = null; // will contain the name of the method which creates the shape
|
||||
String shapeVariable = null; // will be one of rect, roundRect, ellipse, or path.
|
||||
String shapeMethodBody = null;
|
||||
|
||||
if (shape instanceof RectangleShape) {
|
||||
RectangleShape rshape = (RectangleShape) shape;
|
||||
float x1 = encode((float)rshape.getX1(), a, b, width);
|
||||
float y1 = encode((float)rshape.getY1(), c, d, height);
|
||||
float x2 = encode((float)rshape.getX2(), a, b, width);
|
||||
float y2 = encode((float)rshape.getY2(), c, d, height);
|
||||
if (rshape.isRounded()) {
|
||||
//it is a rounded rectangle
|
||||
float rounding = (float)rshape.getRounding();
|
||||
|
||||
shapeMethodBody =
|
||||
" roundRect.setRoundRect(" +
|
||||
writeDecodeX(x1) + ", //x\n" +
|
||||
" " + writeDecodeY(y1) + ", //y\n" +
|
||||
" " + writeDecodeX(x2) + " - " + writeDecodeX(x1) + ", //width\n" +
|
||||
" " + writeDecodeY(y2) + " - " + writeDecodeY(y1) + ", //height\n" +
|
||||
" " + rounding + "f, " + rounding + "f); //rounding";
|
||||
shapeVariable = "roundRect";
|
||||
} else {
|
||||
shapeMethodBody =
|
||||
" rect.setRect(" +
|
||||
writeDecodeX(x1) + ", //x\n" +
|
||||
" " + writeDecodeY(y1) + ", //y\n" +
|
||||
" " + writeDecodeX(x2) + " - " + writeDecodeX(x1) + ", //width\n" +
|
||||
" " + writeDecodeY(y2) + " - " + writeDecodeY(y1) + "); //height";
|
||||
shapeVariable = "rect";
|
||||
}
|
||||
} else if (shape instanceof EllipseShape) {
|
||||
EllipseShape eshape = (EllipseShape) shape;
|
||||
float x1 = encode((float)eshape.getX1(), a, b, width);
|
||||
float y1 = encode((float)eshape.getY1(), c, d, height);
|
||||
float x2 = encode((float)eshape.getX2(), a, b, width);
|
||||
float y2 = encode((float)eshape.getY2(), c, d, height);
|
||||
shapeMethodBody =
|
||||
" ellipse.setFrame(" +
|
||||
writeDecodeX(x1) + ", //x\n" +
|
||||
" " + writeDecodeY(y1) + ", //y\n" +
|
||||
" " + writeDecodeX(x2) + " - " + writeDecodeX(x1) + ", //width\n" +
|
||||
" " + writeDecodeY(y2) + " - " + writeDecodeY(y1) + "); //height";
|
||||
shapeVariable = "ellipse";
|
||||
} else if (shape instanceof PathShape) {
|
||||
PathShape pshape = (PathShape) shape;
|
||||
List<BezierControlPoint> controlPoints = pshape.getBezierControlPoints();
|
||||
BezierControlPoint first, last;
|
||||
first = last = controlPoints.get(0);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(" path.reset();\n");
|
||||
buffer.append(" path.moveTo(" + writeDecodeX(encode((float)first.getX(), a, b, width)) + ", " + writeDecodeY(encode((float)first.getY(), c, d, height)) + ");\n");
|
||||
for (int j=1; j<controlPoints.size(); j++) {
|
||||
BezierControlPoint cp = controlPoints.get(j);
|
||||
if (last.getCp2().isSharp() && cp.getCp1().isSharp()) {
|
||||
float x = encode((float)cp.getX(), a, b, width);
|
||||
float y = encode((float)cp.getY(), c, d, height);
|
||||
buffer.append(" path.lineTo(" + writeDecodeX(x) + ", " + writeDecodeY(y) + ");\n");
|
||||
} else {
|
||||
float x1 = encode((float)last.getX(), a, b, width);
|
||||
float y1 = encode((float)last.getY(), c, d, height);
|
||||
float x2 = encode((float)cp.getX(), a, b, width);
|
||||
float y2 = encode((float)cp.getY(), c, d, height);
|
||||
buffer.append(
|
||||
" path.curveTo(" + writeDecodeBezierX(x1, last.getX(), last.getCp2X()) + ", "
|
||||
+ writeDecodeBezierY(y1, last.getY(), last.getCp2Y()) + ", "
|
||||
+ writeDecodeBezierX(x2, cp.getX(), cp.getCp1X()) + ", "
|
||||
+ writeDecodeBezierY(y2, cp.getY(), cp.getCp1Y()) + ", "
|
||||
+ writeDecodeX(x2) + ", " + writeDecodeY(y2) + ");\n");
|
||||
}
|
||||
last = cp;
|
||||
}
|
||||
if (last.getCp2().isSharp() && first.getCp1().isSharp()) {
|
||||
float x = encode((float)first.getX(), a, b, width);
|
||||
float y = encode((float)first.getY(), c, d, height);
|
||||
buffer.append(" path.lineTo(" + writeDecodeX(x) + ", " + writeDecodeY(y) + ");\n");
|
||||
} else {
|
||||
float x1 = encode((float)last.getX(), a, b, width);
|
||||
float y1 = encode((float)last.getY(), c, d, height);
|
||||
float x2 = encode((float)first.getX(), a, b, width);
|
||||
float y2 = encode((float)first.getY(), c, d, height);
|
||||
buffer.append(
|
||||
" path.curveTo(" + writeDecodeBezierX(x1, last.getX(), last.getCp2X()) + ", "
|
||||
+ writeDecodeBezierY(y1, last.getY(), last.getCp2Y()) + ", "
|
||||
+ writeDecodeBezierX(x2, first.getX(), first.getCp1X()) + ", "
|
||||
+ writeDecodeBezierY(y2, first.getY(), first.getCp1Y()) + ", "
|
||||
+ writeDecodeX(x2) + ", " + writeDecodeY(y2) + ");\n");
|
||||
}
|
||||
buffer.append(" path.closePath();");
|
||||
shapeMethodBody = buffer.toString();
|
||||
shapeVariable = "path";
|
||||
} else {
|
||||
throw new RuntimeException("Cannot happen unless a new Shape has been defined");
|
||||
}
|
||||
|
||||
//now that we have the shape defined in shapeMethodBody, and a shapeVariable name,
|
||||
//look to see if such a body has been previously defined.
|
||||
shapeMethodName = methods.get(shapeMethodBody);
|
||||
String returnType = null;
|
||||
if (shapeMethodName == null) {
|
||||
if ("rect".equals(shapeVariable)) {
|
||||
shapeMethodName = "decodeRect" + rectCounter++;
|
||||
returnType = "Rectangle2D";
|
||||
} else if ("roundRect".equals(shapeVariable)) {
|
||||
shapeMethodName = "decodeRoundRect" + roundRectCounter++;
|
||||
returnType = "RoundRectangle2D";
|
||||
} else if ("ellipse".equals(shapeVariable)) {
|
||||
shapeMethodName = "decodeEllipse" + ellipseCounter++;
|
||||
returnType = "Ellipse2D";
|
||||
} else {
|
||||
shapeMethodName = "decodePath" + pathCounter++;
|
||||
returnType = "Path2D";
|
||||
}
|
||||
methods.put(shapeMethodBody, shapeMethodName);
|
||||
|
||||
//since the method wasn't previously defined, time to define it
|
||||
shapesCode.append(" private ").append(returnType).append(" ").append(shapeMethodName).append("() {\n");
|
||||
shapesCode.append(shapeMethodBody);
|
||||
shapesCode.append("\n");
|
||||
shapesCode.append(" return " + shapeVariable + ";\n");
|
||||
shapesCode.append(" }\n\n");
|
||||
}
|
||||
|
||||
//now that the method has been defined, I can go on and decode the
|
||||
//paint. After the paint is decoded, I can write the g.fill() method call,
|
||||
//using the result of the shapeMethodName. Yay!
|
||||
|
||||
// if (shapeVariable != null) {
|
||||
//first, calculate the bounds of the shape being painted and store in variables
|
||||
paintingCode.append(" ").append(shapeVariable).append(" = ").append(shapeMethodName).append("();\n");
|
||||
|
||||
if (paint instanceof Matte) {
|
||||
String colorVariable = encodeMatte((Matte)paint);
|
||||
paintingCode.append(" g.setPaint(").append(colorVariable).append(");\n");
|
||||
} else if (paint instanceof Gradient) {
|
||||
String gradientMethodName = encodeGradient(shape, (Gradient)paint);
|
||||
paintingCode.append(" g.setPaint(").append(gradientMethodName).append("(").append(shapeVariable).append("));\n");
|
||||
} else if (paint instanceof RadialGradient) {
|
||||
String radialMethodName = encodeRadial(shape, (RadialGradient)paint);
|
||||
paintingCode.append(" g.setPaint(").append(radialMethodName).append("(").append(shapeVariable).append("));\n");
|
||||
}
|
||||
paintingCode.append(" g.fill(").append(shapeVariable).append(");\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paintingCode.append("\n }\n\n");
|
||||
|
||||
//collect component colors
|
||||
if (!componentColors.isEmpty()) {
|
||||
componentColorsMap.put(stateType, componentColors);
|
||||
componentColors = null;
|
||||
}
|
||||
}
|
||||
|
||||
private float encode(float x, float a, float b, float width) {
|
||||
return ObjectCodeConvertors.encode(x, a, b, width);
|
||||
}
|
||||
|
||||
private String writeDecodeX(float encodedX) {
|
||||
return "decodeX(" + encodedX + "f)";
|
||||
}
|
||||
|
||||
private String writeDecodeY(float encodedY) {
|
||||
return "decodeY(" + encodedY + "f)";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ex encoded x value
|
||||
* @param x unencoded x value
|
||||
* @param cpx unencoded cpx value
|
||||
* @return
|
||||
*/
|
||||
private static String writeDecodeBezierX(double ex, double x, double cpx) {
|
||||
return "decodeAnchorX(" + ex + "f, " + (cpx - x) + "f)";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ey encoded y value
|
||||
* @param y unencoded y value
|
||||
* @param cpy unencoded cpy value
|
||||
* @return
|
||||
*/
|
||||
private static String writeDecodeBezierY(double ey, double y, double cpy) {
|
||||
return "decodeAnchorY(" + ey + "f, " + (cpy - y) + "f)";
|
||||
}
|
||||
|
||||
private String encodeMatte(Matte m) {
|
||||
String declaration = null;
|
||||
if (m.isAbsolute()) {
|
||||
Color c = m.getColor();
|
||||
declaration = ObjectCodeConvertors.convert(c);
|
||||
} else {
|
||||
declaration = "decodeColor(\"" + m.getUiDefaultParentName() +
|
||||
"\", " + m.getHueOffset() + "f, " +
|
||||
m.getSaturationOffset() + "f, " +
|
||||
m.getBrightnessOffset() + "f, " +
|
||||
m.getAlphaOffset() + ")";
|
||||
}
|
||||
|
||||
String variableName = colors.get(declaration);
|
||||
if (variableName == null) {
|
||||
variableName = "color" + colorCounter++;
|
||||
colors.put(declaration, variableName);
|
||||
colorCode.append(" private Color ").append(variableName).append(" = ");
|
||||
colorCode.append(declaration).append(";\n");
|
||||
}
|
||||
// handle component colors
|
||||
if (m.getComponentPropertyName() != null) {
|
||||
ComponentColor cc = new ComponentColor(m.getComponentPropertyName(),
|
||||
variableName, m.getSaturationOffset(),
|
||||
m.getBrightnessOffset(), m.getAlphaOffset());
|
||||
int index = componentColors.indexOf(cc);
|
||||
if (index == -1) {
|
||||
index = componentColors.size();
|
||||
componentColors.add(cc);
|
||||
}
|
||||
return "(Color)componentColors[" + index + "]";
|
||||
} else {
|
||||
return variableName;
|
||||
}
|
||||
}
|
||||
|
||||
private String encodeColor(Color c) {
|
||||
String declaration = ObjectCodeConvertors.convert(c);
|
||||
String variableName = colors.get(declaration);
|
||||
if (variableName == null) {
|
||||
variableName = "color" + colorCounter++;
|
||||
colors.put(declaration, variableName);
|
||||
colorCode.append(" private Color ").append(variableName).append(" = ");
|
||||
colorCode.append(declaration).append(";\n");
|
||||
}
|
||||
|
||||
return variableName;
|
||||
}
|
||||
|
||||
private String encodeGradient(PaintedShape ps, Gradient g) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
float x1 = (float)ps.getPaintX1();
|
||||
float y1 = (float)ps.getPaintY1();
|
||||
float x2 = (float)ps.getPaintX2();
|
||||
float y2 = (float)ps.getPaintY2();
|
||||
b.append(" return decodeGradient((");
|
||||
b.append(x1);
|
||||
b.append("f * w) + x, (");
|
||||
b.append(y1);
|
||||
b.append("f * h) + y, (");
|
||||
b.append(x2);
|
||||
b.append("f * w) + x, (");
|
||||
b.append(y2);
|
||||
b.append("f * h) + y,\n");
|
||||
encodeGradientColorsAndFractions(g,b);
|
||||
b.append(");");
|
||||
|
||||
String methodBody = b.toString();
|
||||
String methodName = methods.get(methodBody);
|
||||
if (methodName == null) {
|
||||
methodName = "decodeGradient" + gradientCounter++;
|
||||
gradientsCode.append(" private Paint ").append(methodName).append("(Shape s) {\n");
|
||||
gradientsCode.append(" Rectangle2D bounds = s.getBounds2D();\n");
|
||||
gradientsCode.append(" float x = (float)bounds.getX();\n");
|
||||
gradientsCode.append(" float y = (float)bounds.getY();\n");
|
||||
gradientsCode.append(" float w = (float)bounds.getWidth();\n");
|
||||
gradientsCode.append(" float h = (float)bounds.getHeight();\n");
|
||||
gradientsCode.append(methodBody);
|
||||
gradientsCode.append("\n }\n\n");
|
||||
methods.put(methodBody, methodName);
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a abstract gradient and creates the code for the fractions float
|
||||
* array and the colors array that can be used in the constructors of linear
|
||||
* and radial gradients.
|
||||
*
|
||||
* @param g The abstract gradient to get stops from
|
||||
* @param b Append code string of the form "new float[]{...},
|
||||
* new Color[]{...}" to this StringBuilder
|
||||
*/
|
||||
private void encodeGradientColorsAndFractions(AbstractGradient g,
|
||||
StringBuilder b) {
|
||||
List<GradientStop> stops = g.getStops();
|
||||
// there are stops.size() number of main stops. Between each is a
|
||||
// fractional stop. Thus, there are: stops.size() + stops.size() - 1
|
||||
// number of fractions and colors.
|
||||
float[] fractions = new float[stops.size() + stops.size() - 1];
|
||||
String[] colors = new String[fractions.length];
|
||||
//for each stop, create the stop and it's associated fraction
|
||||
int index = 0; // the index into fractions and colors
|
||||
for (int i = 0; i < stops.size(); i++) {
|
||||
GradientStop s = stops.get(i);
|
||||
//copy over the stop's data
|
||||
colors[index] = encodeMatte(s.getColor());
|
||||
fractions[index] = s.getPosition();
|
||||
|
||||
//If this isn't the last stop, then add in the fraction
|
||||
if (index < fractions.length - 1) {
|
||||
float f1 = s.getPosition();
|
||||
float f2 = stops.get(i + 1).getPosition();
|
||||
index++;
|
||||
fractions[index] = f1 + (f2 - f1) * s.getMidpoint();
|
||||
colors[index] = "decodeColor("+
|
||||
colors[index - 1]+","+
|
||||
encodeMatte(stops.get(i + 1).getColor())+",0.5f)";
|
||||
}
|
||||
index++;
|
||||
}
|
||||
// Check boundry conditions
|
||||
for (int i = 1; i < fractions.length; i++) {
|
||||
//to avoid an error with LinearGradientPaint where two fractions
|
||||
//are identical, bump up the fraction value by a miniscule amount
|
||||
//if it is identical to the previous one
|
||||
//NOTE: The <= is critical because the previous value may already
|
||||
//have been bumped up
|
||||
if (fractions[i] <= fractions[i - 1]) {
|
||||
fractions[i] = fractions[i - 1] + .000001f;
|
||||
}
|
||||
}
|
||||
//another boundary condition where multiple stops are all at the end. The
|
||||
//previous loop bumped all but one of these past 1.0, which is bad.
|
||||
//so remove any fractions (and their colors!) that are beyond 1.0
|
||||
int outOfBoundsIndex = -1;
|
||||
for (int i = 0; i < fractions.length; i++) {
|
||||
if (fractions[i] > 1) {
|
||||
outOfBoundsIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outOfBoundsIndex >= 0) {
|
||||
float[] f = fractions;
|
||||
String[] c = colors;
|
||||
fractions = new float[outOfBoundsIndex];
|
||||
colors = new String[outOfBoundsIndex];
|
||||
System.arraycopy(f, 0, fractions, 0, outOfBoundsIndex);
|
||||
System.arraycopy(c, 0, colors, 0, outOfBoundsIndex);
|
||||
}
|
||||
// build string
|
||||
b.append(" new float[] { ");
|
||||
for (int i = 0; i < fractions.length; i++) {
|
||||
if (i>0)b.append(',');
|
||||
b.append(fractions[i]);
|
||||
b.append('f');
|
||||
}
|
||||
b.append(" },\n new Color[] { ");
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
if (i>0) b.append(",\n ");
|
||||
b.append(colors[i]);
|
||||
}
|
||||
b.append("}");
|
||||
}
|
||||
|
||||
private String encodeRadial(PaintedShape ps, RadialGradient g) {
|
||||
float centerX1 = (float)ps.getPaintX1();
|
||||
float centerY1 = (float)ps.getPaintY1();
|
||||
float x2 = (float)ps.getPaintX2();
|
||||
float y2 = (float)ps.getPaintY2();
|
||||
float radius = (float)Point2D.distance(centerX1, centerY1, x2, y2);
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
b.append(" return decodeRadialGradient((");
|
||||
b.append(centerX1);
|
||||
b.append("f * w) + x, (");
|
||||
b.append(centerY1);
|
||||
b.append("f * h) + y, ");
|
||||
b.append(radius);
|
||||
b.append("f,\n");
|
||||
encodeGradientColorsAndFractions(g,b);
|
||||
b.append(");");
|
||||
|
||||
String methodBody = b.toString();
|
||||
String methodName = methods.get(methodBody);
|
||||
if (methodName == null) {
|
||||
methodName = "decodeRadial" + radialCounter++;
|
||||
gradientsCode.append(" private Paint ").append(methodName).append("(Shape s) {\n");
|
||||
gradientsCode.append(" Rectangle2D bounds = s.getBounds2D();\n");
|
||||
gradientsCode.append(" float x = (float)bounds.getX();\n");
|
||||
gradientsCode.append(" float y = (float)bounds.getY();\n");
|
||||
gradientsCode.append(" float w = (float)bounds.getWidth();\n");
|
||||
gradientsCode.append(" float h = (float)bounds.getHeight();\n");
|
||||
gradientsCode.append(methodBody);
|
||||
gradientsCode.append("\n }\n\n");
|
||||
methods.put(methodBody, methodName);
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
|
||||
//note that this method is not thread-safe. In fact, none of this class is.
|
||||
static void writePainter(UIRegion r, Map<String, String> variables, File painterPackageRoot, String prefix) throws IOException {
|
||||
//Need only write out the stuff for this region, don't need to worry about subregions
|
||||
//since this method will be called for each of those (and they go in their own file, anyway).
|
||||
//The only subregion that we compound into this is the one for icons.
|
||||
|
||||
String painterName = makePretty(prefix) + "Painter";
|
||||
PainterGenerator gen = new PainterGenerator(r);
|
||||
System.out.println("Generating source file: " + painterName + ".java");
|
||||
System.out.println(gen.stateTypeCode.toString());
|
||||
variables.put("PAINTER_NAME", painterName);
|
||||
variables.put("STATIC_DECL", gen.stateTypeCode.toString());
|
||||
variables.put("COLORS_DECL", gen.colorCode.toString());
|
||||
variables.put("DO_PAINT_SWITCH_BODY", gen.switchCode.toString());
|
||||
variables.put("PAINTING_DECL", gen.paintingCode.toString());
|
||||
variables.put("GET_EXTENDED_CACHE_KEYS", gen.getExtendedCacheKeysCode.toString());
|
||||
variables.put("SHAPES_DECL", gen.shapesCode.toString());
|
||||
variables.put("GRADIENTS_DECL", gen.gradientsCode.toString());
|
||||
|
||||
writeSrcFile(getPainterImplTemplate(), variables, new File(painterPackageRoot, painterName + ".java"));
|
||||
|
||||
variables.remove("PAINTER_NAME");
|
||||
variables.remove("STATIC_DECL");
|
||||
variables.remove("COLORS_DECL");
|
||||
variables.remove("DO_PAINT_SWITCH_BODY");
|
||||
variables.remove("PAINTING_DECL");
|
||||
variables.remove("SHAPES_DECL");
|
||||
variables.remove("GRADIENTS_DECL");
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the usage of a color from a component within a painter. That
|
||||
* is, a painter can use colors from the component when it paints. This
|
||||
* class represents the usage of such a color, containing a reference to
|
||||
* the name of the property that contains the color, and the various
|
||||
* derivation offsets to apply to that color.
|
||||
*/
|
||||
private static class ComponentColor {
|
||||
public String propertyName;
|
||||
public String defaultColorVariableName;
|
||||
private float saturationOffset = 0, brightnessOffset = 0;
|
||||
private int alphaOffset = 0;
|
||||
|
||||
private ComponentColor(String propertyName,
|
||||
String defaultColorVariableName,
|
||||
float saturationOffset,
|
||||
float brightnessOffset,
|
||||
int alphaOffset) {
|
||||
this.propertyName = propertyName;
|
||||
this.defaultColorVariableName = defaultColorVariableName;
|
||||
this.saturationOffset = saturationOffset;
|
||||
this.brightnessOffset = brightnessOffset;
|
||||
this.alphaOffset = alphaOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ComponentColor c = (ComponentColor)o;
|
||||
if (alphaOffset != c.alphaOffset) return false;
|
||||
if (Float.compare(saturationOffset, c.saturationOffset) != 0)
|
||||
return false;
|
||||
if (Float.compare(brightnessOffset, c.brightnessOffset) != 0)
|
||||
return false;
|
||||
if (defaultColorVariableName != null ?
|
||||
!defaultColorVariableName.equals(c.defaultColorVariableName) :
|
||||
c.defaultColorVariableName != null) return false;
|
||||
if (propertyName != null ? !propertyName.equals(c.propertyName) :
|
||||
c.propertyName != null) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 61 * hash + (this.propertyName != null ?
|
||||
this.propertyName.hashCode() : 0);
|
||||
hash = 61 * hash + (this.defaultColorVariableName != null ?
|
||||
this.defaultColorVariableName.hashCode() : 0);
|
||||
hash = 61 * hash + Float.floatToIntBits(this.saturationOffset);
|
||||
hash = 61 * hash + Float.floatToIntBits(this.brightnessOffset);
|
||||
hash = 61 * hash + this.alphaOffset;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TemplateWriter - Class for writing Java Source files using a src template and variable subsitution
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class TemplateWriter {
|
||||
|
||||
/**
|
||||
* Write a Java source file by taking a template file and applying variable substitution and writing to the output
|
||||
* file.
|
||||
*
|
||||
* @param template The template to use
|
||||
* @param variables Map of the variable names and values to substitute in the template
|
||||
* @param output The file to write to
|
||||
* @throws IOException If there was a problem writing the Java source file
|
||||
*/
|
||||
static void writeSrcFile(String template, Map<String, String> variables, File output) throws IOException {
|
||||
TemplateReader in = new TemplateReader(variables, template);
|
||||
PrintWriter out =
|
||||
new PrintWriter(new FileWriter(output));
|
||||
|
||||
String line = in.readLine();
|
||||
while (line != null) {
|
||||
out.println(line);
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a template file into a string
|
||||
*
|
||||
* @param name The template file path relative to Generator class
|
||||
* @return The contents of the template file as string
|
||||
* @throws IOException If there was a problem reading the template file
|
||||
*/
|
||||
static String read(String name) throws IOException {
|
||||
InputStream in = Generator.class.getResourceAsStream(name);
|
||||
if (in==null) throw new IOException("Could not find template ["+name+
|
||||
"] relative to class ["+Generator.class.getName()+"]");
|
||||
byte[] data = new byte[4096];
|
||||
int length = -1;
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
while ((length = in.read(data)) != -1) {
|
||||
buffer.append(new String(data, 0, length));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/** A BufferedReader implementation that automatically performs string replacements as needed. */
|
||||
private static final class TemplateReader extends BufferedReader {
|
||||
private Map<String, String> variables;
|
||||
|
||||
TemplateReader(Map<String, String> variables, String template) {
|
||||
super(new StringReader(template));
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a line of text from the template but with variables substituted. Other methods will return the text
|
||||
* sans substitution. Call this method.
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public String readLine() throws IOException {
|
||||
return substituteVariables(super.readLine());
|
||||
}
|
||||
|
||||
private String substituteVariables(String input) {
|
||||
if (input == null) return null;
|
||||
for (Map.Entry<String, String> variable : variables.entrySet()) {
|
||||
input = input.replace("${" + variable.getKey() + "}", variable.getValue());
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.synthmodel;
|
||||
|
||||
/**
|
||||
* CustomUIDefault
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class CustomUIDefault<T> extends UIDefault<T> {
|
||||
private static int counter = -1;
|
||||
|
||||
public CustomUIDefault() {
|
||||
super("Unnamed" + (++counter == 0 ? "" : counter), null);
|
||||
}
|
||||
|
||||
public void setName(String id) {
|
||||
super.setName(id);
|
||||
}
|
||||
}
|
@ -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.synthdesigner.synthmodel;
|
||||
|
||||
/**
|
||||
* HasUIStyle - A marker interface for all classes that have a UIStyle
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public interface HasUIStyle {
|
||||
|
||||
public UIStyle getStyle();
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.synthmodel;
|
||||
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
/**
|
||||
* Represents a border that refers to a Painter to do it's work. This border
|
||||
* doesn't actually render -- it is just used as part of the model.
|
||||
*
|
||||
* @author Richard Bair
|
||||
*/
|
||||
public class PainterBorder extends EmptyBorder {
|
||||
private String painterName;
|
||||
public PainterBorder(String painterName, int top, int left, int bottom, int right) {
|
||||
super(top, left, bottom, right);
|
||||
this.painterName = painterName;
|
||||
}
|
||||
|
||||
public String getPainterName() { return painterName; }
|
||||
}
|
@ -0,0 +1,530 @@
|
||||
/*
|
||||
* 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.synthmodel;
|
||||
|
||||
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.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDesktopPane;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JRadioButtonMenuItem;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import static javax.swing.plaf.synth.SynthConstants.*;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import java.awt.Insets;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Models a Synth look and feel. Contains all of the colors, fonts, painters, states, etc that compose a synth look and
|
||||
* feel.
|
||||
* <p/>
|
||||
* To model Synth properly, I need to both Model the way Synth works (with styles, and so forth) and the way a look and
|
||||
* feel works (UIDefaults table, etc) since both of these are supported ways of doing things in Synth.
|
||||
* <p/>
|
||||
* One important (but non-visual) thing that needs to be configurable is the support for InputMaps per component. In
|
||||
* Synth, an input map can be associated with the main Synth element, meaning it applies to everything. Or it can be
|
||||
* associated with a single style. An Inputmap can have an id, and it can contain multiple key/action pairs (where
|
||||
* actions are denoted by name).
|
||||
* <p/>
|
||||
* It looks like Regions can have InputMaps? Sounds fishy to me. I think only Components really have input maps.
|
||||
* <p/>
|
||||
* I would like some way of denoting special keys between mac and other platforms. For example, cut, copy, paste etc
|
||||
* should be different. In general, the ctrl key and apple (meta) key are reversed from what is typically on windows.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class SynthModel extends AbstractBean implements HasUIDefaults, HasUIStyle, HasResources {
|
||||
//I'm going to want:
|
||||
//entries related to the Control color, and other colors of the Basic LAF
|
||||
//entries related to fonts (standard fonts) used in the Basic LAF
|
||||
//entries related to standard insets, borders, dimensions, icons
|
||||
//entries related to component specific entries in the LAF
|
||||
private List<UIPaint> colors;
|
||||
private List<UIFont> fonts;
|
||||
private List<UIInsets> insets;
|
||||
private List<UIBorder> borders;
|
||||
private List<UIDimension> dimensions;
|
||||
private List<UIIcon> icons;
|
||||
private List<UIComponent> components;
|
||||
/**
|
||||
* This is a local UIDefaults that contains all the UIDefaults in this synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*/
|
||||
private transient UIDefaults modelDefaults = new UIDefaults();
|
||||
private transient UIStyle globalStyle = new UIStyle();
|
||||
|
||||
private transient File resourcesDir;
|
||||
private transient File imagesDir;
|
||||
private transient File templatesDir;
|
||||
|
||||
/** Default constructor used by JIBX to create new empty SynthModel */
|
||||
protected SynthModel() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public SynthModel(boolean populateWithDefaults) {
|
||||
// create observable lists that fire changes on as property changes
|
||||
colors = new ArrayList<UIPaint>();
|
||||
fonts = new ArrayList<UIFont>();
|
||||
insets = new ArrayList<UIInsets>();
|
||||
borders = new ArrayList<UIBorder>();
|
||||
dimensions = new ArrayList<UIDimension>();
|
||||
icons = new ArrayList<UIIcon>();
|
||||
components = new ArrayList<UIComponent>();
|
||||
|
||||
if (populateWithDefaults) {
|
||||
//get the ui defaults from the SynthLookAndFeel. Using the UIDefaults table,
|
||||
//pre initialize everything.
|
||||
// SynthLookAndFeel synth = new SynthLookAndFeel();
|
||||
BasicLookAndFeel synth = new MetalLookAndFeel();
|
||||
UIDefaults defaults = synth.getDefaults();
|
||||
|
||||
//pre-init the palettes
|
||||
colors.add(new UIColor("desktop", defaults.getColor("desktop"), modelDefaults));
|
||||
colors.add(new UIColor("activeCaption", defaults.getColor("activeCaption"), modelDefaults));
|
||||
colors.add(new UIColor("activeCaptionText", defaults.getColor("activeCaptionText"), modelDefaults));
|
||||
colors.add(new UIColor("activeCaptionBorder", defaults.getColor("activeCaptionBorder"), modelDefaults));
|
||||
colors.add(new UIColor("inactiveCaption", defaults.getColor("inactiveCaption"), modelDefaults));
|
||||
colors.add(new UIColor("inactiveCaptionText", defaults.getColor("inactiveCaptionText"), modelDefaults));
|
||||
colors.add(new UIColor("inactiveCaptionBorder", defaults.getColor("inactiveCaptionBorder"), modelDefaults));
|
||||
colors.add(new UIColor("window", defaults.getColor("window"), modelDefaults));
|
||||
colors.add(new UIColor("windowBorder", defaults.getColor("windowBorder"), modelDefaults));
|
||||
colors.add(new UIColor("windowText", defaults.getColor("windowText"), modelDefaults));
|
||||
colors.add(new UIColor("menu", defaults.getColor("menu"), modelDefaults));
|
||||
colors.add(new UIColor("menuText", defaults.getColor("menuText"), modelDefaults));
|
||||
colors.add(new UIColor("text", defaults.getColor("text"), modelDefaults));
|
||||
colors.add(new UIColor("textText", defaults.getColor("textText"), modelDefaults));
|
||||
colors.add(new UIColor("textHighlight", defaults.getColor("textHighlight"), modelDefaults));
|
||||
colors.add(new UIColor("textHighlightText", defaults.getColor("textHighlightText"), modelDefaults));
|
||||
colors.add(new UIColor("textInactiveText", defaults.getColor("textInactiveText"), modelDefaults));
|
||||
colors.add(new UIColor("control", defaults.getColor("control"), modelDefaults));
|
||||
colors.add(new UIColor("controlText", defaults.getColor("controlText"), modelDefaults));
|
||||
colors.add(new UIColor("controlHighlight", defaults.getColor("controlHighlight"), modelDefaults));
|
||||
colors.add(new UIColor("controlLHighlight", defaults.getColor("controlLHighlight"), modelDefaults));
|
||||
colors.add(new UIColor("controlShadow", defaults.getColor("controlShadow"), modelDefaults));
|
||||
colors.add(new UIColor("controlDkShadow", defaults.getColor("controlDkShadow"), modelDefaults));
|
||||
colors.add(new UIColor("scrollbar", defaults.getColor("scrollbar"), modelDefaults));
|
||||
colors.add(new UIColor("info", defaults.getColor("info"), modelDefaults));
|
||||
colors.add(new UIColor("infoText", defaults.getColor("infoText"), modelDefaults));
|
||||
|
||||
fonts.add(new UIFont("dialogPlain", defaults.getFont("Button.font"), modelDefaults));
|
||||
fonts.add(new UIFont("serifPlain", defaults.getFont("TextPane.font"), modelDefaults));
|
||||
fonts.add(new UIFont("sansSerifPlain", defaults.getFont("ToolTip.font"), modelDefaults));
|
||||
fonts.add(new UIFont("monospacedPlain", defaults.getFont("TextArea.font"), modelDefaults));
|
||||
fonts.add(new UIFont("dialogBold", defaults.getFont("InternalFrame.titleFont"), modelDefaults));
|
||||
|
||||
insets.add(new UIInsets("zeroInsets", new Insets(0, 0, 0, 0)));
|
||||
insets.add(new UIInsets("twoInsets", new Insets(2, 2, 2, 2)));
|
||||
insets.add(new UIInsets("threeInsets", new Insets(3, 3, 3, 3)));
|
||||
|
||||
borders.add(new UIBorder("marginBorder", defaults.getBorder("MenuItem.border")));
|
||||
borders.add(new UIBorder("etchedBorder", defaults.getBorder("TitledBorder.border")));
|
||||
borders.add(new UIBorder("loweredBevelBorder", defaults.getBorder("Table.scrollPaneBorder")));
|
||||
borders.add(new UIBorder("blackLineBorder", defaults.getBorder("ToolTip.border")));
|
||||
|
||||
//TODO have to deal with the special arrow button region
|
||||
|
||||
//pre-init the list of UI components
|
||||
UIComponent button = new UIComponent("Button", JButton.class.getName(), "ButtonUI");
|
||||
addStates(this, button, DEFAULT, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(button);
|
||||
|
||||
UIComponent toggleButton =
|
||||
new UIComponent("ToggleButton", JToggleButton.class.getName(), "ToggleButtonUI");
|
||||
addStates(this, toggleButton, DEFAULT, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED, SELECTED,
|
||||
SELECTED | PRESSED, SELECTED | MOUSE_OVER, DISABLED | SELECTED);
|
||||
components.add(toggleButton);
|
||||
|
||||
UIComponent radioButton =
|
||||
new UIComponent("RadioButton", JRadioButton.class.getName(), "RadioButtonUI");
|
||||
addStates(this, radioButton, DEFAULT, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED, SELECTED,
|
||||
SELECTED | PRESSED, SELECTED | MOUSE_OVER, DISABLED | SELECTED);
|
||||
components.add(radioButton);
|
||||
|
||||
UIComponent checkBox =
|
||||
new UIComponent("CheckBox", JCheckBox.class.getName(), "CheckBoxUI");
|
||||
addStates(this, checkBox, DEFAULT, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED, SELECTED,
|
||||
SELECTED | PRESSED, SELECTED | MOUSE_OVER, DISABLED | SELECTED);
|
||||
components.add(checkBox);
|
||||
|
||||
UIComponent colorChooser =
|
||||
new UIComponent("ColorChooser", JColorChooser.class.getName(), "ColorChooserUI");
|
||||
addStates(this, colorChooser, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(colorChooser);
|
||||
|
||||
UIComponent comboBox =
|
||||
new UIComponent("ComboBox", JComboBox.class.getName(), "ComboBoxUI");
|
||||
addStates(this, comboBox, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(comboBox);
|
||||
|
||||
UIComponent fileChooser =
|
||||
new UIComponent("FileChooser", JFileChooser.class.getName(), "FileChooserUI");
|
||||
addStates(this, fileChooser, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(fileChooser);
|
||||
|
||||
//not represented in Synth
|
||||
// UIComponent fileView = new UIComponent ("FileView",
|
||||
// list(DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
|
||||
UIComponent internalFrame =
|
||||
new UIComponent("InternalFrame", JInternalFrame.class.getName(), "InternalFrameUI");
|
||||
addStates(this, internalFrame, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has an internal frame title pane region
|
||||
components.add(internalFrame);
|
||||
|
||||
//TODO DesktopIcon ???
|
||||
|
||||
UIComponent desktop =
|
||||
new UIComponent("Desktop", JDesktopPane.class.getName(), "DesktopPaneUI");
|
||||
addStates(this, desktop, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(desktop);
|
||||
|
||||
UIComponent label = new UIComponent("Label", JLabel.class.getName(), "LabelUI");
|
||||
addStates(this, label, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(label);
|
||||
|
||||
UIComponent list = new UIComponent("List", JList.class.getName(), "ListUI");
|
||||
addStates(this, list, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(list);
|
||||
|
||||
UIComponent menuBar = new UIComponent("MenuBar", JMenuBar.class.getName(), "MenuBarUI");
|
||||
addStates(this, menuBar, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(menuBar);
|
||||
|
||||
UIComponent menuItem =
|
||||
new UIComponent("MenuItem", JMenuItem.class.getName(), "MenuItemUI");
|
||||
addStates(this, menuItem, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has a menuItemAccelerator region
|
||||
components.add(menuItem);
|
||||
|
||||
UIComponent radioButtonMenuItem =
|
||||
new UIComponent("RadioButtonMenuItem", JRadioButtonMenuItem.class.getName(),
|
||||
"RadioButtonMenuItemUI");
|
||||
addStates(this, radioButtonMenuItem, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(radioButtonMenuItem);
|
||||
|
||||
UIComponent checkBoxMenuItem =
|
||||
new UIComponent("CheckBoxMenuItem", JCheckBoxMenuItem.class.getName(),
|
||||
"CheckBoxMenuItemUI");
|
||||
addStates(this, checkBoxMenuItem, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(checkBoxMenuItem);
|
||||
|
||||
UIComponent menu = new UIComponent("Menu", JMenu.class.getName(), "MenuUI");
|
||||
addStates(this, menu, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(menu);
|
||||
|
||||
UIComponent popupMenu =
|
||||
new UIComponent("PopupMenu", JPopupMenu.class.getName(), "PopupMenuUI");
|
||||
addStates(this, popupMenu, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has a popupMenuSeparator region
|
||||
components.add(popupMenu);
|
||||
|
||||
UIComponent optionPane =
|
||||
new UIComponent("OptionPane", JOptionPane.class.getName(), "OptionPaneUI");
|
||||
addStates(this, optionPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(optionPane);
|
||||
|
||||
UIComponent panel = new UIComponent("Panel", JPanel.class.getName(), "PanelUI");
|
||||
addStates(this, panel, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(panel);
|
||||
|
||||
UIComponent progressBar =
|
||||
new UIComponent("ProgressBar", JProgressBar.class.getName(), "ProgressBarUI");
|
||||
addStates(this, progressBar, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(progressBar);
|
||||
|
||||
UIComponent separator =
|
||||
new UIComponent("Separator", JSeparator.class.getName(), "SeparatorUI");
|
||||
addStates(this, separator, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(separator);
|
||||
|
||||
UIRegion scrollBarThumb = new UIRegion("ScrollBar.Thumb");
|
||||
addStates(this, scrollBarThumb, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
UIRegion scrollBarTrack = new UIRegion("ScrollBar.Track");
|
||||
addStates(this, scrollBarTrack, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
UIComponent scrollBar =
|
||||
new UIComponent("ScrollBar", JScrollBar.class.getName(), "ScrollBarUI", scrollBarThumb,
|
||||
scrollBarTrack);
|
||||
addStates(this, scrollBar, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(scrollBar);
|
||||
|
||||
UIComponent scrollPane =
|
||||
new UIComponent("ScrollPane", JScrollPane.class.getName(), "ScrollPaneUI");
|
||||
addStates(this, scrollPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(scrollPane);
|
||||
|
||||
UIComponent viewport =
|
||||
new UIComponent("Viewport", JViewport.class.getName(), "ViewportUI");
|
||||
addStates(this, viewport, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(viewport);
|
||||
|
||||
UIComponent slider = new UIComponent("Slider", JSlider.class.getName(), "SliderUI");
|
||||
addStates(this, slider, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has sliderThumb and sliderTrack sub regions
|
||||
components.add(slider);
|
||||
|
||||
UIComponent spinner = new UIComponent("Spinner", JSpinner.class.getName(), "SpinnerUI");
|
||||
addStates(this, spinner, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(spinner);
|
||||
|
||||
UIComponent splitPane =
|
||||
new UIComponent("SplitPane", JSplitPane.class.getName(), "SplitPaneUI");
|
||||
addStates(this, splitPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has splitPaneDivider sub region
|
||||
components.add(splitPane);
|
||||
|
||||
UIComponent tabbedPane =
|
||||
new UIComponent("TabbedPane", JTabbedPane.class.getName(), "TabbedPaneUI");
|
||||
addStates(this, tabbedPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//has tabbedPaneContent and tabbedPaneTab and TabbedPaneTabArea sub regions
|
||||
components.add(tabbedPane);
|
||||
|
||||
UIComponent table = new UIComponent("Table", JTable.class.getName(), "TableUI");
|
||||
addStates(this, table, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(table);
|
||||
|
||||
UIComponent tableHeader =
|
||||
new UIComponent("TableHeader", JTableHeader.class.getName(), "TableHeaderUI");
|
||||
addStates(this, tableHeader, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(tableHeader);
|
||||
|
||||
UIComponent textField =
|
||||
new UIComponent("TextField", JTextField.class.getName(), "TextFieldUI");
|
||||
addStates(this, textField, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(textField);
|
||||
|
||||
UIComponent formattedTextField =
|
||||
new UIComponent("FormattedTextField", JFormattedTextField.class.getName(),
|
||||
"FormattedTextFieldUI");
|
||||
addStates(this, formattedTextField, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(formattedTextField);
|
||||
|
||||
UIComponent passwordField =
|
||||
new UIComponent("PasswordField", JPasswordField.class.getName(), "PasswordFieldUI");
|
||||
addStates(this, passwordField, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(passwordField);
|
||||
|
||||
UIComponent textArea =
|
||||
new UIComponent("TextArea", JTextArea.class.getName(), "TextAreaUI");
|
||||
addStates(this, textArea, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(textArea);
|
||||
|
||||
UIComponent textPane =
|
||||
new UIComponent("TextPane", JTextPane.class.getName(), "TextPaneUI");
|
||||
addStates(this, textPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(textPane);
|
||||
|
||||
UIComponent editorPane =
|
||||
new UIComponent("EditorPane", JEditorPane.class.getName(), "EditorPaneUI");
|
||||
addStates(this, editorPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(editorPane);
|
||||
|
||||
/*
|
||||
* The only thing not represented in Synth as a region. I suppose we'll have
|
||||
* to make it a CustomUIComponent
|
||||
*/
|
||||
// UIComponent titledBorder = new UIComponent ("TitledBorder",
|
||||
// list(DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
|
||||
UIComponent toolBar = new UIComponent("ToolBar", JToolBar.class.getName(), "ToolBarUI");
|
||||
addStates(this, toolBar, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//toolBarContent, toolBarDragWindow, toolBarSeparator sub regions
|
||||
components.add(toolBar);
|
||||
|
||||
UIComponent toolTip = new UIComponent("ToolTip", JToolTip.class.getName(), "ToolTipUI");
|
||||
addStates(this, toolTip, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(toolTip);
|
||||
|
||||
//tooltip manager
|
||||
|
||||
UIComponent tree = new UIComponent("Tree", JTree.class.getName(), "TreeUI");
|
||||
addStates(this, tree, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
//treeCell sub region
|
||||
components.add(tree);
|
||||
|
||||
UIComponent rootPane =
|
||||
new UIComponent("RootPane", JRootPane.class.getName(), "RootPaneUI");
|
||||
addStates(this, rootPane, DISABLED, ENABLED, FOCUSED, MOUSE_OVER, PRESSED);
|
||||
components.add(rootPane);
|
||||
}
|
||||
}
|
||||
|
||||
public List<UIPaint> getColorPalette() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
public List<UIFont> getFontPalette() {
|
||||
return fonts;
|
||||
}
|
||||
|
||||
public List<UIInsets> getInsetPalette() {
|
||||
return insets;
|
||||
}
|
||||
|
||||
public List<UIBorder> getBorderPalette() {
|
||||
return borders;
|
||||
}
|
||||
|
||||
public List<UIDimension> getDimensionPalette() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
public List<UIIcon> getIconPalette() {
|
||||
return icons;
|
||||
}
|
||||
|
||||
public List<UIComponent> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local UIDefaults that contains all the UIDefaults in this synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*
|
||||
* @return The UIDefaults for the synth model
|
||||
*/
|
||||
public UIDefaults getUiDefaults() {
|
||||
return modelDefaults;
|
||||
}
|
||||
|
||||
public UIStyle getStyle() {
|
||||
return globalStyle;
|
||||
}
|
||||
|
||||
// by default there are no painters assigned to the various states
|
||||
private static void addStates(SynthModel model, UIRegion parentRegion, int... states) {
|
||||
for (int state : states) {
|
||||
List<String> stateList = new ArrayList<String>();
|
||||
if ((state & ENABLED) != 0) {
|
||||
stateList.add(UIStateType.ENABLED_KEY);
|
||||
}
|
||||
if ((state & MOUSE_OVER) != 0) {
|
||||
stateList.add(UIStateType.MOUSE_OVER_KEY);
|
||||
}
|
||||
if ((state & PRESSED) != 0) {
|
||||
stateList.add(UIStateType.PRESSED_KEY);
|
||||
}
|
||||
if ((state & DISABLED) != 0) {
|
||||
stateList.add(UIStateType.DISABLED_KEY);
|
||||
}
|
||||
if ((state & FOCUSED) != 0) {
|
||||
stateList.add(UIStateType.FOCUSED_KEY);
|
||||
}
|
||||
if ((state & SELECTED) != 0) {
|
||||
stateList.add(UIStateType.SELECTED_KEY);
|
||||
}
|
||||
if ((state & DEFAULT) != 0) {
|
||||
stateList.add(UIStateType.DEFAULT_KEY);
|
||||
}
|
||||
parentRegion.addBackgroundState(new UIState(model, parentRegion, stateList.toArray(new String[stateList.size()])));
|
||||
}
|
||||
}
|
||||
|
||||
public File getResourcesDir() {
|
||||
return resourcesDir;
|
||||
}
|
||||
|
||||
public void setResourcesDir(File resourcesDir) {
|
||||
System.out.println("SynthModel.setResourcesDir(" + resourcesDir + ")");
|
||||
File old = getResourcesDir();
|
||||
this.resourcesDir = resourcesDir;
|
||||
firePropertyChange("resourcesDir", old, getResourcesDir());
|
||||
}
|
||||
|
||||
public File getImagesDir() {
|
||||
return imagesDir;
|
||||
}
|
||||
|
||||
public void setImagesDir(File imagesDir) {
|
||||
System.out.println("SynthModel.setImagesDir(" + imagesDir + ")");
|
||||
File old = getImagesDir();
|
||||
this.imagesDir = imagesDir;
|
||||
firePropertyChange("imagesDir", old, getImagesDir());
|
||||
}
|
||||
|
||||
public File getTemplatesDir() {
|
||||
return templatesDir;
|
||||
}
|
||||
|
||||
public void setTemplatesDir(File templatesDir) {
|
||||
System.out.println("SynthModel.setTemplatesDir(" + templatesDir + ")");
|
||||
File old = getTemplatesDir();
|
||||
this.templatesDir = templatesDir;
|
||||
firePropertyChange("templatesDir", old, getTemplatesDir());
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
public void preSet(IUnmarshallingContext context) {
|
||||
File resourcesDir = (File) context.getUserContext();
|
||||
this.resourcesDir = resourcesDir;
|
||||
this.imagesDir = new File(resourcesDir, "images");
|
||||
this.templatesDir = new File(resourcesDir, "templates");
|
||||
}
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Copyright 1998-2004 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.
|
||||
-->
|
||||
|
||||
<!DOCTYPE binding SYSTEM "http://jibx.sourceforge.net">
|
||||
<binding>
|
||||
<mapping class="org.jdesktop.synthdesigner.synthmodel.UIDefault" abstract="true" post-set="postSet">
|
||||
<value name="name" field="name" style="attribute"/>
|
||||
</mapping>
|
||||
<!-- == AWT TYPES =========================================================================================== -->
|
||||
<mapping class="java.awt.Color"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.ColorMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.ColorMapper"/>
|
||||
<mapping class="java.lang.Class"
|
||||
marshaller="org.jdesktop.synthdesigner.synthmodel.jibxhelpers.ClassMapper"
|
||||
unmarshaller="org.jdesktop.synthdesigner.synthmodel.jibxhelpers.ClassMapper"/>
|
||||
<!-- == UI FONT =========================================================================================== -->
|
||||
<mapping name="typeface" class="org.jdesktop.swingx.designer.font.Typeface" post-set="postSet">
|
||||
<value name="family" field="name" style="attribute" usage="optional"/>
|
||||
<value name="bold" field="bold" style="attribute" usage="optional" default="Default"/>
|
||||
<value name="italic" field="italic" style="attribute" usage="optional" default="Default"/>
|
||||
<value name="size" field="size" style="attribute" usage="optional"/>
|
||||
<value name="sizeOffset" field="sizeOffset" style="attribute" usage="optional" default="1"/>
|
||||
<value name="uiDefaultParentName" field="uiDefaultParentName" style="attribute" usage="optional"/>
|
||||
</mapping>
|
||||
<mapping name="uiFont" class="org.jdesktop.synthdesigner.synthmodel.UIFont"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIDefault">
|
||||
<structure map-as="org.jdesktop.synthdesigner.synthmodel.UIDefault"/>
|
||||
<collection get-method="getFonts" set-method="setFonts" create-type="java.util.ArrayList"/>
|
||||
</mapping>
|
||||
<!-- == UI INSETS =========================================================================================== -->
|
||||
<mapping name="uiInsets" class="org.jdesktop.synthdesigner.synthmodel.UIInsets"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIDefault">
|
||||
<structure map-as="org.jdesktop.synthdesigner.synthmodel.UIDefault"/>
|
||||
<structure name="insets" get-method="getInsets" set-method="setInsets"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"/>
|
||||
</mapping>
|
||||
<!-- == UI PAINT =========================================================================================== -->
|
||||
<mapping name="matte" class="org.jdesktop.swingx.designer.paint.Matte" post-set="postSet">
|
||||
<value name="red" field="red" style="attribute"/>
|
||||
<value name="green" field="green" style="attribute"/>
|
||||
<value name="blue" field="blue" style="attribute"/>
|
||||
<value name="alpha" field="alpha" style="attribute"/>
|
||||
<value name="uiDefaultParentName" field="uiDefaultParentName" style="attribute" usage="optional"/>
|
||||
<value name="componentPropertyName" field="componentPropertyName" style="attribute" usage="optional"/>
|
||||
<value name="hueOffset" field="hueOffset" style="attribute"/>
|
||||
<value name="saturationOffset" field="saturationOffset" style="attribute"/>
|
||||
<value name="brightnessOffset" field="brightnessOffset" style="attribute"/>
|
||||
<value name="alphaOffset" field="alphaOffset" style="attribute"/>
|
||||
<value name="uiResource" field="uiResource" style="attribute" usage="optional" default="true"/>
|
||||
</mapping>
|
||||
<mapping class="org.jdesktop.synthdesigner.synthmodel.UIPaint" abstract="true" type-name="uipaint"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIDefault">
|
||||
<structure map-as="org.jdesktop.synthdesigner.synthmodel.UIDefault"/>
|
||||
<structure get-method="getPaint" set-method="setPaint"/>
|
||||
</mapping>
|
||||
<mapping name="uiPaint" class="org.jdesktop.synthdesigner.synthmodel.UIPaint"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIDefault">
|
||||
<structure map-as="uipaint"/>
|
||||
</mapping>
|
||||
<mapping name="uiColor" class="org.jdesktop.synthdesigner.synthmodel.UIColor"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIPaint">
|
||||
<structure map-as="uipaint"/>
|
||||
</mapping>
|
||||
<!-- == UI STYLE =========================================================================================== -->
|
||||
<mapping class="org.jdesktop.synthdesigner.synthmodel.UIStyle" abstract="true" post-set="postSet">
|
||||
<structure field="font" usage="optional"/>
|
||||
<structure name="textForeground" usage="optional">
|
||||
<structure field="textForeground" usage="optional"/>
|
||||
</structure>
|
||||
<structure name="textBackground" usage="optional">
|
||||
<structure field="textBackground" usage="optional"/>
|
||||
</structure>
|
||||
<structure name="background" usage="optional">
|
||||
<structure field="background" usage="optional"/>
|
||||
</structure>
|
||||
<value name="inherit-font" field="fontInherited" usage="optional" default="true"/>
|
||||
<value name="inherit-textForeground" field="textForegroundInherited" usage="optional" default="true"/>
|
||||
<value name="inherit-textBackground" field="textBackgroundInherited" usage="optional" default="true"/>
|
||||
<value name="inherit-background" field="backgroundInherited" usage="optional" default="true"/>
|
||||
<value name="hintAlphaInterpolation" field="hintAlphaInterpolation" usage="optional"/>
|
||||
<value name="hintAntialiasing" field="hintAntialiasing" usage="optional"/>
|
||||
<value name="hintColorRendering" field="hintColorRendering" usage="optional"/>
|
||||
<value name="hintDithering" field="hintDithering" usage="optional"/>
|
||||
<value name="hintFractionalMetrics" field="hintFractionalMetrics" usage="optional"/>
|
||||
<value name="hintInterpolation" field="hintInterpolation" usage="optional"/>
|
||||
<value name="hintRendering" field="hintRendering" usage="optional"/>
|
||||
<value name="hintStrokeControl" field="hintStrokeControl" usage="optional"/>
|
||||
<value name="hintTextAntialiasing" field="hintTextAntialiasing" usage="optional"/>
|
||||
<value name="cacheSettingsInherited" field="cacheSettingsInherited" usage="optional" default="true"/>
|
||||
<value name="cacheMode" field="cacheMode" usage="optional" default="FIXED_SIZES"/>
|
||||
<value name="maxHozCachedImgScaling" field="maxHozCachedImgScaling" usage="optional" default="1"/>
|
||||
<value name="maxVertCachedImgScaling" field="maxVertCachedImgScaling" usage="optional" default="1"/>
|
||||
<collection name="uiproperties" field="uiProperties" create-type="java.util.ArrayList">
|
||||
<structure marshaller="org.jdesktop.synthdesigner.synthmodel.jibxhelpers.UIPropertyMapper"
|
||||
unmarshaller="org.jdesktop.synthdesigner.synthmodel.jibxhelpers.UIPropertyMapper"/>
|
||||
</collection>
|
||||
</mapping>
|
||||
<!-- == UI STATE =========================================================================================== -->
|
||||
<mapping name="stateType" class="org.jdesktop.synthdesigner.synthmodel.UIStateType">
|
||||
<value name="key" field="key" style="attribute"/>
|
||||
<structure name="codeSnippet" usage="optional" test-method="hasCodeSnippet">
|
||||
<value field="codeSnippet" style="cdata" usage="optional"/>
|
||||
</structure>
|
||||
</mapping>
|
||||
<mapping name="state" class="org.jdesktop.synthdesigner.synthmodel.UIState" post-set="postSet" pre-set="preSet">
|
||||
<value name="stateKeys" field="stateKeys" style="attribute" get-method="getStateKeys" set-method="setStateKeys"
|
||||
serializer="org.jdesktop.synthdesigner.synthmodel.UIState.keysToString"
|
||||
deserializer="org.jdesktop.synthdesigner.synthmodel.UIState.stringToKeys"/>
|
||||
<value name="inverted" field="inverted" style="attribute" usage="optional"/>
|
||||
<structure name="style" field="style"/>
|
||||
<structure field="canvas"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.CanvasMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.CanvasMapper"/>
|
||||
</mapping>
|
||||
<!-- == REGIONS =========================================================================================== -->
|
||||
<mapping class="org.jdesktop.synthdesigner.synthmodel.UIRegion" abstract="true"
|
||||
type-name="region" pre-set="preSet">
|
||||
<value name="name" field="name" style="attribute"/>
|
||||
<value name="ui" field="ui" style="attribute" usage="optional"/>
|
||||
<value name="subregion" field="subregion" style="attribute"/>
|
||||
<value name="key" field="key" style="attribute" usage="optional"/>
|
||||
<value name="title" field="title" style="attribute" usage="optional"/>
|
||||
<structure name="contentMargins" field="contentMargins"
|
||||
marshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"
|
||||
unmarshaller="org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper"/>
|
||||
<structure name="style" field="style"/>
|
||||
<collection name="backgroundStates" field="backgroundStates" create-type="java.util.ArrayList"/>
|
||||
<collection name="foregroundStates" field="foregroundStates" create-type="java.util.ArrayList"/>
|
||||
<collection name="borderStates" field="borderStates" create-type="java.util.ArrayList"/>
|
||||
<collection name="regions" field="subRegions" create-type="java.util.ArrayList"/>
|
||||
</mapping>
|
||||
<mapping name="region" class="org.jdesktop.synthdesigner.synthmodel.UIRegion">
|
||||
<structure map-as="region"/>
|
||||
</mapping>
|
||||
<mapping name="uiIconRegion" class="org.jdesktop.synthdesigner.synthmodel.UIIconRegion"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIRegion">
|
||||
<structure map-as="region"/>
|
||||
<value name="basicKey" field="basicKey" style="attribute" usage="optional"/>
|
||||
</mapping>
|
||||
<mapping name="uiComponent" class="org.jdesktop.synthdesigner.synthmodel.UIComponent"
|
||||
extends="org.jdesktop.synthdesigner.synthmodel.UIRegion">
|
||||
<value name="opaque" field="opaque" style="attribute"/>
|
||||
<value name="componentName" field="componentName" style="attribute" usage="optional"/>
|
||||
<value name="type" field="type" style="attribute"/>
|
||||
<collection name="stateTypes" field="stateTypes" create-type="java.util.ArrayList"/>
|
||||
<structure map-as="region"/>
|
||||
</mapping>
|
||||
<!-- == BASE MODEL =========================================================================================== -->
|
||||
<mapping name="synthModel" class="org.jdesktop.synthdesigner.synthmodel.SynthModel" pre-set="preSet">
|
||||
<collection name="insets" field="insets" create-type="java.util.ArrayList"/>
|
||||
<collection name="colors" field="colors" create-type="java.util.ArrayList"/>
|
||||
<collection name="fonts" field="fonts" create-type="java.util.ArrayList"/>
|
||||
<structure name="style" field="globalStyle"/>
|
||||
<collection name="components" field="components" create-type="java.util.ArrayList"/>
|
||||
</mapping>
|
||||
</binding>
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 javax.swing.border.Border;
|
||||
|
||||
/**
|
||||
* UIBorder
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIBorder extends UIDefault<Border> {
|
||||
|
||||
public UIBorder() {
|
||||
}
|
||||
|
||||
public UIBorder(String id, Border b) {
|
||||
super(id, b);
|
||||
}
|
||||
|
||||
public Border getBorder() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
public void setBorder(Border b) {
|
||||
Border old = getBorder();
|
||||
super.setValue(b);
|
||||
firePropertyChange("border", old, b);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.swingx.designer.paint.Matte;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* UIColor
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIColor extends UIPaint {
|
||||
|
||||
public UIColor() {
|
||||
}
|
||||
|
||||
public UIColor(String id, Matte value) {
|
||||
super(id, value);
|
||||
}
|
||||
|
||||
public UIColor(String id, Color color, UIDefaults modelDefaults) {
|
||||
this(id, new Matte(color, modelDefaults));
|
||||
}
|
||||
|
||||
public Matte getPaint() {
|
||||
return (Matte) super.getPaint();
|
||||
}
|
||||
|
||||
public void setPaint(Matte c) {
|
||||
super.setPaint(c);
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.swingx.designer.utils.HasUIDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* UIComponent - model node that represents the designs for a single swing component
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIComponent extends UIRegion implements HasUIDefaults {
|
||||
|
||||
/** The classname of the swing component that this UIComponent represents */
|
||||
private String type;
|
||||
/** The name of the component if its a named component or null if its a generic component */
|
||||
private String componentName = null;
|
||||
/** If this components is opaque which means that when it is painted all of its bounds are filled */
|
||||
private boolean opaque = false;
|
||||
/**
|
||||
* A list of state types that are available to this region and sub regions of this component but not subcomponents
|
||||
* of this component. If this list is empty then the standard synth set of state types are assumed.
|
||||
*/
|
||||
private List<UIStateType> stateTypes;
|
||||
|
||||
// =================================================================================================================
|
||||
// Contructors
|
||||
|
||||
/** no-args contructor for JIBX */
|
||||
protected UIComponent() {
|
||||
super();
|
||||
// create new observable list for state types so we get events for when the model changes
|
||||
stateTypes = new ArrayList<UIStateType>();
|
||||
}
|
||||
|
||||
public UIComponent(String name, String type, String ui, UIRegion... subRegions) {
|
||||
super(name, ui, subRegions);
|
||||
this.type = type;
|
||||
for (UIRegion r : subRegions) {
|
||||
r.setRegion(this);
|
||||
}
|
||||
// create new observable list for state types so we get events for when the model changes
|
||||
stateTypes = new ArrayList<UIStateType>();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
public String getComponentName() {
|
||||
return componentName;
|
||||
}
|
||||
|
||||
public void setComponentName(String componentName) {
|
||||
String old = getComponentName();
|
||||
this.componentName = componentName;
|
||||
firePropertyChange("componentName", old, getComponentName());
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return opaque;
|
||||
}
|
||||
|
||||
public void setOpaque(boolean opaque) {
|
||||
boolean old = isOpaque();
|
||||
this.opaque = opaque;
|
||||
firePropertyChange("opaque", old, isOpaque());
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
String old = getType();
|
||||
this.type = type;
|
||||
firePropertyChange("type", old, getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of state types that are available to this region and sub regions of this component but not
|
||||
* subcomponents of this component. If this list is empty then the standard synth set of state types are assumed.
|
||||
*
|
||||
* @return List of available state types
|
||||
*/
|
||||
public List<UIStateType> getStateTypes() {
|
||||
return stateTypes;
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
if (key == null || "".equals(key)) {
|
||||
if (componentName == null || "".equals(componentName)) {
|
||||
return getName();
|
||||
} else {
|
||||
return "\"" + componentName + "\"";
|
||||
}
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String getTitle() {
|
||||
if (title == null || "".equals(title)) {
|
||||
if (componentName == null || "".equals(componentName)) {
|
||||
return getName();
|
||||
} else {
|
||||
return componentName;
|
||||
}
|
||||
} else {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* Represents an entry in the UI defaults table.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIDefault<T> extends AbstractBean implements HasUIDefaults {
|
||||
private String name;
|
||||
private T value;
|
||||
/**
|
||||
* This is a local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*/
|
||||
private transient UIDefaults modelDefaults = null;
|
||||
|
||||
public UIDefault() {
|
||||
}
|
||||
|
||||
public UIDefault(String name, T value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public UIDefault(String name, T value, UIDefaults modelDefaults) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.modelDefaults = modelDefaults;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void postSet(IUnmarshallingContext context) {
|
||||
// walk up till we get synth model
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIDefaults) {
|
||||
modelDefaults = ((HasUIDefaults) context.getStackObject(i)).getUiDefaults();
|
||||
if (modelDefaults != null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
/**
|
||||
* Get the local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*
|
||||
* @return The UIDefaults for the synth model
|
||||
*/
|
||||
public UIDefaults getUiDefaults() {
|
||||
return modelDefaults;
|
||||
}
|
||||
|
||||
public void setValue(T t) {
|
||||
T old = this.value;
|
||||
this.value = t;
|
||||
firePropertyChange("value", old, getValue());
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
String old = this.name;
|
||||
firePropertyChange("name", old, name);
|
||||
this.name = name;
|
||||
// update model defaults
|
||||
if (old != null) modelDefaults.remove(old);
|
||||
modelDefaults.put(getName(), getValue());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 java.awt.Dimension;
|
||||
|
||||
/**
|
||||
* UIDimension
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIDimension extends UIDefault<Dimension> {
|
||||
public UIDimension() {
|
||||
}
|
||||
|
||||
public Dimension getDimension() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
public void setDimension(Dimension d) {
|
||||
Dimension old = getDimension();
|
||||
super.setValue(d);
|
||||
firePropertyChange("dimension", old, d);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 java.awt.Font;
|
||||
import org.jdesktop.swingx.designer.font.Typeface;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.UIDefaults;
|
||||
|
||||
/**
|
||||
* Represents a single font entry in the UIDefaults table. Each UIFont takes a
|
||||
* list of Typefaces. These typefaces are listed by order of preference. Thus,
|
||||
* when putting a font into UIDefaults, the code can check whether each font
|
||||
* exists, and when it finds the first font that does, insert it.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIFont extends UIDefault<List<Typeface>> 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<Typeface>());
|
||||
}
|
||||
|
||||
public UIFont(String id, List<Typeface> values, UIDefaults defaults) {
|
||||
super(id, values, defaults);
|
||||
updateUIDefaults();
|
||||
}
|
||||
|
||||
public UIFont(String id, Font font, UIDefaults modelDefaults) {
|
||||
this(id, Arrays.asList(new Typeface(font, modelDefaults)), modelDefaults);
|
||||
}
|
||||
|
||||
public List<Typeface> getFonts() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
private void setFonts(List<Typeface> values) {
|
||||
super.setValue(values);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 javax.swing.Icon;
|
||||
|
||||
/**
|
||||
* UIIcon
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIIcon extends UIDefault<Icon> {
|
||||
|
||||
public UIIcon() {
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
public void setIcon(Icon i) {
|
||||
Icon old = getIcon();
|
||||
super.setValue(i);
|
||||
firePropertyChange("icon", old, i);
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A UIRegion subclass which is used for generating icons. For example, JRadioButton and JCheckBox represent themselves
|
||||
* mainly via their icons. However, from the designers perspective, the main design isn't an "icon", but just a region
|
||||
* on the button.
|
||||
* <p/>
|
||||
* That type of region is represented by a UIIconRegion. UIIconRegion contains a string which references the UIDefault
|
||||
* value associated with this icon. For example, RadioButton.icon.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIIconRegion extends UIRegion {
|
||||
/** The UiDefaults key which this icon should be stored for basic LaF to find it. This is absolute */
|
||||
private String basicKey = null;
|
||||
|
||||
public UIIconRegion() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getBasicKey() {
|
||||
return basicKey;
|
||||
}
|
||||
|
||||
public void setBasicKey(String basicKey) {
|
||||
String old = getBasicKey();
|
||||
this.basicKey = basicKey;
|
||||
firePropertyChange("basicKey",old,getBasicKey());
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 java.awt.Insets;
|
||||
|
||||
/**
|
||||
* UIInsets
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIInsets extends UIDefault<Insets> {
|
||||
|
||||
public UIInsets() {
|
||||
}
|
||||
|
||||
public UIInsets(String id, Insets value) {
|
||||
super(id, value);
|
||||
}
|
||||
|
||||
public Insets getInsets() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
public void setInsets(Insets i) {
|
||||
Insets old = getInsets();
|
||||
super.setValue(i);
|
||||
firePropertyChange("insets", old, i);
|
||||
// update model defaults
|
||||
getUiDefaults().put(getName(), i);
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "UiInset(" + getName() + ")" +
|
||||
((getInsets() == null) ? " NONE" : "(" + getInsets().top + "," + getInsets().left + "," +
|
||||
getInsets().bottom + "," + getInsets().right + ")");
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.swingx.designer.paint.Matte;
|
||||
import org.jdesktop.swingx.designer.paint.PaintModel;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
* UIPaint
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIPaint extends UIDefault<PaintModel> {
|
||||
|
||||
/** Listener to keep model UiDefaults up to date for this UiPaint */
|
||||
private PropertyChangeListener matteListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
PaintModel paintModel = getValue();
|
||||
if (paintModel instanceof Matte) {
|
||||
getUiDefaults().put(getName(), ((Matte) paintModel).getColor());
|
||||
}
|
||||
// propogate the paint change up as PaintModel is a mutable object
|
||||
if (evt.getPropertyName().equals("paint")) {
|
||||
firePropertyChange("paint", null, getPaint());
|
||||
firePropertyChange("value", null, getPaint());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public UIPaint() {}
|
||||
|
||||
public UIPaint(String id, PaintModel value) {
|
||||
super(id, value, (value instanceof Matte) ? ((Matte) value).getUiDefaults() : null);
|
||||
// update model defaults
|
||||
if (value instanceof Matte) {
|
||||
Matte matte = (Matte) value;
|
||||
if (getUiDefaults() != null) getUiDefaults().put(getName(), matte.getColor());
|
||||
matte.addPropertyChangeListener(matteListener);
|
||||
}
|
||||
}
|
||||
|
||||
public PaintModel getPaint() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
public void setPaint(PaintModel c) {
|
||||
PaintModel old = getPaint();
|
||||
if (old instanceof Matte) old.removePropertyChangeListener(matteListener);
|
||||
super.setValue(c);
|
||||
firePropertyChange("paint", old, c);
|
||||
// update model defaults
|
||||
if (c instanceof Matte) {
|
||||
Matte matte = (Matte) c;
|
||||
getUiDefaults().put(getName(), matte.getColor());
|
||||
matte.addPropertyChangeListener(matteListener);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* UIProperty
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIProperty extends AbstractBean {
|
||||
public static enum PropertyType {
|
||||
BOOLEAN, INT, FLOAT, DOUBLE, STRING, FONT, COLOR, INSETS, DIMENSION, BORDER
|
||||
}
|
||||
|
||||
private String name;
|
||||
private PropertyType type;
|
||||
private Object value;
|
||||
|
||||
protected UIProperty() {
|
||||
}
|
||||
|
||||
public UIProperty(String name, PropertyType type, Object value) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
String old = getName();
|
||||
this.name = name;
|
||||
firePropertyChange("name", old, getName());
|
||||
}
|
||||
|
||||
public PropertyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(PropertyType type) {
|
||||
PropertyType old = getType();
|
||||
this.type = type;
|
||||
firePropertyChange("type", old, getType());
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
Object old = getValue();
|
||||
this.value = value;
|
||||
firePropertyChange("value", old, getValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.awt.Insets;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents a "Region" in synth, which also includes entire components.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIRegion extends AbstractBean implements HasUIDefaults, HasUIStyle {
|
||||
private String name;//the code-wise name of the region
|
||||
protected String key; //the UIdefaults key for this region
|
||||
protected String title; //the user friendly name/title of this region
|
||||
/** List of background states */
|
||||
private List<UIState> backgroundStates;
|
||||
/** List of foreground states */
|
||||
private List<UIState> foregroundStates;
|
||||
/** List of border states */
|
||||
private List<UIState> borderStates;
|
||||
private UIStyle style = new UIStyle();
|
||||
protected Insets contentMargins = new Insets(0, 0, 0, 0);
|
||||
/** Sub regions, if any */
|
||||
private List<UIRegion> subRegions;
|
||||
|
||||
//together with name, these two fields allow me to reconstruct, in
|
||||
//code, a synth Region, including a custom Region, if you make one.
|
||||
private String ui;
|
||||
private boolean subregion;
|
||||
/**
|
||||
* This is a local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*/
|
||||
private transient UIDefaults modelDefaults = null;
|
||||
|
||||
private UIRegion region; //the region that this region belongs to
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
/** no-args contructor for JIBX */
|
||||
protected UIRegion() {
|
||||
subRegions = new ArrayList<UIRegion>();
|
||||
backgroundStates = new ArrayList<UIState>();
|
||||
foregroundStates = new ArrayList<UIState>();
|
||||
borderStates = new ArrayList<UIState>();
|
||||
style.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("style." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public UIRegion(String name, UIRegion... subRegions) {
|
||||
this(name, null, true, subRegions);
|
||||
}
|
||||
|
||||
public UIRegion(String name, String ui, UIRegion... subRegions) {
|
||||
this(name, ui, false, subRegions);
|
||||
}
|
||||
|
||||
public UIRegion(String name, String ui, boolean subregion, UIRegion... subRegions) {
|
||||
this();
|
||||
this.name = name;
|
||||
this.ui = ui;
|
||||
this.subregion = subregion;
|
||||
if (subRegions != null) {
|
||||
for (UIRegion r : subRegions) {
|
||||
if (r != null) {
|
||||
this.subRegions.add(r);
|
||||
r.getStyle().setParentStyle(getStyle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void preSet(IUnmarshallingContext context) {
|
||||
// walk up till we get synth model
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIDefaults) {
|
||||
modelDefaults = ((HasUIDefaults) context.getStackObject(i)).getUiDefaults();
|
||||
if (modelDefaults != null) break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof UIRegion && context.getStackObject(i) != this) {
|
||||
region = (UIRegion) context.getStackObject(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
public Insets getContentMargins() {
|
||||
return contentMargins;
|
||||
}
|
||||
|
||||
public void setContentMargins(Insets contentMargins) {
|
||||
Insets old = getContentMargins();
|
||||
this.contentMargins = contentMargins;
|
||||
firePropertyChange("contentMargins", old, getContentMargins());
|
||||
}
|
||||
|
||||
void setRegion(UIRegion r) {
|
||||
this.region = r;
|
||||
}
|
||||
|
||||
public UIRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*
|
||||
* @return The UIDefaults for the synth model
|
||||
*/
|
||||
public UIDefaults getUiDefaults() {
|
||||
return modelDefaults;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public final UIRegion[] getSubRegions() {
|
||||
return subRegions.toArray(new UIRegion[0]);
|
||||
}
|
||||
|
||||
public final UIState[] getBackgroundStates() {
|
||||
return backgroundStates.toArray(new UIState[0]);
|
||||
}
|
||||
|
||||
public final UIState[] getForegroundStates() {
|
||||
return foregroundStates.toArray(new UIState[0]);
|
||||
}
|
||||
|
||||
public final UIState[] getBorderStates() {
|
||||
return borderStates.toArray(new UIState[0]);
|
||||
}
|
||||
|
||||
public UIStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public final boolean isSubRegion() {
|
||||
return subregion;
|
||||
}
|
||||
|
||||
public final String getUi() {
|
||||
return ui;
|
||||
}
|
||||
|
||||
public void addBackgroundState(UIState state) {
|
||||
// check if we already have that state
|
||||
for (UIState uiState : backgroundStates) {
|
||||
if (uiState.getName().equals(state.getName())) return;
|
||||
}
|
||||
backgroundStates.add(state);
|
||||
state.setRegion(this);
|
||||
firePropertyChange("backgroundStates", null, backgroundStates);
|
||||
}
|
||||
|
||||
public void removeBackgroundState(UIState state) {
|
||||
if (backgroundStates.remove(state)) {
|
||||
firePropertyChange("backgroundStates", null, backgroundStates);
|
||||
}
|
||||
}
|
||||
|
||||
public void addForegroundState(UIState state) {
|
||||
// check if we already have that state
|
||||
for (UIState uiState : foregroundStates) {
|
||||
if (uiState.getName().equals(state.getName())) return;
|
||||
}
|
||||
foregroundStates.add(state);
|
||||
state.setRegion(this);
|
||||
firePropertyChange("foregroundStates", null, foregroundStates);
|
||||
}
|
||||
|
||||
public void removeForegroundState(UIState state) {
|
||||
if (foregroundStates.remove(state)) {
|
||||
firePropertyChange("foregroundStates", null, foregroundStates);
|
||||
}
|
||||
}
|
||||
|
||||
public void addBorderState(UIState state) {
|
||||
// check if we already have that state
|
||||
for (UIState uiState : borderStates) {
|
||||
if (uiState.getName().equals(state.getName())) return;
|
||||
}
|
||||
borderStates.add(state);
|
||||
state.setRegion(this);
|
||||
firePropertyChange("borderStates", null, borderStates);
|
||||
}
|
||||
|
||||
public void removeBorderState(UIState state) {
|
||||
if (borderStates.remove(state)) {
|
||||
firePropertyChange("borderStates", null, borderStates);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getKey() {
|
||||
return key == null || "".equals(key) ? name : key;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title == null || "".equals(title) ? name : title;
|
||||
}
|
||||
}
|
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* 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.Canvas;
|
||||
import org.jdesktop.swingx.designer.utils.HasPath;
|
||||
import org.jdesktop.swingx.designer.utils.HasUIDefaults;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
|
||||
import javax.swing.UIDefaults;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a State in the Synth LAF.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIState extends AbstractBean implements HasUIStyle, HasPath {
|
||||
|
||||
private List<String> stateKeys;
|
||||
private boolean inverted; //indicates whether to invert the meaning of the 9-square stretching insets
|
||||
/** A cached string representing the list of stateKeys deliminated with "+" */
|
||||
private String cachedName = null;
|
||||
private Canvas canvas;
|
||||
private UIStyle style;
|
||||
/** the region that this state belongs to */
|
||||
private UIRegion region;
|
||||
/**
|
||||
* This is a local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*/
|
||||
private transient UIDefaults modelDefaults = null;
|
||||
|
||||
// =================================================================================================================
|
||||
// Contructors
|
||||
|
||||
public UIState() {
|
||||
// Create state keys as event list so model changes are propogated
|
||||
stateKeys = new ArrayList<String>();
|
||||
}
|
||||
|
||||
public UIState(SynthModel model, UIRegion parentRegion, String... stateTypeKeys) {
|
||||
// Create state keys as event list so model changes are propogated
|
||||
stateKeys = new ArrayList<String>();
|
||||
this.stateKeys.addAll(Arrays.asList(stateTypeKeys));
|
||||
//
|
||||
modelDefaults = model.getUiDefaults();
|
||||
region = parentRegion;
|
||||
// create new canvas
|
||||
canvas = new Canvas(100, 30);
|
||||
canvas.setUiDefaults(modelDefaults);
|
||||
String canvasPath = getPath();
|
||||
canvas.setResourcesDir(new File(model.getResourcesDir(), canvasPath));
|
||||
canvas.setTemplatesDir(new File(model.getTemplatesDir(), canvasPath));
|
||||
canvas.setImagesDir(new File(model.getImagesDir(), canvasPath));
|
||||
canvas.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("canvas." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
// create new style
|
||||
style = new UIStyle();
|
||||
style.setParentStyle(region.getStyle());
|
||||
style.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("style." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* JIBX needs this
|
||||
*
|
||||
* @param stateKeys The new list of states
|
||||
*/
|
||||
private void setStateKeys(List<String> stateKeys) {
|
||||
if (stateKeys != this.stateKeys) {
|
||||
this.stateKeys.clear();
|
||||
this.stateKeys.addAll(stateKeys);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void preSet(IUnmarshallingContext context) {
|
||||
// walk up till we get synth model
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIDefaults) {
|
||||
modelDefaults = ((HasUIDefaults) context.getStackObject(i)).getUiDefaults();
|
||||
if (modelDefaults != null) break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof UIRegion) {
|
||||
region = (UIRegion) context.getStackObject(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void postSet(IUnmarshallingContext context) {
|
||||
// add listeners to pass canvas and style events up tree
|
||||
canvas.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("canvas." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
style.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("style." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
/**
|
||||
* Get path to this UI State of the form /RegionA/RegionB/StateName
|
||||
*
|
||||
* @return Path to this state
|
||||
*/
|
||||
public String getPath() {
|
||||
StringBuilder buf = new StringBuilder(getName());
|
||||
UIRegion region = getRegion();
|
||||
// check if we are foreground background or border
|
||||
boolean found = false;
|
||||
for (UIState state : region.getBackgroundStates()) {
|
||||
if (state == this) {
|
||||
buf.insert(0, "Background/");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
for (UIState state : region.getForegroundStates()) {
|
||||
if (state == this) {
|
||||
buf.insert(0, "Foreground/");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
for (UIState state : region.getBorderStates()) {
|
||||
if (state == this) {
|
||||
buf.insert(0, "Border/");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add parent regions
|
||||
while (region != null) {
|
||||
buf.insert(0, '/');
|
||||
if (region instanceof UIComponent && ((UIComponent) region).getComponentName() != null) {
|
||||
buf.insert(0, ((UIComponent) region).getComponentName());
|
||||
} else {
|
||||
buf.insert(0, region.getName());
|
||||
}
|
||||
region = region.getRegion();
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
void setRegion(UIRegion r) {
|
||||
this.region = r;
|
||||
this.style.setParentStyle(r.getStyle());
|
||||
}
|
||||
|
||||
public UIRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local UIDefaults that contains all the UIDefaults in the synth model. It is kept uptodate by the
|
||||
* indervidual UIDefaults nodes
|
||||
*
|
||||
* @return The UIDefaults for the synth model
|
||||
*/
|
||||
public UIDefaults getUIDefaults() {
|
||||
return modelDefaults;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of state type keys for this state. This state is applied when the current component state matches as
|
||||
* many as possible of these state types.
|
||||
*
|
||||
* @return List of state types that need to be true for this state. This is direct access to the data and changes to
|
||||
* the returned list will effect this UiState.
|
||||
*/
|
||||
public List<String> getStateKeys() {
|
||||
return stateKeys;
|
||||
}
|
||||
|
||||
public void setInverted(boolean b) {
|
||||
boolean old = inverted;
|
||||
inverted = b;
|
||||
firePropertyChange("invert", old, b);
|
||||
}
|
||||
|
||||
public final boolean isInverted() {
|
||||
return inverted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
if (cachedName == null) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
List<String> keys = new ArrayList<String>(stateKeys);
|
||||
Collections.sort(keys);
|
||||
for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
|
||||
buf.append(iter.next());
|
||||
if (iter.hasNext()) buf.append('+');
|
||||
}
|
||||
cachedName = buf.toString();
|
||||
}
|
||||
return cachedName;
|
||||
}
|
||||
|
||||
public final Canvas getCanvas() {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public void setCanvas(Canvas c) {
|
||||
Canvas old = canvas;
|
||||
canvas = c;
|
||||
firePropertyChange("canvas", old, c);
|
||||
}
|
||||
|
||||
public UIStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Helper Methods
|
||||
|
||||
public static String keysToString(List<String> keys) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
|
||||
buf.append(iter.next());
|
||||
if (iter.hasNext()) buf.append('+');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static List<String> stringToKeys(String keysString) {
|
||||
return Arrays.asList(keysString.split("\\+"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* UIStateType - A UIComponents has a collection of these which constitute the avilables states which can be chosen in
|
||||
* the components regions. A UIStateType can be either a custom state or one of the predefined standard states.
|
||||
*
|
||||
* @author Richard Bair
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class UIStateType extends AbstractBean {
|
||||
/* Keys for standard synth states */
|
||||
public static final String ENABLED_KEY = "Enabled";
|
||||
public static final String MOUSE_OVER_KEY = "MouseOver";
|
||||
public static final String PRESSED_KEY = "Pressed";
|
||||
public static final String DISABLED_KEY = "Disabled";
|
||||
public static final String FOCUSED_KEY = "Focused";
|
||||
public static final String SELECTED_KEY = "Selected";
|
||||
public static final String DEFAULT_KEY = "Default";
|
||||
public static final String[] STANDARD_SYNTH_STATE_KEYS = new String[]{
|
||||
ENABLED_KEY, MOUSE_OVER_KEY, PRESSED_KEY, DISABLED_KEY, FOCUSED_KEY, SELECTED_KEY, DEFAULT_KEY
|
||||
};
|
||||
public static final UIStateType[] STANDARD_SYNTH_STATES = new UIStateType[]{
|
||||
new UIStateType(ENABLED_KEY),
|
||||
new UIStateType(MOUSE_OVER_KEY),
|
||||
new UIStateType(PRESSED_KEY),
|
||||
new UIStateType(DISABLED_KEY),
|
||||
new UIStateType(FOCUSED_KEY),
|
||||
new UIStateType(SELECTED_KEY),
|
||||
new UIStateType(DEFAULT_KEY)
|
||||
};
|
||||
|
||||
/** Unique string for the ui key for this state, must be unique within a components set of UiStateTypes */
|
||||
private String key;
|
||||
/**
|
||||
* Snippet of java code that defines calculates the value of this state for a particular component. The varaiable
|
||||
* <code>c</code> 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 <code>c</code> 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 <code>c</code> 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 <code>true</code> if codeSnippet is non null
|
||||
*/
|
||||
public boolean hasCodeSnippet() {
|
||||
return codeSnippet != null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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 List<UIProperty> uiProperties;
|
||||
private UIStyle parentStyle = null;
|
||||
|
||||
private PropertyChangeListener textForegoundListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("textForeground." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
private PropertyChangeListener textBackgroundListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("textBackground." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
private PropertyChangeListener backgroundListener = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
firePropertyChange("background." + evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
};
|
||||
|
||||
// =================================================================================================================
|
||||
// Constructors
|
||||
|
||||
public UIStyle() {
|
||||
uiProperties = new ArrayList<UIProperty>();
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// JIBX Methods
|
||||
|
||||
/**
|
||||
* Called by JIBX after all fields have been set
|
||||
*
|
||||
* @param context The JIBX Unmarshalling Context
|
||||
*/
|
||||
private void postSet(IUnmarshallingContext context) {
|
||||
// walk up till we get a parent style
|
||||
for (int i = 0; i < context.getStackDepth(); i++) {
|
||||
if (context.getStackObject(i) instanceof HasUIStyle) {
|
||||
HasUIStyle hasStyle = (HasUIStyle) context.getStackObject(i);
|
||||
if (hasStyle.getStyle() != this) {
|
||||
parentStyle = hasStyle.getStyle();
|
||||
if (parentStyle != null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================================
|
||||
// Bean Methods
|
||||
|
||||
public UIStyle getParentStyle() {
|
||||
return parentStyle;
|
||||
}
|
||||
|
||||
public void setParentStyle(UIStyle parentStyle) {
|
||||
UIStyle old = getParentStyle();
|
||||
this.parentStyle = parentStyle;
|
||||
firePropertyChange("parentStyle", old, getParentStyle());
|
||||
}
|
||||
|
||||
public List<UIProperty> getUiProperties() {
|
||||
return uiProperties;
|
||||
}
|
||||
|
||||
public void addUiProperty(UIProperty uiProperty) {
|
||||
uiProperties.add(uiProperty);
|
||||
// todo not quite sure what events we want here
|
||||
fireIndexedPropertyChange("uiProperties", uiProperties.size(), null, uiProperty);
|
||||
// firePropertyChange("uiProperties", null, uiProperties);
|
||||
}
|
||||
|
||||
public void removeUiProperty(UIProperty uiProperty) {
|
||||
int index = uiProperties.indexOf(uiProperty);
|
||||
if (index != -1) {
|
||||
uiProperties.remove(uiProperty);
|
||||
// todo not quite sure what events we want here
|
||||
fireIndexedPropertyChange("uiProperties", index, null, uiProperty);
|
||||
// firePropertyChange("uiProperties", null, uiProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public Typeface getFont() {
|
||||
if (isFontInherited()) {
|
||||
return parentStyle == null ? font : parentStyle.getFont();
|
||||
} else {
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFont(Typeface font) {
|
||||
Typeface old = getFont();
|
||||
this.font = font;
|
||||
firePropertyChange("font", old, font);
|
||||
}
|
||||
|
||||
public boolean isFontInherited() {
|
||||
return fontInherited;
|
||||
}
|
||||
|
||||
public void setFontInherited(boolean b) {
|
||||
boolean old = isFontInherited();
|
||||
fontInherited = b;
|
||||
firePropertyChange("fontInherited", old, b);
|
||||
|
||||
if (!fontInherited && font == null && parentStyle != null && parentStyle.getFont() != null) {
|
||||
font = parentStyle.getFont().clone();
|
||||
firePropertyChange("font", null, font);
|
||||
}
|
||||
}
|
||||
|
||||
public Matte getTextForeground() {
|
||||
if (isTextForegroundInherited()) {
|
||||
return parentStyle == null ? null : parentStyle.getTextForeground();
|
||||
} else {
|
||||
return textForeground;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTextForegroundInherited() {
|
||||
return textForegroundInherited;
|
||||
}
|
||||
|
||||
public void setTextForegroundInherited(boolean b) {
|
||||
boolean old = isTextForegroundInherited();
|
||||
textForegroundInherited = b;
|
||||
firePropertyChange("foregroundInherited", old, b);
|
||||
|
||||
if (!textForegroundInherited && textForeground == null && parentStyle != null &&
|
||||
parentStyle.getTextForeground() != null) {
|
||||
textForeground = parentStyle.getTextForeground().clone();
|
||||
firePropertyChange("textForeground", null, textForeground);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextForeground(Matte textForeground) {
|
||||
Matte old = this.textForeground;
|
||||
if (old != null) old.removePropertyChangeListener(textForegoundListener);
|
||||
this.textForeground = textForeground;
|
||||
if (this.textForeground != null) this.textForeground.addPropertyChangeListener(textForegoundListener);
|
||||
firePropertyChange("textForeground", old, this.textForeground);
|
||||
}
|
||||
|
||||
public Matte getTextBackground() {
|
||||
if (isTextBackgroundInherited()) {
|
||||
return parentStyle == null ? null : parentStyle.getBackground();
|
||||
} else {
|
||||
return textBackground;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTextBackgroundInherited() {
|
||||
return textBackgroundInherited;
|
||||
}
|
||||
|
||||
public void setTextBackgroundInherited(boolean b) {
|
||||
boolean old = isBackgroundInherited();
|
||||
textBackgroundInherited = b;
|
||||
firePropertyChange("textBackgroundInherited", old, b);
|
||||
|
||||
if (!textBackgroundInherited && textBackground == null && parentStyle != null &&
|
||||
parentStyle.getTextBackground() != null) {
|
||||
textBackground = parentStyle.getTextBackground().clone();
|
||||
firePropertyChange("textBackground", null, textBackground);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextBackground(Matte textBackground) {
|
||||
Matte old = this.textBackground;
|
||||
if (old != null) old.removePropertyChangeListener(textBackgroundListener);
|
||||
this.textBackground = textBackground;
|
||||
if (this.textBackground != null) this.textBackground.addPropertyChangeListener(textBackgroundListener);
|
||||
firePropertyChange("textBackground", old, this.textBackground);
|
||||
}
|
||||
|
||||
public Matte getBackground() {
|
||||
if (isBackgroundInherited()) {
|
||||
return parentStyle == null ? null : parentStyle.getBackground();
|
||||
} else {
|
||||
return background;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBackgroundInherited() {
|
||||
return backgroundInherited;
|
||||
}
|
||||
|
||||
public void setBackgroundInherited(boolean b) {
|
||||
boolean old = isBackgroundInherited();
|
||||
backgroundInherited = b;
|
||||
firePropertyChange("backgroundInherited", old, b);
|
||||
|
||||
if (!backgroundInherited && background == null && parentStyle != null && parentStyle.getBackground() != null) {
|
||||
background = parentStyle.getBackground().clone();
|
||||
firePropertyChange("background", null, background);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBackground(Matte background) {
|
||||
Matte old = this.background;
|
||||
if (old != null) old.removePropertyChangeListener(backgroundListener);
|
||||
this.background = background;
|
||||
if (this.background != null) this.background.addPropertyChangeListener(backgroundListener);
|
||||
firePropertyChange("background", old, this.background);
|
||||
}
|
||||
|
||||
public HintAlphaInterpolation getHintAlphaInterpolation() {
|
||||
return hintAlphaInterpolation;
|
||||
}
|
||||
|
||||
public void setHintAlphaInterpolation(HintAlphaInterpolation hintAlphaInterpolation) {
|
||||
HintAlphaInterpolation old = getHintAlphaInterpolation();
|
||||
this.hintAlphaInterpolation = hintAlphaInterpolation;
|
||||
firePropertyChange("hintAlphaInterpolation", old, getHintAlphaInterpolation());
|
||||
}
|
||||
|
||||
public HintAntialiasing getHintAntialiasing() {
|
||||
return hintAntialiasing;
|
||||
}
|
||||
|
||||
public void setHintAntialiasing(HintAntialiasing hintAntialiasing) {
|
||||
HintAntialiasing old = getHintAntialiasing();
|
||||
this.hintAntialiasing = hintAntialiasing;
|
||||
firePropertyChange("hintAntialiasing", old, getHintAntialiasing());
|
||||
}
|
||||
|
||||
public HintColorRendering getHintColorRendering() {
|
||||
return hintColorRendering;
|
||||
}
|
||||
|
||||
public void setHintColorRendering(HintColorRendering hintColorRendering) {
|
||||
HintColorRendering old = getHintColorRendering();
|
||||
this.hintColorRendering = hintColorRendering;
|
||||
firePropertyChange("hintColorRendering", old, getHintColorRendering());
|
||||
}
|
||||
|
||||
public HintDithering getHintDithering() {
|
||||
return hintDithering;
|
||||
}
|
||||
|
||||
public void setHintDithering(HintDithering hintDithering) {
|
||||
HintDithering old = getHintDithering();
|
||||
this.hintDithering = hintDithering;
|
||||
firePropertyChange("hintDithering", old, getHintDithering());
|
||||
}
|
||||
|
||||
public HintFractionalMetrics getHintFractionalMetrics() {
|
||||
return hintFractionalMetrics;
|
||||
}
|
||||
|
||||
public void setHintFractionalMetrics(HintFractionalMetrics hintFractionalMetrics) {
|
||||
HintFractionalMetrics old = getHintFractionalMetrics();
|
||||
this.hintFractionalMetrics = hintFractionalMetrics;
|
||||
firePropertyChange("hintFractionalMetrics", old, getHintFractionalMetrics());
|
||||
}
|
||||
|
||||
public HintInterpolation getHintInterpolation() {
|
||||
return hintInterpolation;
|
||||
}
|
||||
|
||||
public void setHintInterpolation(HintInterpolation hintInterpolation) {
|
||||
HintInterpolation old = getHintInterpolation();
|
||||
this.hintInterpolation = hintInterpolation;
|
||||
firePropertyChange("hintInterpolation", old, getHintInterpolation());
|
||||
}
|
||||
|
||||
public HintRendering getHintRendering() {
|
||||
return hintRendering;
|
||||
}
|
||||
|
||||
public void setHintRendering(HintRendering hintRendering) {
|
||||
HintRendering old = getHintRendering();
|
||||
this.hintRendering = hintRendering;
|
||||
firePropertyChange("hintRendering", old, getHintRendering());
|
||||
}
|
||||
|
||||
public HintStrokeControl getHintStrokeControl() {
|
||||
return hintStrokeControl;
|
||||
}
|
||||
|
||||
public void setHintStrokeControl(HintStrokeControl hintStrokeControl) {
|
||||
HintStrokeControl old = getHintStrokeControl();
|
||||
this.hintStrokeControl = hintStrokeControl;
|
||||
firePropertyChange("hintStrokeControl", old, getHintStrokeControl());
|
||||
}
|
||||
|
||||
public HintTextAntialiasing getHintTextAntialiasing() {
|
||||
return hintTextAntialiasing;
|
||||
}
|
||||
|
||||
public void setHintTextAntialiasing(HintTextAntialiasing hintTextAntialiasing) {
|
||||
HintTextAntialiasing old = getHintTextAntialiasing();
|
||||
this.hintTextAntialiasing = hintTextAntialiasing;
|
||||
firePropertyChange("hintTextAntialiasing", old, getHintTextAntialiasing());
|
||||
}
|
||||
|
||||
public boolean isCacheSettingsInherited() {
|
||||
return cacheSettingsInherited;
|
||||
}
|
||||
|
||||
public void setCacheSettingsInherited(boolean cacheSettingsInherited) {
|
||||
boolean old = isCacheSettingsInherited();
|
||||
this.cacheSettingsInherited = cacheSettingsInherited;
|
||||
firePropertyChange("cacheSettingsInherited", old, isCacheSettingsInherited());
|
||||
}
|
||||
|
||||
public CacheMode getCacheMode() {
|
||||
if (isCacheSettingsInherited()) {
|
||||
return (parentStyle == null)?CacheMode.FIXED_SIZES : parentStyle.getCacheMode();
|
||||
} else {
|
||||
return cacheMode;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCacheMode(CacheMode cacheMode) {
|
||||
CacheMode old = this.cacheMode;
|
||||
this.cacheMode = cacheMode;
|
||||
if (isCacheSettingsInherited()) {
|
||||
setCacheSettingsInherited(false);
|
||||
UIStyle parent = getParentStyle();
|
||||
setMaxHozCachedImgScaling(parent == null ? 1 : parent.getMaxHozCachedImgScaling());
|
||||
setMaxVertCachedImgScaling(parent == null ? 1 : parent.getMaxVertCachedImgScaling());
|
||||
}
|
||||
firePropertyChange("cacheMode",old,cacheMode);
|
||||
}
|
||||
|
||||
public double getMaxHozCachedImgScaling() {
|
||||
if (isCacheSettingsInherited()) {
|
||||
return parentStyle == null ? 1 : parentStyle.getMaxHozCachedImgScaling();
|
||||
} else {
|
||||
return maxHozCachedImgScaling;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMaxHozCachedImgScaling(double maxHozCachedImgScaling) {
|
||||
double old = getMaxHozCachedImgScaling();
|
||||
this.maxHozCachedImgScaling = maxHozCachedImgScaling;
|
||||
if (isCacheSettingsInherited()) {
|
||||
setCacheSettingsInherited(false);
|
||||
setCacheMode((parentStyle == null)?CacheMode.FIXED_SIZES : parentStyle.getCacheMode());
|
||||
setMaxVertCachedImgScaling(parentStyle == null ? 1 : parentStyle.getMaxVertCachedImgScaling());
|
||||
}
|
||||
firePropertyChange("maxHozCachedImgScaling", old, getMaxHozCachedImgScaling());
|
||||
}
|
||||
|
||||
public double getMaxVertCachedImgScaling() {
|
||||
if (isCacheSettingsInherited()) {
|
||||
return parentStyle == null ? 1 : parentStyle.getMaxVertCachedImgScaling();
|
||||
} else {
|
||||
return maxVertCachedImgScaling;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMaxVertCachedImgScaling(double maxVertCachedImgScaling) {
|
||||
double old = getMaxVertCachedImgScaling();
|
||||
this.maxVertCachedImgScaling = maxVertCachedImgScaling;
|
||||
if (isCacheSettingsInherited()) {
|
||||
setCacheSettingsInherited(false);
|
||||
setCacheMode((parentStyle == null)?CacheMode.FIXED_SIZES : parentStyle.getCacheMode());
|
||||
setMaxHozCachedImgScaling(parentStyle == null ? 1 : parentStyle.getMaxHozCachedImgScaling());
|
||||
}
|
||||
firePropertyChange("maxVertCachedImgScaling", old, getMaxVertCachedImgScaling());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IAliasable;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
import org.jdesktop.swingx.designer.jibxhelpers.ColorMapper;
|
||||
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.border.MatteBorder;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.BorderFactory;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Color;
|
||||
import org.jdesktop.synthdesigner.synthmodel.PainterBorder;
|
||||
|
||||
/**
|
||||
* BorderMapper - JIBX xml mapper for swing standard borders
|
||||
*
|
||||
* @author Jasper Potts
|
||||
*/
|
||||
public class BorderMapper implements IMarshaller, IUnmarshaller, IAliasable {
|
||||
private static enum BorderType {
|
||||
empty, line, etched, bevel, matte, compound, painter
|
||||
}
|
||||
private static enum SubType {
|
||||
raised(EtchedBorder.RAISED), lowered(EtchedBorder.LOWERED);
|
||||
private int subtype;
|
||||
|
||||
SubType(int type) {
|
||||
this.subtype = type;
|
||||
}
|
||||
|
||||
public int getSubType() {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
private static final String ELEMENT_NAME = "border";
|
||||
private static final String TYPE_NAME = "type";
|
||||
private static final String SUB_TYPE_NAME = "subtype";
|
||||
private static final String TOP_NAME = "top";
|
||||
private static final String BOTTOM_NAME = "bottom";
|
||||
private static final String LEFT_NAME = "left";
|
||||
private static final String RIGHT_NAME = "right";
|
||||
private static final String THICKNESS_NAME = "thickness";
|
||||
private static final String INSIDE_NAME = "inside";
|
||||
private static final String OUTSIDE_NAME = "outside";
|
||||
private static final String PAINTER_NAME = "painter";
|
||||
|
||||
private String uri;
|
||||
private int index;
|
||||
private String name;
|
||||
|
||||
public BorderMapper() {
|
||||
uri = null;
|
||||
index = 0;
|
||||
name = ELEMENT_NAME;
|
||||
}
|
||||
|
||||
public BorderMapper(String uri, int index, String name) {
|
||||
this.uri = uri;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws
|
||||
JiBXException {
|
||||
return iUnmarshallingContext.isAt(uri, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext)
|
||||
throws JiBXException {
|
||||
if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
if (object instanceof PainterBorder) {
|
||||
PainterBorder border = (PainterBorder) object;
|
||||
Insets insets = border.getBorderInsets();
|
||||
ctx.startTagAttributes(index, name)
|
||||
.attribute(index, TYPE_NAME, BorderType.painter.toString())
|
||||
.attribute(index, PAINTER_NAME, border.getPainterName())
|
||||
.attribute(index, TOP_NAME, insets.top)
|
||||
.attribute(index, BOTTOM_NAME, insets.bottom)
|
||||
.attribute(index, LEFT_NAME, insets.left)
|
||||
.attribute(index, RIGHT_NAME, insets.right)
|
||||
.closeStartContent();
|
||||
ctx.endTag(index, name);
|
||||
} else if (object instanceof EmptyBorder) {
|
||||
Insets insets = ((EmptyBorder) object).getBorderInsets();
|
||||
ctx.startTagAttributes(index, name)
|
||||
.attribute(index, TYPE_NAME,
|
||||
BorderType.empty.toString())
|
||||
.attribute(index, TOP_NAME, insets.top)
|
||||
.attribute(index, BOTTOM_NAME, insets.bottom)
|
||||
.attribute(index, LEFT_NAME, insets.left)
|
||||
.attribute(index, RIGHT_NAME, insets.right)
|
||||
.closeStartEmpty();
|
||||
} else if (object instanceof LineBorder) {
|
||||
LineBorder border = (LineBorder) object;
|
||||
ctx.startTagAttributes(index, name).
|
||||
attribute(index, TYPE_NAME, BorderType.line.toString()).
|
||||
attribute(index, THICKNESS_NAME, border.getThickness()).
|
||||
closeStartContent();
|
||||
new ColorMapper().marshal(border.getLineColor(), ctx);
|
||||
ctx.endTag(index, name);
|
||||
} else if (object instanceof EtchedBorder) {
|
||||
EtchedBorder border = (EtchedBorder) object;
|
||||
ctx.startTagAttributes(index, name).
|
||||
attribute(index, TYPE_NAME,
|
||||
BorderType.etched.toString()).
|
||||
attribute(index, SUB_TYPE_NAME,
|
||||
border.getEtchType()==EtchedBorder.RAISED?
|
||||
SubType.raised.toString():
|
||||
SubType.lowered.toString()).
|
||||
closeStartContent();
|
||||
new ColorMapper().marshal(border.getHighlightColor(), ctx);
|
||||
new ColorMapper().marshal(border.getShadowColor(), ctx);
|
||||
ctx.endTag(index, name);
|
||||
} else if (object instanceof BevelBorder) {
|
||||
BevelBorder border = (BevelBorder) object;
|
||||
ctx.startTagAttributes(index, name).
|
||||
attribute(index, TYPE_NAME,
|
||||
BorderType.bevel.toString()).
|
||||
attribute(index, SUB_TYPE_NAME,
|
||||
border.getBevelType()==BevelBorder.RAISED?
|
||||
SubType.raised.toString():
|
||||
SubType.lowered.toString()).
|
||||
closeStartContent();
|
||||
new ColorMapper().marshal(border.getHighlightInnerColor(), ctx);
|
||||
new ColorMapper().marshal(border.getHighlightOuterColor(), ctx);
|
||||
new ColorMapper().marshal(border.getShadowInnerColor(), ctx);
|
||||
new ColorMapper().marshal(border.getHighlightOuterColor(), ctx);
|
||||
ctx.endTag(index, name);
|
||||
} else if (object instanceof MatteBorder) {
|
||||
MatteBorder border = (MatteBorder) object;
|
||||
Insets insets = ((EmptyBorder) object).getBorderInsets();
|
||||
ctx.startTagAttributes(index, name)
|
||||
.attribute(index, TYPE_NAME,
|
||||
BorderType.matte.toString())
|
||||
.attribute(index, TOP_NAME, insets.top)
|
||||
.attribute(index, BOTTOM_NAME, insets.bottom)
|
||||
.attribute(index, LEFT_NAME, insets.left)
|
||||
.attribute(index, RIGHT_NAME, insets.right)
|
||||
.closeStartContent();
|
||||
new ColorMapper().marshal(border.getMatteColor(), ctx);
|
||||
// todo: we should support tiled icons here to be 100% complete
|
||||
ctx.endTag(index, name);
|
||||
} else if (object instanceof CompoundBorder) {
|
||||
CompoundBorder border = (CompoundBorder) object;
|
||||
ctx.startTagAttributes(index, name)
|
||||
.attribute(index, TYPE_NAME,
|
||||
BorderType.compound.toString())
|
||||
.closeStartContent();
|
||||
new BorderMapper(null,0, INSIDE_NAME).marshal(border.getInsideBorder(),ctx);
|
||||
new BorderMapper(null,0, OUTSIDE_NAME).marshal(border.getOutsideBorder(),ctx);
|
||||
ctx.endTag(index, name);
|
||||
} else {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object,
|
||||
IUnmarshallingContext iUnmarshallingContext)
|
||||
throws JiBXException {
|
||||
Border border = null;
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(uri, name)) {
|
||||
ctx.throwStartTagNameError(uri, name);
|
||||
}
|
||||
// get type
|
||||
BorderType type = BorderType.valueOf(ctx.attributeText(uri, TYPE_NAME)
|
||||
.toLowerCase());
|
||||
int top,bottom,left,right;
|
||||
Color color;
|
||||
switch(type){
|
||||
case empty:
|
||||
top = ctx.attributeInt(uri, TOP_NAME, index);
|
||||
bottom = ctx.attributeInt(uri, BOTTOM_NAME, index);
|
||||
left = ctx.attributeInt(uri, LEFT_NAME, index);
|
||||
right = ctx.attributeInt(uri, RIGHT_NAME, index);
|
||||
border = BorderFactory.createEmptyBorder(top,left,bottom,right);
|
||||
break;
|
||||
case line:
|
||||
int thickness = ctx.attributeInt(uri, THICKNESS_NAME, index);
|
||||
ctx.parsePastStartTag(uri,name);
|
||||
color = (Color)new ColorMapper().unmarshal(null,ctx);
|
||||
border = BorderFactory.createLineBorder(color,thickness);
|
||||
break;
|
||||
case etched:
|
||||
SubType etchedType = SubType.valueOf(
|
||||
ctx.attributeText(uri, SUB_TYPE_NAME).toLowerCase());
|
||||
ctx.parsePastStartTag(uri,name);
|
||||
Color highColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
Color shadowColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
border = BorderFactory.createEtchedBorder(
|
||||
etchedType.getSubType(),highColor,shadowColor);
|
||||
break;
|
||||
case bevel:
|
||||
SubType bevelType = SubType.valueOf(
|
||||
ctx.attributeText(uri, SUB_TYPE_NAME).toLowerCase());
|
||||
ctx.parsePastStartTag(uri,name);
|
||||
Color innerHighColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
Color outerHighColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
Color innerShadowColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
Color outerShadowColor = (Color)new ColorMapper()
|
||||
.unmarshal(null,ctx);
|
||||
border = BorderFactory.createBevelBorder(
|
||||
bevelType.getSubType(),outerHighColor,innerHighColor,
|
||||
outerShadowColor,innerShadowColor);
|
||||
break;
|
||||
case matte:
|
||||
top = ctx.attributeInt(uri, TOP_NAME, index);
|
||||
bottom = ctx.attributeInt(uri, BOTTOM_NAME, index);
|
||||
left = ctx.attributeInt(uri, LEFT_NAME, index);
|
||||
right = ctx.attributeInt(uri, RIGHT_NAME, index);
|
||||
ctx.parsePastStartTag(uri,name);
|
||||
color = (Color)new ColorMapper().unmarshal(null,ctx);
|
||||
border = BorderFactory.createMatteBorder(top,left,bottom,right,
|
||||
color);
|
||||
break;
|
||||
case compound:
|
||||
ctx.parsePastStartTag(uri,name);
|
||||
Border inside = (Border) new BorderMapper(null,0, INSIDE_NAME)
|
||||
.unmarshal(null,ctx);
|
||||
Border outside = (Border) new BorderMapper(null,0, OUTSIDE_NAME)
|
||||
.unmarshal(null,ctx);
|
||||
border = BorderFactory.createCompoundBorder(outside, inside);
|
||||
break;
|
||||
case painter:
|
||||
String painterName = ctx.attributeText(uri, PAINTER_NAME);
|
||||
top = ctx.attributeInt(uri, TOP_NAME, index);
|
||||
bottom = ctx.attributeInt(uri, BOTTOM_NAME, index);
|
||||
left = ctx.attributeInt(uri, LEFT_NAME, index);
|
||||
right = ctx.attributeInt(uri, RIGHT_NAME, index);
|
||||
border = new PainterBorder(painterName, top, left, bottom, right);
|
||||
}
|
||||
ctx.parsePastEndTag(uri, name);
|
||||
return border;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
/**
|
||||
* ClassConverter
|
||||
*
|
||||
* @author Created by Jasper Potts (Jul 16, 2007)
|
||||
*/
|
||||
public class ClassConverter {
|
||||
|
||||
public static String classToString(Class c) {
|
||||
return c == null ? "" : c.getName();
|
||||
}
|
||||
|
||||
public static Class stringToClass(String className) {
|
||||
if (className == null || className.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (classLoader == null) classLoader = ClassConverter.class.getClassLoader();
|
||||
return classLoader.loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Failed to find class with name [" + className + "] in ClassConverter");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
|
||||
public class ClassMapper implements IMarshaller, IUnmarshaller {
|
||||
private static final String ELEMENT_NAME = "type";
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Class)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
Class clazz = (Class) object;
|
||||
ctx.startTagAttributes(0, ELEMENT_NAME).
|
||||
attribute(0, "value", clazz.getName()).
|
||||
closeStartEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(null, ELEMENT_NAME)) {
|
||||
ctx.throwStartTagNameError(null, ELEMENT_NAME);
|
||||
}
|
||||
// get values
|
||||
String value = ctx.attributeText(null, "value", null);
|
||||
ctx.parsePastEndTag(null, ELEMENT_NAME);
|
||||
// create
|
||||
try {
|
||||
return Class.forName(value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* FontMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jun 8, 2007)
|
||||
*/
|
||||
public class FontMapper implements IMarshaller, IUnmarshaller {
|
||||
private static final String ELEMENT_NAME = "font";
|
||||
private static final String FAMILY_NAME = "family";
|
||||
private static final String STYLE_NAME = "style";
|
||||
private static final String SIZE_NAME = "size";
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof Font)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
Font font = (Font) object;
|
||||
ctx.startTagAttributes(0, ELEMENT_NAME).
|
||||
attribute(0, FAMILY_NAME, font.getFamily()).
|
||||
attribute(0, STYLE_NAME, font.getStyle()).
|
||||
attribute(0, SIZE_NAME, font.getSize()).
|
||||
closeStartEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(null, ELEMENT_NAME)) {
|
||||
ctx.throwStartTagNameError(null, ELEMENT_NAME);
|
||||
}
|
||||
// get values
|
||||
String name = ctx.attributeText(null, FAMILY_NAME, null);
|
||||
int style = ctx.attributeInt(null, STYLE_NAME, 0);
|
||||
int size = ctx.attributeInt(null, SIZE_NAME, 0);
|
||||
ctx.parsePastEndTag(null, ELEMENT_NAME);
|
||||
// create
|
||||
return new Font(name, style, size);
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.jibxhelpers;
|
||||
|
||||
import org.jdesktop.swingx.designer.jibxhelpers.DimensionMapper;
|
||||
import org.jdesktop.swingx.designer.jibxhelpers.InsetsMapper;
|
||||
import org.jdesktop.synthdesigner.synthmodel.UIProperty;
|
||||
import org.jibx.runtime.IMarshallable;
|
||||
import org.jibx.runtime.IMarshaller;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshaller;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
import org.jibx.runtime.impl.MarshallingContext;
|
||||
import org.jibx.runtime.impl.UnmarshallingContext;
|
||||
|
||||
/**
|
||||
* UIPropertyMapper
|
||||
*
|
||||
* @author Created by Jasper Potts (Jul 10, 2007)
|
||||
*/
|
||||
public class UIPropertyMapper implements IMarshaller, IUnmarshaller {
|
||||
private static final String ELEMENT_NAME = "uiProperty";
|
||||
private static final String NAME_NAME = "name";
|
||||
private static final String TYPE_NAME = "type";
|
||||
private static final String VALUE_NAME = "value";
|
||||
|
||||
public boolean isExtension(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPresent(IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
return iUnmarshallingContext.isAt(null, ELEMENT_NAME);
|
||||
}
|
||||
|
||||
public void marshal(Object object, IMarshallingContext iMarshallingContext) throws JiBXException {
|
||||
if (!(object instanceof UIProperty)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else if (!(iMarshallingContext instanceof MarshallingContext)) {
|
||||
throw new JiBXException("Invalid object type for marshaller");
|
||||
} else {
|
||||
MarshallingContext ctx = (MarshallingContext) iMarshallingContext;
|
||||
UIProperty property = (UIProperty) object;
|
||||
ctx.startTagAttributes(0, ELEMENT_NAME);
|
||||
ctx.attribute(0, NAME_NAME, property.getName());
|
||||
ctx.attribute(0, TYPE_NAME, property.getType().toString());
|
||||
switch (property.getType()) {
|
||||
case BOOLEAN:
|
||||
case DOUBLE:
|
||||
case INT:
|
||||
case FLOAT:
|
||||
case STRING:
|
||||
ctx.attribute(0, VALUE_NAME, property.getValue().toString());
|
||||
ctx.closeStartEmpty();
|
||||
break;
|
||||
case INSETS:
|
||||
ctx.closeStartContent();
|
||||
new InsetsMapper().marshal(property.getValue(), ctx);
|
||||
ctx.endTag(0, ELEMENT_NAME);
|
||||
break;
|
||||
case COLOR:
|
||||
case FONT:
|
||||
ctx.closeStartContent();
|
||||
if (property.getValue() instanceof IMarshallable) {
|
||||
((IMarshallable) property.getValue()).marshal(ctx);
|
||||
} else {
|
||||
throw new JiBXException("Mapped value is not marshallable");
|
||||
}
|
||||
ctx.endTag(0, ELEMENT_NAME);
|
||||
break;
|
||||
case DIMENSION:
|
||||
ctx.closeStartContent();
|
||||
new DimensionMapper().marshal(property.getValue(), ctx);
|
||||
ctx.endTag(0, ELEMENT_NAME);
|
||||
break;
|
||||
case BORDER:
|
||||
ctx.closeStartContent();
|
||||
new BorderMapper().marshal(property.getValue(), ctx);
|
||||
ctx.endTag(0, ELEMENT_NAME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object unmarshal(Object object, IUnmarshallingContext iUnmarshallingContext) throws JiBXException {
|
||||
// make sure we're at the appropriate start tag
|
||||
UnmarshallingContext ctx = (UnmarshallingContext) iUnmarshallingContext;
|
||||
if (!ctx.isAt(null, ELEMENT_NAME)) {
|
||||
ctx.throwStartTagNameError(null, ELEMENT_NAME);
|
||||
}
|
||||
// get values
|
||||
Object value = null;
|
||||
String name = ctx.attributeText(null, NAME_NAME, null);
|
||||
UIProperty.PropertyType type = UIProperty.PropertyType.valueOf(ctx.attributeText(null, TYPE_NAME, null));
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
value = Boolean.parseBoolean(ctx.attributeText(null, VALUE_NAME, null));
|
||||
break;
|
||||
case DOUBLE:
|
||||
value = Double.parseDouble(ctx.attributeText(null, VALUE_NAME, null));
|
||||
break;
|
||||
case INT:
|
||||
value = Integer.parseInt(ctx.attributeText(null, VALUE_NAME, null));
|
||||
break;
|
||||
case FLOAT:
|
||||
value = Float.parseFloat(ctx.attributeText(null, VALUE_NAME, null));
|
||||
break;
|
||||
case STRING:
|
||||
value = ctx.attributeText(null, VALUE_NAME, null);
|
||||
break;
|
||||
case INSETS:
|
||||
ctx.parsePastStartTag(null, ELEMENT_NAME);
|
||||
value = new InsetsMapper().unmarshal(value, ctx);
|
||||
break;
|
||||
case COLOR:
|
||||
case FONT:
|
||||
ctx.parsePastStartTag(null, ELEMENT_NAME);
|
||||
value = ctx.unmarshalElement();
|
||||
break;
|
||||
case DIMENSION:
|
||||
ctx.parsePastStartTag(null, ELEMENT_NAME);
|
||||
value = new DimensionMapper().unmarshal(value, ctx);
|
||||
break;
|
||||
case BORDER:
|
||||
ctx.parsePastStartTag(null, ELEMENT_NAME);
|
||||
value = new BorderMapper().unmarshal(value, ctx);
|
||||
break;
|
||||
}
|
||||
ctx.parsePastEndTag(null, ELEMENT_NAME);
|
||||
// create
|
||||
return new UIProperty(name, type, value);
|
||||
}
|
||||
}
|
33
jdk/src/share/classes/com/sun/java/swing/Painter.java
Normal file
33
jdk/src/share/classes/com/sun/java/swing/Painter.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 com.sun.java.swing;
|
||||
|
||||
/**
|
||||
* This class is preserved for backward compatibility with JDK 6.
|
||||
*
|
||||
* @deprecated Use {@link javax.swing.Painter} instead.
|
||||
*/
|
||||
public interface Painter<T> extends javax.swing.Painter {
|
||||
}
|
@ -134,6 +134,15 @@ class GTKFileChooserUI extends SynthFileChooserUI {
|
||||
super(filechooser);
|
||||
}
|
||||
|
||||
protected 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;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
JFileChooser fc = getFileChooser();
|
||||
String typedInName = fileNameTextField != null ?
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 com.sun.java.swing.plaf.nimbus;
|
||||
|
||||
/**
|
||||
* This class is preserved for backward compatibility with JDK 6.
|
||||
*
|
||||
* @deprecated Use {@link javax.swing.plaf.nimbus.AbstractRegionPainter} instead.
|
||||
*/
|
||||
public abstract class AbstractRegionPainter extends javax.swing.plaf.nimbus.AbstractRegionPainter {
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 com.sun.java.swing.plaf.nimbus;
|
||||
|
||||
/**
|
||||
* This class is preserved for backward compatibility with JDK 6.
|
||||
*
|
||||
* @deprecated Use {@link javax.swing.plaf.nimbus.NimbusLookAndFeel} instead.
|
||||
*/
|
||||
public class NimbusLookAndFeel extends javax.swing.plaf.nimbus.NimbusLookAndFeel {
|
||||
}
|
@ -1009,6 +1009,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
|
||||
"PopupMenu.background", MenuBackgroundColor,
|
||||
"PopupMenu.foreground", MenuTextColor,
|
||||
"PopupMenu.popupSound", "win.sound.menuPopup",
|
||||
"PopupMenu.consumeEventOnClose", Boolean.TRUE,
|
||||
|
||||
// Menus
|
||||
"Menu.font", MenuFont,
|
||||
|
@ -54,6 +54,7 @@ public class SoftAudioPusher implements Runnable {
|
||||
return;
|
||||
active = true;
|
||||
audiothread = new Thread(this);
|
||||
audiothread.setDaemon(true);
|
||||
audiothread.setPriority(Thread.MAX_PRIORITY);
|
||||
audiothread.start();
|
||||
}
|
||||
|
@ -93,7 +93,6 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
protected double portamento_time = 1; // keyschanges per control buffer time
|
||||
protected int[] portamento_lastnote = new int[128];
|
||||
protected int portamento_lastnote_ix = 0;
|
||||
private int portamento_control_note = -1;
|
||||
private boolean portamento = false;
|
||||
private boolean mono = false;
|
||||
private boolean mute = false;
|
||||
@ -369,12 +368,12 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
voice.setSoloMute(solomute);
|
||||
if (releaseTriggered)
|
||||
return;
|
||||
if (portamento_control_note != -1) {
|
||||
if (controller[84] != 0) {
|
||||
voice.co_noteon_keynumber[0]
|
||||
= (tuning.getTuning(portamento_control_note) / 100.0)
|
||||
= (tuning.getTuning(controller[84]) / 100.0)
|
||||
* (1f / 128f);
|
||||
voice.portamento = true;
|
||||
portamento_control_note = -1;
|
||||
controlChange(84, 0);
|
||||
} else if (portamento) {
|
||||
if (mono) {
|
||||
if (portamento_lastnote[0] != -1) {
|
||||
@ -382,7 +381,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
= (tuning.getTuning(portamento_lastnote[0]) / 100.0)
|
||||
* (1f / 128f);
|
||||
voice.portamento = true;
|
||||
portamento_control_note = -1;
|
||||
controlChange(84, 0);
|
||||
}
|
||||
portamento_lastnote[0] = noteNumber;
|
||||
} else {
|
||||
@ -449,19 +448,19 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
if (portamento_control_note != -1) {
|
||||
if (controller[84] != 0) {
|
||||
boolean n_found = false;
|
||||
for (int i = 0; i < voices.length; i++) {
|
||||
if (voices[i].on && voices[i].channel == channel
|
||||
&& voices[i].active
|
||||
&& voices[i].note == portamento_control_note
|
||||
&& voices[i].note == controller[84]
|
||||
&& voices[i].releaseTriggered == false) {
|
||||
voices[i].portamento = true;
|
||||
voices[i].setNote(noteNumber);
|
||||
n_found = true;
|
||||
}
|
||||
}
|
||||
portamento_control_note = -1;
|
||||
controlChange(84, 0);
|
||||
if (n_found)
|
||||
return;
|
||||
}
|
||||
@ -556,6 +555,18 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
&& voices[i].releaseTriggered == false) {
|
||||
voices[i].noteOff(velocity);
|
||||
}
|
||||
// We must also check stolen voices
|
||||
if (voices[i].stealer_channel == this && voices[i].stealer_noteNumber == noteNumber) {
|
||||
SoftVoice v = voices[i];
|
||||
v.stealer_releaseTriggered = false;
|
||||
v.stealer_channel = null;
|
||||
v.stealer_performer = null;
|
||||
v.stealer_voiceID = -1;
|
||||
v.stealer_noteNumber = 0;
|
||||
v.stealer_velocity = 0;
|
||||
v.stealer_extendedConnectionBlocks = null;
|
||||
v.stealer_channelmixer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Try play back note-off triggered voices,
|
||||
@ -1141,9 +1152,6 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 84:
|
||||
portamento_control_note = value;
|
||||
break;
|
||||
case 98:
|
||||
nrpn_control = (nrpn_control & (127 << 7)) + value;
|
||||
rpn_control = RPN_NULL_VALUE;
|
||||
|
@ -38,11 +38,11 @@ public class SoftChorus implements SoftAudioProcessor {
|
||||
|
||||
private float[] delaybuffer;
|
||||
private int rovepos = 0;
|
||||
private volatile float gain = 1;
|
||||
private volatile float rgain = 0;
|
||||
private volatile float delay = 0;
|
||||
private float gain = 1;
|
||||
private float rgain = 0;
|
||||
private float delay = 0;
|
||||
private float lastdelay = 0;
|
||||
private volatile float feedback = 0;
|
||||
private float feedback = 0;
|
||||
|
||||
public VariableDelay(int maxbuffersize) {
|
||||
delaybuffer = new float[maxbuffersize];
|
||||
@ -115,10 +115,8 @@ public class SoftChorus implements SoftAudioProcessor {
|
||||
|
||||
private static class LFODelay {
|
||||
|
||||
private volatile double c_cos_delta;
|
||||
private volatile double c_sin_delta;
|
||||
private double c_cos = 1;
|
||||
private double c_sin = 0;
|
||||
private double phase = 1;
|
||||
private double phase_step = 0;
|
||||
private double depth = 0;
|
||||
private VariableDelay vdelay;
|
||||
private double samplerate;
|
||||
@ -139,13 +137,11 @@ public class SoftChorus implements SoftAudioProcessor {
|
||||
|
||||
public void setRate(double rate) {
|
||||
double g = (Math.PI * 2) * (rate / controlrate);
|
||||
c_cos_delta = Math.cos(g);
|
||||
c_sin_delta = Math.sin(g);
|
||||
phase_step = g;
|
||||
}
|
||||
|
||||
public void setPhase(double phase) {
|
||||
c_cos = Math.cos(phase);
|
||||
c_sin = Math.sin(phase);
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
public void setFeedBack(float feedback) {
|
||||
@ -161,16 +157,16 @@ public class SoftChorus implements SoftAudioProcessor {
|
||||
}
|
||||
|
||||
public void processMix(float[] in, float[] out, float[] rout) {
|
||||
c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
|
||||
c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
|
||||
vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
|
||||
phase += phase_step;
|
||||
while(phase > (Math.PI * 2)) phase -= (Math.PI * 2);
|
||||
vdelay.setDelay((float) (depth * 0.5 * (Math.cos(phase) + 2)));
|
||||
vdelay.processMix(in, out, rout);
|
||||
}
|
||||
|
||||
public void processReplace(float[] in, float[] out, float[] rout) {
|
||||
c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
|
||||
c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
|
||||
vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
|
||||
phase += phase_step;
|
||||
while(phase > (Math.PI * 2)) phase -= (Math.PI * 2);
|
||||
vdelay.setDelay((float) (depth * 0.5 * (Math.cos(phase) + 2)));
|
||||
vdelay.processReplace(in, out, rout);
|
||||
|
||||
}
|
||||
|
@ -543,8 +543,6 @@ public class SoftFilter {
|
||||
|
||||
public void filter1(SoftAudioBuffer sbuffer) {
|
||||
|
||||
float[] buffer = sbuffer.array();
|
||||
|
||||
if (dirty) {
|
||||
filter1calc();
|
||||
dirty = false;
|
||||
@ -559,6 +557,7 @@ public class SoftFilter {
|
||||
|
||||
if (wet > 0 || last_wet > 0) {
|
||||
|
||||
float[] buffer = sbuffer.array();
|
||||
int len = buffer.length;
|
||||
float a0 = this.last_a0;
|
||||
float q = this.last_q;
|
||||
@ -577,14 +576,16 @@ public class SoftFilter {
|
||||
q += q_delta;
|
||||
gain += gain_delta;
|
||||
wet += wet_delta;
|
||||
y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
|
||||
y2 = (1 - q * a0) * y2 + (a0) * y1;
|
||||
float ga0 = (1 - q * a0);
|
||||
y1 = ga0 * y1 + (a0) * (buffer[i] - y2);
|
||||
y2 = ga0 * y2 + (a0) * y1;
|
||||
buffer[i] = y2 * gain * wet + buffer[i] * (1 - wet);
|
||||
}
|
||||
} else if (a0_delta == 0 && q_delta == 0) {
|
||||
float ga0 = (1 - q * a0);
|
||||
for (int i = 0; i < len; i++) {
|
||||
y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
|
||||
y2 = (1 - q * a0) * y2 + (a0) * y1;
|
||||
y1 = ga0 * y1 + (a0) * (buffer[i] - y2);
|
||||
y2 = ga0 * y2 + (a0) * y1;
|
||||
buffer[i] = y2 * gain;
|
||||
}
|
||||
} else {
|
||||
@ -592,8 +593,9 @@ public class SoftFilter {
|
||||
a0 += a0_delta;
|
||||
q += q_delta;
|
||||
gain += gain_delta;
|
||||
y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
|
||||
y2 = (1 - q * a0) * y2 + (a0) * y1;
|
||||
float ga0 = (1 - q * a0);
|
||||
y1 = ga0 * y1 + (a0) * (buffer[i] - y2);
|
||||
y2 = ga0 * y2 + (a0) * y1;
|
||||
buffer[i] = y2 * gain;
|
||||
}
|
||||
}
|
||||
|
@ -216,6 +216,7 @@ public class SoftJitterCorrector extends AudioInputStream {
|
||||
};
|
||||
|
||||
thread = new Thread(runnable);
|
||||
thread.setDaemon(true);
|
||||
thread.setPriority(Thread.MAX_PRIORITY);
|
||||
thread.start();
|
||||
}
|
||||
|
@ -45,6 +45,13 @@ public class SoftLowFrequencyOscillator implements SoftProcess {
|
||||
private double sin_factor = 0;
|
||||
private static double PI2 = 2.0 * Math.PI;
|
||||
|
||||
public SoftLowFrequencyOscillator() {
|
||||
// If sin_step is 0 then sin_stepfreq must be -INF
|
||||
for (int i = 0; i < sin_stepfreq.length; i++) {
|
||||
sin_stepfreq[i] = Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (int i = 0; i < used_count; i++) {
|
||||
out[i][0] = 0;
|
||||
@ -53,7 +60,8 @@ public class SoftLowFrequencyOscillator implements SoftProcess {
|
||||
freq[i][0] = 0;
|
||||
delay_counter[i] = 0;
|
||||
sin_phase[i] = 0;
|
||||
sin_stepfreq[i] = 0;
|
||||
// If sin_step is 0 then sin_stepfreq must be -INF
|
||||
sin_stepfreq[i] = Double.NEGATIVE_INFINITY;
|
||||
sin_step[i] = 0;
|
||||
}
|
||||
used_count = 0;
|
||||
|
@ -48,16 +48,18 @@ public class SoftMainMixer {
|
||||
|
||||
public final static int CHANNEL_LEFT = 0;
|
||||
public final static int CHANNEL_RIGHT = 1;
|
||||
public final static int CHANNEL_EFFECT1 = 2;
|
||||
public final static int CHANNEL_EFFECT2 = 3;
|
||||
public final static int CHANNEL_EFFECT3 = 4;
|
||||
public final static int CHANNEL_EFFECT4 = 5;
|
||||
public final static int CHANNEL_MONO = 2;
|
||||
public final static int CHANNEL_EFFECT1 = 3;
|
||||
public final static int CHANNEL_EFFECT2 = 4;
|
||||
public final static int CHANNEL_EFFECT3 = 5;
|
||||
public final static int CHANNEL_EFFECT4 = 6;
|
||||
public final static int CHANNEL_LEFT_DRY = 10;
|
||||
public final static int CHANNEL_RIGHT_DRY = 11;
|
||||
public final static int CHANNEL_SCRATCH1 = 12;
|
||||
public final static int CHANNEL_SCRATCH2 = 13;
|
||||
public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
|
||||
public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
|
||||
public final static int CHANNEL_CHANNELMIXER_MONO = 16;
|
||||
protected boolean active_sensing_on = false;
|
||||
private long msec_last_activity = -1;
|
||||
private boolean pusher_silent = false;
|
||||
@ -485,8 +487,10 @@ public class SoftMainMixer {
|
||||
// to channelmixer left,right input/output
|
||||
SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
|
||||
SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
|
||||
SoftAudioBuffer monobak = buffers[CHANNEL_MONO];
|
||||
buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
|
||||
buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
|
||||
buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_RIGHT];
|
||||
buffers[CHANNEL_MONO] = buffers[CHANNEL_CHANNELMIXER_MONO];
|
||||
|
||||
int bufferlen = buffers[CHANNEL_LEFT].getSize();
|
||||
|
||||
@ -503,6 +507,7 @@ public class SoftMainMixer {
|
||||
for (ModelChannelMixer cmixer : act_registeredMixers) {
|
||||
for (int i = 0; i < cbuffer.length; i++)
|
||||
Arrays.fill(cbuffer[i], 0);
|
||||
buffers[CHANNEL_MONO].clear();
|
||||
boolean hasactivevoices = false;
|
||||
for (int i = 0; i < voicestatus.length; i++)
|
||||
if (voicestatus[i].active)
|
||||
@ -517,6 +522,26 @@ public class SoftMainMixer {
|
||||
}
|
||||
}
|
||||
|
||||
if(!buffers[CHANNEL_MONO].isSilent())
|
||||
{
|
||||
float[] mono = buffers[CHANNEL_MONO].array();
|
||||
float[] left = buffers[CHANNEL_LEFT].array();
|
||||
if (nrofchannels != 1) {
|
||||
float[] right = buffers[CHANNEL_RIGHT].array();
|
||||
for (int i = 0; i < bufferlen; i++) {
|
||||
float v = mono[i];
|
||||
left[i] += v;
|
||||
right[i] += v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < bufferlen; i++) {
|
||||
left[i] += mono[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cbuffer.length; i++) {
|
||||
float[] cbuff = cbuffer[i];
|
||||
float[] obuff = obuffer[i];
|
||||
@ -539,6 +564,7 @@ public class SoftMainMixer {
|
||||
|
||||
buffers[CHANNEL_LEFT] = leftbak;
|
||||
buffers[CHANNEL_RIGHT] = rightbak;
|
||||
buffers[CHANNEL_MONO] = monobak;
|
||||
|
||||
}
|
||||
|
||||
@ -547,6 +573,27 @@ public class SoftMainMixer {
|
||||
if (voicestatus[i].channelmixer == null)
|
||||
voicestatus[i].processAudioLogic(buffers);
|
||||
|
||||
if(!buffers[CHANNEL_MONO].isSilent())
|
||||
{
|
||||
float[] mono = buffers[CHANNEL_MONO].array();
|
||||
float[] left = buffers[CHANNEL_LEFT].array();
|
||||
int bufferlen = buffers[CHANNEL_LEFT].getSize();
|
||||
if (nrofchannels != 1) {
|
||||
float[] right = buffers[CHANNEL_RIGHT].array();
|
||||
for (int i = 0; i < bufferlen; i++) {
|
||||
float v = mono[i];
|
||||
left[i] += v;
|
||||
right[i] += v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < bufferlen; i++) {
|
||||
left[i] += mono[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run effects
|
||||
if (synth.chorus_on)
|
||||
chorus.processAudio();
|
||||
@ -665,7 +712,7 @@ public class SoftMainMixer {
|
||||
/ synth.getControlRate());
|
||||
|
||||
control_mutex = synth.control_mutex;
|
||||
buffers = new SoftAudioBuffer[16];
|
||||
buffers = new SoftAudioBuffer[17];
|
||||
for (int i = 0; i < buffers.length; i++) {
|
||||
buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
|
||||
}
|
||||
|
@ -889,9 +889,12 @@ public class SoftSynthesizer implements AudioSynthesizer,
|
||||
return;
|
||||
}
|
||||
synchronized (control_mutex) {
|
||||
Throwable causeException = null;
|
||||
try {
|
||||
if (line != null)
|
||||
if (line != null) {
|
||||
// can throw IllegalArgumentException
|
||||
setFormat(line.getFormat());
|
||||
}
|
||||
|
||||
AudioInputStream ais = openStream(getFormat(), info);
|
||||
|
||||
@ -900,10 +903,13 @@ public class SoftSynthesizer implements AudioSynthesizer,
|
||||
|
||||
if (line == null)
|
||||
{
|
||||
if(testline != null)
|
||||
if (testline != null) {
|
||||
line = testline;
|
||||
else
|
||||
} else {
|
||||
// can throw LineUnavailableException,
|
||||
// IllegalArgumentException, SecurityException
|
||||
line = AudioSystem.getSourceDataLine(getFormat());
|
||||
}
|
||||
}
|
||||
|
||||
double latency = this.latency;
|
||||
@ -911,6 +917,8 @@ public class SoftSynthesizer implements AudioSynthesizer,
|
||||
if (!line.isOpen()) {
|
||||
int bufferSize = getFormat().getFrameSize()
|
||||
* (int)(getFormat().getFrameRate() * (latency/1000000f));
|
||||
// can throw LineUnavailableException,
|
||||
// IllegalArgumentException, SecurityException
|
||||
line.open(getFormat(), bufferSize);
|
||||
|
||||
// Remember that we opened that line
|
||||
@ -954,13 +962,22 @@ public class SoftSynthesizer implements AudioSynthesizer,
|
||||
weakstream.sourceDataLine = sourceDataLine;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch (LineUnavailableException e) {
|
||||
causeException = e;
|
||||
} catch (IllegalArgumentException e) {
|
||||
causeException = e;
|
||||
} catch (SecurityException e) {
|
||||
causeException = e;
|
||||
}
|
||||
|
||||
if (causeException != null) {
|
||||
if (isOpen())
|
||||
close();
|
||||
// am: need MidiUnavailableException(Throwable) ctor!
|
||||
throw new MidiUnavailableException(e.toString());
|
||||
MidiUnavailableException ex = new MidiUnavailableException(
|
||||
"Can not open line");
|
||||
ex.initCause(causeException);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -782,6 +782,7 @@ public class SoftVoice extends VoiceStatus {
|
||||
|
||||
SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT];
|
||||
SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT];
|
||||
SoftAudioBuffer mono = buffer[SoftMainMixer.CHANNEL_MONO];
|
||||
SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
|
||||
SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];
|
||||
SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
|
||||
@ -803,13 +804,22 @@ public class SoftVoice extends VoiceStatus {
|
||||
mixAudioStream(rightdry, left, last_out_mixer_left,
|
||||
out_mixer_left);
|
||||
} else {
|
||||
mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
|
||||
if (rightdry != null)
|
||||
mixAudioStream(rightdry, right, last_out_mixer_right,
|
||||
out_mixer_right);
|
||||
if(rightdry == null &&
|
||||
last_out_mixer_left == last_out_mixer_right &&
|
||||
out_mixer_left == out_mixer_right)
|
||||
{
|
||||
mixAudioStream(leftdry, mono, last_out_mixer_left, out_mixer_left);
|
||||
}
|
||||
else
|
||||
mixAudioStream(leftdry, right, last_out_mixer_right,
|
||||
{
|
||||
mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
|
||||
if (rightdry != null)
|
||||
mixAudioStream(rightdry, right, last_out_mixer_right,
|
||||
out_mixer_right);
|
||||
else
|
||||
mixAudioStream(leftdry, right, last_out_mixer_right,
|
||||
out_mixer_right);
|
||||
}
|
||||
}
|
||||
|
||||
if (rightdry == null) {
|
||||
|
@ -687,7 +687,7 @@ public class Color implements Paint, java.io.Serializable {
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Color && ((Color)obj).value == this.value;
|
||||
return obj instanceof Color && ((Color)obj).getRGB() == this.getRGB();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,6 +102,29 @@ public class MetaMessage extends MidiMessage {
|
||||
this(defaultMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code MetaMessage} and sets the message parameters.
|
||||
* The contents of the message can be changed by using
|
||||
* the {@code setMessage} method.
|
||||
*
|
||||
* @param type meta-message type (must be less than 128)
|
||||
* @param data the data bytes in the MIDI message
|
||||
* @param length an amount of bytes in the {@code data} byte 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(int, byte[], int)
|
||||
* @see #getType()
|
||||
* @see #getData()
|
||||
* @since 1.7
|
||||
*/
|
||||
public MetaMessage(int type, byte[] data, int length)
|
||||
throws InvalidMidiDataException {
|
||||
super(null);
|
||||
setMessage(type, data, length); // can throw InvalidMidiDataException
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new <code>MetaMessage</code>.
|
||||
|
@ -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 <code>ShortMessage</code>.
|
||||
|
@ -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 <code>SysexMessage</code>.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,15 @@ public abstract class MixerProvider {
|
||||
/**
|
||||
* Indicates whether the mixer provider supports the mixer represented by
|
||||
* the specified mixer info object.
|
||||
* <p>
|
||||
* 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 <code>true</code> if the specified mixer is supported,
|
||||
* otherwise <code>false</code>
|
||||
* @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
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user