changeset 1173:7f45fcc04f8e

6591875: Nimbus Swing Look and Feel Reviewed-by: jasper, ohair
author peterz
date Sat, 25 Apr 2009 21:17:50 +0400
parents 5ac8b97ffabd
children 8df0db057762
files README make/common/Sanity.gmk make/common/shared/Defs.gmk make/common/shared/Platform.gmk make/common/shared/Sanity-Settings.gmk make/common/shared/Sanity.gmk make/javax/swing/plaf/Makefile make/javax/swing/plaf/nimbus/Makefile make/tools/Makefile make/tools/swing-nimbus/Makefile make/tools/swing-nimbus/classes/org/jdesktop/beans/AbstractBean.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BezierControlPoint.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BlendingMode.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Canvas.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/ControlPoint.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Designer.jibx.xml make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/DoubleBean.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/EllipseShape.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/GraphicsHelper.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Layer.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/LayerContainer.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/PaintedShape.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/PathShape.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/RectangleShape.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/SimpleShape.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/TemplateLayer.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/DropShadowEffect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/Effect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/EffectUtils.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/EffectUtilsTemp.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/InnerGlowEffect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/InnerShadowEffect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/OuterGlowEffect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/ShadowEffect.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/font/Typeface.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/CanvasMapper.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/ColorMapper.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/DimensionMapper.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/InsetsMapper.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/AbstractGradient.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Gradient.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/GradientStop.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Matte.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/PaintModel.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/RadialGradient.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Texture.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasPath.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasResources.java make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasUIDefaults.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/Generator.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/GeneratorUtils.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/ObjectCodeConvertors.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/PainterGenerator.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/TemplateWriter.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/CustomUIDefault.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/HasUIStyle.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/PainterBorder.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/SynthModel.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/SynthModel.jibx.xml make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIBorder.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIColor.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIComponent.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIDefault.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIDimension.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIFont.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIIcon.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIIconRegion.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIInsets.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIPaint.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIProperty.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIRegion.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIState.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIStateType.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/UIStyle.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/jibxhelpers/BorderMapper.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/jibxhelpers/ClassConverter.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/jibxhelpers/ClassMapper.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/jibxhelpers/FontMapper.java make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/synthmodel/jibxhelpers/UIPropertyMapper.java src/share/classes/com/sun/java/swing/Painter.java src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java src/share/classes/com/sun/java/swing/plaf/nimbus/AbstractRegionPainter.java src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java src/share/classes/java/awt/Color.java src/share/classes/javax/swing/DefaultCellEditor.java src/share/classes/javax/swing/DefaultListCellRenderer.java src/share/classes/javax/swing/JComboBox.java src/share/classes/javax/swing/JScrollPane.java src/share/classes/javax/swing/JSpinner.java src/share/classes/javax/swing/JSplitPane.java src/share/classes/javax/swing/JTable.java src/share/classes/javax/swing/MultiUIDefaults.java src/share/classes/javax/swing/Painter.java src/share/classes/javax/swing/UIManager.java src/share/classes/javax/swing/border/TitledBorder.java src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java src/share/classes/javax/swing/plaf/basic/BasicListUI.java src/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java src/share/classes/javax/swing/plaf/basic/BasicProgressBarUI.java src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java src/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java src/share/classes/javax/swing/plaf/basic/BasicTableUI.java src/share/classes/javax/swing/plaf/basic/BasicTextUI.java src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java src/share/classes/javax/swing/plaf/nimbus/Defaults.template src/share/classes/javax/swing/plaf/nimbus/DerivedColor.java src/share/classes/javax/swing/plaf/nimbus/DropShadowEffect.java src/share/classes/javax/swing/plaf/nimbus/Effect.java src/share/classes/javax/swing/plaf/nimbus/EffectUtils.java src/share/classes/javax/swing/plaf/nimbus/ImageCache.java src/share/classes/javax/swing/plaf/nimbus/ImageScalingHelper.java src/share/classes/javax/swing/plaf/nimbus/InnerGlowEffect.java src/share/classes/javax/swing/plaf/nimbus/InnerShadowEffect.java src/share/classes/javax/swing/plaf/nimbus/LoweredBorder.java src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java src/share/classes/javax/swing/plaf/nimbus/OuterGlowEffect.java src/share/classes/javax/swing/plaf/nimbus/PainterImpl.template src/share/classes/javax/swing/plaf/nimbus/ShadowEffect.java src/share/classes/javax/swing/plaf/nimbus/State.java src/share/classes/javax/swing/plaf/nimbus/StateImpl.template src/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java src/share/classes/javax/swing/plaf/nimbus/TableScrollPaneCorner.java src/share/classes/javax/swing/plaf/nimbus/ToolBarSeparatorPainter.java src/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html src/share/classes/javax/swing/plaf/nimbus/package.html src/share/classes/javax/swing/plaf/nimbus/skin.laf src/share/classes/javax/swing/plaf/synth/SynthArrowButton.java src/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java src/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java src/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java src/share/classes/javax/swing/plaf/synth/SynthSliderUI.java src/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java src/share/classes/javax/swing/plaf/synth/SynthStyle.java src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java src/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java src/share/classes/javax/swing/plaf/synth/SynthTableUI.java src/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java src/share/classes/javax/swing/plaf/synth/SynthToggleButtonUI.java src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java src/share/classes/javax/swing/plaf/synth/SynthTreeUI.java src/share/classes/javax/swing/table/DefaultTableCellRenderer.java src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java src/share/classes/sun/swing/DefaultLookup.java src/share/classes/sun/swing/FilePane.java src/share/classes/sun/swing/plaf/GTKKeybindings.java src/share/classes/sun/swing/plaf/WindowsKeybindings.java src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java
diffstat 158 files changed, 53713 insertions(+), 566 deletions(-) [+]
line wrap: on
line diff
--- a/README	Fri Apr 17 16:28:02 2009 +0400
+++ b/README	Sat Apr 25 21:17:50 2009 +0400
@@ -9,25 +9,35 @@
      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
 
--- a/make/common/Sanity.gmk	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/common/Sanity.gmk	Sat Apr 25 21:17:50 2009 +0400
@@ -92,7 +92,8 @@
     sane-ld_run_path \
     sane-alt_bootdir \
     sane-bootdir \
-    sane-alsa-headers
+    sane-alsa-headers \
+    sane-jibx
 
 ifdef OPENJDK
 sanity-all:: sane-freetype 
--- a/make/common/shared/Defs.gmk	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/common/shared/Defs.gmk	Sat Apr 25 21:17:50 2009 +0400
@@ -515,6 +515,15 @@
 #   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 @@
 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 \
--- a/make/common/shared/Platform.gmk	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/common/shared/Platform.gmk	Sat Apr 25 21:17:50 2009 +0400
@@ -89,8 +89,8 @@
 
 SYSTEM_UNAME := $(shell uname)
 
-# Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
-REQUIRED_BOOT_VER = 1.5
+# Normal boot jdk is previous release, but a hard requirement is a 1.6 boot
+REQUIRED_BOOT_VER = 1.6
 
 # If we are using freetype, this is the required version
 REQUIRED_FREETYPE_VERSION=2.3.0
--- a/make/common/shared/Sanity-Settings.gmk	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/common/shared/Sanity-Settings.gmk	Sat Apr 25 21:17:50 2009 +0400
@@ -237,6 +237,7 @@
   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
--- a/make/common/shared/Sanity.gmk	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/common/shared/Sanity.gmk	Sat Apr 25 21:17:50 2009 +0400
@@ -169,6 +169,7 @@
 	sane-cacerts \
 	sane-alsa-versioncheck \
 	sane-alsa-headers \
+	sane-jibx \
 	sane-ant_version \
 	sane-zip_version \
 	sane-unzip_version \
@@ -1504,6 +1505,18 @@
 
 
 ######################################################
+# 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
 ######################################################
 sane-mozilla:
--- a/make/javax/swing/plaf/Makefile	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/javax/swing/plaf/Makefile	Sat Apr 25 21:17:50 2009 +0400
@@ -34,9 +34,14 @@
 #
 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 @@
 # 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/javax/swing/plaf/nimbus/Makefile	Sat Apr 25 21:17:50 2009 +0400
@@ -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)
--- a/make/tools/Makefile	Fri Apr 17 16:28:02 2009 +0400
+++ b/make/tools/Makefile	Sat Apr 25 21:17:50 2009 +0400
@@ -51,6 +51,7 @@
   makeclasslist             \
   strip_properties          \
   spp                       \
+  swing-nimbus              \
   CharsetMapping
 
 all build clean clobber::
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/Makefile	Sat Apr 25 21:17:50 2009 +0400
@@ -0,0 +1,89 @@
+#
+# 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/*.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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/beans/AbstractBean.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BezierControlPoint.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/BlendingMode.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Canvas.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/ControlPoint.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+        }
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Designer.jibx.xml	Sat Apr 25 21:17:50 2009 +0400
@@ -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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/DoubleBean.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/EllipseShape.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/GraphicsHelper.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/Layer.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/LayerContainer.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/PaintedShape.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/PathShape.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/RectangleShape.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/SimpleShape.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/TemplateLayer.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/DropShadowEffect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/Effect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/EffectUtils.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/EffectUtilsTemp.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/InnerGlowEffect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/InnerShadowEffect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/OuterGlowEffect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/effects/ShadowEffect.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/font/Typeface.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/CanvasMapper.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/ColorMapper.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/DimensionMapper.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/jibxhelpers/InsetsMapper.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/AbstractGradient.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Gradient.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/GradientStop.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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 &lt;= midpoint &lt;= 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;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Matte.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/PaintModel.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/RadialGradient.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/paint/Texture.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasPath.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasResources.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/swingx/designer/utils/HasUIDefaults.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/DefaultsGenerator.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/Generator.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/GeneratorUtils.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/ObjectCodeConvertors.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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 + ")";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/swing-nimbus/classes/org/jdesktop/synthdesigner/generator/PainterGenerator.java	Sat Apr 25 21:17:50 2009 +0400
@@ -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();