You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by tv...@apache.org on 2009/10/28 14:01:33 UTC

svn commit: r830516 - in /incubator/pivot/trunk: demos/src/org/apache/pivot/demos/explorer/ tools/src/org/apache/pivot/tools/wtk/

Author: tvolkert
Date: Wed Oct 28 13:01:32 2009
New Revision: 830516

URL: http://svn.apache.org/viewvc?rev=830516&view=rev
Log:
Added styles support to the component explorer demo

Added:
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.json
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspector.java
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspectorSkin.java
      - copied, changed from r830489, incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspector.java
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspectorSkin.java
Removed:
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.json
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx
Modified:
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.java
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/component_explorer.wtkx
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspector.java
    incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorListener.java

Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.java?rev=830516&r1=830515&r2=830516&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.java (original)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.java Wed Oct 28 13:01:32 2009
@@ -23,8 +23,10 @@
 import org.apache.pivot.collections.Sequence;
 import org.apache.pivot.collections.Sequence.Tree.Path;
 import org.apache.pivot.serialization.SerializationException;
-import org.apache.pivot.tools.wtk.ComponentInspector;
+import org.apache.pivot.tools.wtk.ComponentPropertyInspector;
+import org.apache.pivot.tools.wtk.ComponentStyleInspector;
 import org.apache.pivot.tools.wtk.EventLogger;
+import org.apache.pivot.util.Resources;
 import org.apache.pivot.wtk.Application;
 import org.apache.pivot.wtk.Component;
 import org.apache.pivot.wtk.ComponentMouseButtonListener;
@@ -41,18 +43,21 @@
     private Window window = null;
     private TreeView treeView = null;
     private ScrollPane scrollPane = null;
-    private ComponentInspector componentInspector = null;
+    private ComponentPropertyInspector componentPropertyInspector = null;
+    private ComponentStyleInspector componentStyleInspector = null;
     private EventLogger eventLogger = null;
 
     @Override
     public void startup(Display display, Map<String, String> properties)
         throws Exception {
-        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+        Resources resources = new Resources(getClass().getName());
+        WTKXSerializer wtkxSerializer = new WTKXSerializer(resources);
         window = (Window)wtkxSerializer.readObject(this, "component_explorer.wtkx");
 
         treeView = wtkxSerializer.getValue("treeView");
         scrollPane = wtkxSerializer.getValue("scrollPane");
-        componentInspector = wtkxSerializer.getValue("componentInspector");
+        componentPropertyInspector = wtkxSerializer.getValue("componentPropertyInspector");
+        componentStyleInspector = wtkxSerializer.getValue("componentStyleInspector");
         eventLogger = wtkxSerializer.getValue("eventLogger");
 
         treeView.getTreeViewSelectionListeners().add(new TreeViewSelectionListener.Adapter() {
@@ -81,7 +86,8 @@
                 }
 
                 scrollPane.setView(component);
-                componentInspector.setSource(component);
+                componentPropertyInspector.setSource(component);
+                componentStyleInspector.setSource(component);
                 eventLogger.setSource(component);
             }
         });

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.json
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.json?rev=830516&view=auto
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.json (added)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/ComponentExplorer.json Wed Oct 28 13:01:32 2009
@@ -0,0 +1,4 @@
+{
+    properties: "Properties",
+    styles: "Styles"
+}

Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/component_explorer.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/component_explorer.wtkx?rev=830516&r1=830515&r2=830516&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/component_explorer.wtkx (original)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/explorer/component_explorer.wtkx Wed Oct 28 13:01:32 2009
@@ -148,11 +148,54 @@
                                 </Border>
                             </left>
                             <right>
-                                <Border>
-                                    <content>
-                                        <tools:ComponentInspector wtkx:id="componentInspector"/>
-                                    </content>
-                                </Border>
+                                <SplitPane orientation="vertical" splitRatio="0.5">
+                                    <top>
+                                        <Border>
+                                            <content>
+                                                <ScrollPane
+                                                    horizontalScrollBarPolicy="fill_to_capacity">
+                                                    <view>
+                                                        <BoxPane orientation="vertical"
+                                                            styles="{fill:true,
+                                                            horizontalAlignment:'right'}">
+                                                            <Label text="%properties"
+                                                                styles="{padding:{left:10, top:5},
+                                                                font:{bold:true}}"/>
+                                                            <BoxPane orientation="vertical"
+                                                                styles="{padding:{left:10}}">
+                                                                <tools:ComponentPropertyInspector
+                                                                    wtkx:id="componentPropertyInspector"/>
+                                                            </BoxPane>
+                                                        </BoxPane>
+                                                    </view>
+                                                </ScrollPane>
+                                            </content>
+                                        </Border>
+                                    </top>
+                                    <bottom>
+                                        <Border>
+                                            <content>
+                                                <ScrollPane
+                                                    horizontalScrollBarPolicy="fill_to_capacity">
+                                                    <view>
+                                                        <BoxPane orientation="vertical"
+                                                            styles="{fill:true,
+                                                            horizontalAlignment:'right'}">
+                                                            <Label text="%styles"
+                                                                styles="{padding:{left:10, top:5},
+                                                                font:{bold:true}}"/>
+                                                            <BoxPane orientation="vertical"
+                                                                styles="{padding:{left:10}}">
+                                                                <tools:ComponentStyleInspector
+                                                                    wtkx:id="componentStyleInspector"/>
+                                                            </BoxPane>
+                                                        </BoxPane>
+                                                    </view>
+                                                </ScrollPane>
+                                            </content>
+                                        </Border>
+                                    </bottom>
+                                </SplitPane>
                             </right>
                         </SplitPane>
                     </top>

Modified: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspector.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspector.java?rev=830516&r1=830515&r2=830516&view=diff
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspector.java (original)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspector.java Wed Oct 28 13:01:32 2009
@@ -20,7 +20,7 @@
 import org.apache.pivot.wtk.Component;
 import org.apache.pivot.wtk.Container;
 
-public class ComponentInspector extends Container {
+public abstract class ComponentInspector extends Container {
     private static class ComponentInspectorListenerList
         extends ListenerList<ComponentInspectorListener> implements ComponentInspectorListener {
         @Override
@@ -36,15 +36,6 @@
     private ComponentInspectorListenerList componentInspectorListeners =
         new ComponentInspectorListenerList();
 
-    public ComponentInspector() {
-        this(null);
-    }
-
-    public ComponentInspector(Component source) {
-        setSource(source);
-        setSkin(new ComponentInspectorSkin());
-    }
-
     public Component getSource() {
         return source;
     }

Modified: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorListener.java?rev=830516&r1=830515&r2=830516&view=diff
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorListener.java (original)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorListener.java Wed Oct 28 13:01:32 2009
@@ -32,7 +32,7 @@
     }
 
     /**
-     * Called when an component inspector's source has changed.
+     * Called when an component inspector's source component has changed.
      *
      * @param componentInspector
      * @param previousSource

Added: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspector.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspector.java?rev=830516&view=auto
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspector.java (added)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspector.java Wed Oct 28 13:01:32 2009
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tools.wtk;
+
+import org.apache.pivot.wtk.Component;
+
+public class ComponentPropertyInspector extends ComponentInspector {
+    public ComponentPropertyInspector() {
+        this(null);
+    }
+
+    public ComponentPropertyInspector(Component source) {
+        setSource(source);
+        setSkin(new ComponentPropertyInspectorSkin());
+    }
+}

Copied: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspectorSkin.java (from r830489, incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java)
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspectorSkin.java?p2=incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspectorSkin.java&p1=incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java&r1=830489&r2=830516&rev=830516&view=diff
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java (original)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentPropertyInspectorSkin.java Wed Oct 28 13:01:32 2009
@@ -16,7 +16,6 @@
  */
 package org.apache.pivot.tools.wtk;
 
-import java.io.IOException;
 import java.lang.reflect.Method;
 import java.util.Comparator;
 
@@ -26,8 +25,6 @@
 import org.apache.pivot.collections.EnumList;
 import org.apache.pivot.collections.HashMap;
 import org.apache.pivot.collections.List;
-import org.apache.pivot.serialization.SerializationException;
-import org.apache.pivot.util.Resources;
 import org.apache.pivot.wtk.BoxPane;
 import org.apache.pivot.wtk.Button;
 import org.apache.pivot.wtk.ButtonStateListener;
@@ -47,10 +44,9 @@
 import org.apache.pivot.wtk.skin.ContainerSkin;
 import org.apache.pivot.wtk.text.validation.IntValidator;
 import org.apache.pivot.wtk.text.validation.FloatValidator;
-import org.apache.pivot.wtkx.WTKX;
-import org.apache.pivot.wtkx.WTKXSerializer;
 
-class ComponentInspectorSkin extends ContainerSkin implements ComponentInspectorListener {
+class ComponentPropertyInspectorSkin extends ContainerSkin
+    implements ComponentInspectorListener {
     private static class PropertyNameComparator implements Comparator<String> {
         @Override
         public int compare(String propertyName1, String propertyName2) {
@@ -75,10 +71,7 @@
         }
     }
 
-    private Component content = null;
-
-    @WTKX private Form propertiesForm = null;
-    @WTKX private BoxPane stylesPane = null;
+    private Form form = new Form();
 
     private BeanDictionary beanDictionary = new BeanDictionary();
 
@@ -88,7 +81,7 @@
     private static PropertySourceTypeComparator propertySourceTypeComparator =
         new PropertySourceTypeComparator();
 
-    public ComponentInspectorSkin() {
+    public ComponentPropertyInspectorSkin() {
         beanDictionary.getBeanDictionaryListeners().add(new BeanDictionaryListener.Adapter() {
             @Override
             public void propertyChanged(BeanDictionary beanDictionary, String propertyName) {
@@ -113,68 +106,49 @@
                 }
             }
         });
+
+        form.getStyles().put("rightAlignLabels", true);
+        form.getStyles().put("showFirstSectionHeading", true);
     }
 
     @Override
     public void install(Component component) {
         super.install(component);
 
-        ComponentInspector componentInspector = (ComponentInspector)component;
+        ComponentPropertyInspector componentPropertyInspector =
+            (ComponentPropertyInspector)component;
 
-        componentInspector.getComponentInspectorListeners().add(this);
+        componentPropertyInspector.getComponentInspectorListeners().add(this);
+        componentPropertyInspector.add(form);
 
-        Resources resources;
-        try {
-            resources = new Resources(getClass().getName());
-        } catch (IOException exception) {
-            throw new RuntimeException(exception);
-        } catch (SerializationException exception) {
-            throw new RuntimeException(exception);
-        }
-
-        WTKXSerializer wtkxSerializer = new WTKXSerializer(resources);
-        try {
-            content = (Component)wtkxSerializer.readObject(this, "component_inspector_skin.wtkx");
-        } catch (IOException exception) {
-            throw new RuntimeException(exception);
-        } catch (SerializationException exception) {
-            throw new RuntimeException(exception);
-        }
-
-        componentInspector.add(content);
-
-        wtkxSerializer.bind(this, ComponentInspectorSkin.class);
-
-        sourceChanged(componentInspector, null);
+        sourceChanged(componentPropertyInspector, null);
     }
 
     @Override
     public int getPreferredWidth(int height) {
-        return content.getPreferredWidth(height);
+        return form.getPreferredWidth(height);
     }
 
     @Override
     public int getPreferredHeight(int width) {
-        return content.getPreferredHeight(width);
+        return form.getPreferredHeight(width);
     }
 
     @Override
     public Dimensions getPreferredSize() {
-        return content.getPreferredSize();
+        return form.getPreferredSize();
     }
 
     @Override
     public void layout() {
-        content.setLocation(0, 0);
-        content.setSize(getWidth(), getHeight());
+        form.setLocation(0, 0);
+        form.setSize(getWidth(), getHeight());
     }
 
     @Override
     public void sourceChanged(ComponentInspector componentInspector, Component previousSource) {
-        Form.SectionSequence propertiesSections = propertiesForm.getSections();
-        propertiesSections.remove(0, propertiesSections.getLength());
-
-        stylesPane.remove(0, stylesPane.getLength());
+        Form.SectionSequence sections = form.getSections();
+        sections.remove(0, sections.getLength());
 
         Component source = componentInspector.getSource();
 
@@ -204,7 +178,7 @@
             for (Class<?> declaringClass : propertyBuckets) {
                 Form.Section section = new Form.Section();
                 section.setHeading(declaringClass.getSimpleName());
-                propertiesSections.add(section);
+                sections.add(section);
 
                 for (String propertyName : propertyBuckets.get(declaringClass)) {
                     addPropertyControl(propertyName, section);

Added: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspector.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspector.java?rev=830516&view=auto
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspector.java (added)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspector.java Wed Oct 28 13:01:32 2009
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tools.wtk;
+
+import org.apache.pivot.wtk.Component;
+
+public class ComponentStyleInspector extends ComponentInspector {
+    public ComponentStyleInspector() {
+        this(null);
+    }
+
+    public ComponentStyleInspector(Component source) {
+        setSource(source);
+        setSkin(new ComponentStyleInspectorSkin());
+    }
+}

Added: incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspectorSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspectorSkin.java?rev=830516&view=auto
==============================================================================
--- incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspectorSkin.java (added)
+++ incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentStyleInspectorSkin.java Wed Oct 28 13:01:32 2009
@@ -0,0 +1,643 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.tools.wtk;
+
+import java.util.Comparator;
+
+import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.EnumList;
+import org.apache.pivot.collections.HashMap;
+import org.apache.pivot.wtk.BoxPane;
+import org.apache.pivot.wtk.Button;
+import org.apache.pivot.wtk.ButtonStateListener;
+import org.apache.pivot.wtk.Checkbox;
+import org.apache.pivot.wtk.Component;
+import org.apache.pivot.wtk.ComponentListener;
+import org.apache.pivot.wtk.ComponentStateListener;
+import org.apache.pivot.wtk.Dimensions;
+import org.apache.pivot.wtk.FlowPane;
+import org.apache.pivot.wtk.Form;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.Limits;
+import org.apache.pivot.wtk.ListButton;
+import org.apache.pivot.wtk.ListButtonSelectionListener;
+import org.apache.pivot.wtk.Orientation;
+import org.apache.pivot.wtk.Point;
+import org.apache.pivot.wtk.TextInput;
+import org.apache.pivot.wtk.skin.ContainerSkin;
+import org.apache.pivot.wtk.text.validation.IntValidator;
+import org.apache.pivot.wtk.text.validation.FloatValidator;
+
+class ComponentStyleInspectorSkin extends ContainerSkin implements ComponentInspectorListener {
+    private static class StyleKeyComparator implements Comparator<String> {
+        @Override
+        public int compare(String styleKey1, String styleKey2) {
+            return styleKey1.compareTo(styleKey2);
+        }
+    }
+
+    private ComponentListener componentHandler = new ComponentListener.Adapter() {
+        @Override
+        public void styleUpdated(Component component, String styleKey, Object previousValue) {
+            Class<?> styleType = styles.getType(styleKey);
+
+            if (styleType == Boolean.TYPE) {
+                updateBooleanControl(styleKey);
+            } else if (styleType == Integer.TYPE) {
+                updateIntControl(styleKey);
+            } else if (styleType == Float.TYPE) {
+                updateFloatControl(styleKey);
+            } else if (styleType == String.class) {
+                updateStringControl(styleKey);
+            } else if (styleType.isEnum()) {
+                updateEnumControl(styleKey);
+            } else if (styleType == Point.class) {
+                updatePointControl(styleKey);
+            } else if (styleType == Dimensions.class) {
+                updateDimensionsControl(styleKey);
+            } else if (styleType == Limits.class) {
+                updateLimitsControl(styleKey);
+            }
+        }
+    };
+
+    private Form form = new Form();
+    private Form.Section formSection = new Form.Section();
+
+    private Component.StyleDictionary styles = null;
+
+    private HashMap<String, Component> inspectorComponents = new HashMap<String, Component>();
+
+    private static StyleKeyComparator styleKeyComparator = new StyleKeyComparator();
+
+    public ComponentStyleInspectorSkin() {
+        form.getStyles().put("rightAlignLabels", true);
+        form.getSections().add(formSection);
+    }
+
+    @Override
+    public void install(Component component) {
+        super.install(component);
+
+        ComponentStyleInspector componentStyleInspector = (ComponentStyleInspector)component;
+
+        componentStyleInspector.getComponentInspectorListeners().add(this);
+        componentStyleInspector.add(form);
+
+        sourceChanged(componentStyleInspector, null);
+    }
+
+    @Override
+    public int getPreferredWidth(int height) {
+        return form.getPreferredWidth(height);
+    }
+
+    @Override
+    public int getPreferredHeight(int width) {
+        return form.getPreferredHeight(width);
+    }
+
+    @Override
+    public Dimensions getPreferredSize() {
+        return form.getPreferredSize();
+    }
+
+    @Override
+    public void layout() {
+        form.setLocation(0, 0);
+        form.setSize(getWidth(), getHeight());
+    }
+
+    @Override
+    public void sourceChanged(ComponentInspector componentInspector, Component previousSource) {
+        formSection.remove(0, formSection.getLength());
+        styles = null;
+
+        Component source = componentInspector.getSource();
+
+        if (previousSource != null) {
+            previousSource.getComponentListeners().remove(componentHandler);
+        }
+
+        if (source != null) {
+            source.getComponentListeners().add(componentHandler);
+
+            styles = source.getStyles();
+
+            ArrayList<String> styleKeys = new ArrayList<String>(styleKeyComparator);
+            for (String styleKey : styles) {
+                if (!styles.isReadOnly(styleKey)) {
+                    styleKeys.add(styleKey);
+                }
+            }
+
+            for (String styleKey : styleKeys) {
+                addStyleControl(styleKey);
+            }
+        }
+    }
+
+    private void addStyleControl(String styleKey) {
+        Class<?> styleType = styles.getType(styleKey);
+
+        Component inspectorComponent = null;
+
+        if (styleType == Boolean.TYPE) {
+            inspectorComponent = addBooleanControl(styleKey);
+        } else if (styleType == Integer.TYPE) {
+            inspectorComponent = addIntControl(styleKey);
+        } else if (styleType == Float.TYPE) {
+            inspectorComponent = addFloatControl(styleKey);
+        } else if (styleType == String.class) {
+            inspectorComponent = addStringControl(styleKey);
+        } else if (styleType.isEnum()) {
+            inspectorComponent = addEnumControl(styleKey);
+        } else if (styleType == Point.class) {
+            inspectorComponent = addPointControl(styleKey);
+        } else if (styleType == Dimensions.class) {
+            inspectorComponent = addDimensionsControl(styleKey);
+        } else if (styleType == Limits.class) {
+            inspectorComponent = addLimitsControl(styleKey);
+        }
+
+        if (inspectorComponent != null) {
+            inspectorComponents.put(styleKey, inspectorComponent);
+        }
+    }
+
+    private Component addBooleanControl(final String styleKey) {
+        boolean styleValue = (Boolean)styles.get(styleKey);
+
+        Checkbox checkbox = new Checkbox();
+        checkbox.setSelected(styleValue);
+        formSection.add(checkbox);
+        Form.setLabel(checkbox, styleKey);
+
+        checkbox.getButtonStateListeners().add(new ButtonStateListener() {
+            private boolean updating = false;
+
+            @Override
+            public void stateChanged(Button button, Button.State previousState) {
+                if (!updating) {
+                    updating = true;
+                    try {
+                        styles.put(styleKey, button.isSelected());
+                    } catch (Exception exception) {
+                        button.setState(previousState);
+                    } finally {
+                        updating = false;
+                    }
+                }
+            }
+        });
+
+        return checkbox;
+    }
+
+    private void updateBooleanControl(String styleKey) {
+        Checkbox checkbox = (Checkbox)inspectorComponents.get(styleKey);
+
+        if (checkbox != null) {
+            boolean styleValue = (Boolean)styles.get(styleKey);
+            checkbox.setSelected(styleValue);
+        }
+    }
+
+    private Component addIntControl(final String styleKey) {
+        int styleValue = (Integer)styles.get(styleKey);
+
+        TextInput textInput = new TextInput();
+        textInput.setTextSize(10);
+        textInput.setMaximumLength(10);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(styleValue));
+        formSection.add(textInput);
+        Form.setLabel(textInput, styleKey);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+
+                    try {
+                        styles.put(styleKey, Integer.parseInt(textInput.getText()));
+                    } catch (Exception exception) {
+                        Object styleValue = styles.get(styleKey);
+                        textInput.setText(String.valueOf(styleValue));
+                    }
+                }
+            }
+        });
+
+        return textInput;
+    }
+
+    private void updateIntControl(String styleKey) {
+        TextInput textInput = (TextInput)inspectorComponents.get(styleKey);
+
+        if (textInput != null) {
+            int styleValue = (Integer)styles.get(styleKey);
+            textInput.setText(String.valueOf(styleValue));
+        }
+    }
+
+    private Component addFloatControl(final String styleKey) {
+        float styleValue = (Float)styles.get(styleKey);
+
+        TextInput textInput = new TextInput();
+        textInput.setTextSize(10);
+        textInput.setValidator(new FloatValidator());
+        textInput.setText(String.valueOf(styleValue));
+        formSection.add(textInput);
+        Form.setLabel(textInput, styleKey);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+
+                    try {
+                        styles.put(styleKey, Float.parseFloat(textInput.getText()));
+                    } catch (Exception exception) {
+                        Object styleValue = styles.get(styleKey);
+                        textInput.setText(String.valueOf(styleValue));
+                    }
+                }
+            }
+        });
+
+        return textInput;
+    }
+
+    private void updateFloatControl(String styleKey) {
+        TextInput textInput = (TextInput)inspectorComponents.get(styleKey);
+
+        if (textInput != null) {
+            float styleValue = (Float)styles.get(styleKey);
+            textInput.setText(String.valueOf(styleValue));
+        }
+    }
+
+    private Component addStringControl(final String styleKey) {
+        String styleValue = (String)styles.get(styleKey);
+
+        TextInput textInput = new TextInput();
+        textInput.setText(styleValue == null ? "" : styleValue);
+        formSection.add(textInput);
+        Form.setLabel(textInput, styleKey);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+
+                    try {
+                        styles.put(styleKey, textInput.getText());
+                    } catch (Exception exception) {
+                        String styleValue = (String)styles.get(styleKey);
+                        textInput.setText(styleValue == null ? "" : styleValue);
+                    }
+                }
+            }
+        });
+
+        return textInput;
+    }
+
+    private void updateStringControl(String styleKey) {
+        TextInput textInput = (TextInput)inspectorComponents.get(styleKey);
+
+        if (textInput != null) {
+            String styleValue = (String)styles.get(styleKey);
+            textInput.setText(styleValue == null ? "" : styleValue);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Component addEnumControl(final String styleKey) {
+        Class<?> styleType = styles.getType(styleKey);
+        Enum<?> styleValue = (Enum<?>)styles.get(styleKey);
+
+        ListButton listButton = new ListButton();
+        listButton.setListData(new EnumList(styleType));
+        listButton.setSelectedItem(styleValue);
+        formSection.add(listButton);
+        Form.setLabel(listButton, styleKey);
+
+        listButton.getListButtonSelectionListeners().add(new ListButtonSelectionListener() {
+            private boolean updating = false;
+
+            @Override
+            public void selectedIndexChanged(ListButton listButton, int previousSelectedIndex) {
+                if (!updating) {
+                    updating = true;
+                    try {
+                        styles.put(styleKey, listButton.getSelectedItem());
+                    } catch (Exception exception) {
+                        listButton.setSelectedIndex(previousSelectedIndex);
+                    } finally {
+                        updating = false;
+                    }
+                }
+            }
+        });
+
+        return listButton;
+    }
+
+    private void updateEnumControl(String styleKey) {
+        ListButton listButton = (ListButton)inspectorComponents.get(styleKey);
+
+        if (listButton != null) {
+            Enum<?> styleValue = (Enum<?>)styles.get(styleKey);
+            listButton.setSelectedItem(styleValue);
+        }
+    }
+
+    private Component addPointControl(final String styleKey) {
+        Point point = (Point)styles.get(styleKey);
+
+        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
+        formSection.add(boxPane);
+        Form.setLabel(boxPane, styleKey);
+
+        FlowPane flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        TextInput textInput = new TextInput();
+        textInput.setTextSize(3);
+        textInput.setMaximumLength(4);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(point.x));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Point point = (Point)styles.get(styleKey);
+
+                    try {
+                        int x = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Point(x, point.y));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(point.x));
+                    }
+                }
+            }
+        });
+
+        Label label = new Label("x");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        textInput = new TextInput();
+        textInput.setTextSize(3);
+        textInput.setMaximumLength(4);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(point.y));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Point point = (Point)styles.get(styleKey);
+
+                    try {
+                        int y = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Point(point.x, y));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(point.y));
+                    }
+                }
+            }
+        });
+
+        label = new Label("y");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        return boxPane;
+    }
+
+    private void updatePointControl(String styleKey) {
+        BoxPane boxPane = (BoxPane)inspectorComponents.get(styleKey);
+
+        if (boxPane != null) {
+            Point point = (Point)styles.get(styleKey);
+
+            TextInput xTextInput = (TextInput)((FlowPane)boxPane.get(0)).get(0);
+            TextInput yTextInput = (TextInput)((FlowPane)boxPane.get(1)).get(0);
+
+            xTextInput.setText(String.valueOf(point.x));
+            yTextInput.setText(String.valueOf(point.y));
+        }
+    }
+
+    private Component addDimensionsControl(final String styleKey) {
+        Dimensions dimensions = (Dimensions)styles.get(styleKey);
+
+        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
+        formSection.add(boxPane);
+        Form.setLabel(boxPane, styleKey);
+
+        FlowPane flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        TextInput textInput = new TextInput();
+        textInput.setTextSize(3);
+        textInput.setMaximumLength(4);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(dimensions.width));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Dimensions dimensions = (Dimensions)styles.get(styleKey);
+
+                    try {
+                        int width = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Dimensions(width, dimensions.height));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(dimensions.width));
+                    }
+                }
+            }
+        });
+
+        Label label = new Label("width");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        textInput = new TextInput();
+        textInput.setTextSize(3);
+        textInput.setMaximumLength(4);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(dimensions.height));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Dimensions dimensions = (Dimensions)styles.get(styleKey);
+
+                    try {
+                        int height = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Dimensions(dimensions.width, height));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(dimensions.height));
+                    }
+                }
+            }
+        });
+
+        label = new Label("height");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        return boxPane;
+    }
+
+    private void updateDimensionsControl(String styleKey) {
+        BoxPane boxPane = (BoxPane)inspectorComponents.get(styleKey);
+
+        if (boxPane != null) {
+            Dimensions dimensions = (Dimensions)styles.get(styleKey);
+
+            TextInput widthTextInput = (TextInput)((FlowPane)boxPane.get(0)).get(0);
+            TextInput heightTextInput = (TextInput)((FlowPane)boxPane.get(1)).get(0);
+
+            widthTextInput.setText(String.valueOf(dimensions.width));
+            heightTextInput.setText(String.valueOf(dimensions.height));
+        }
+    }
+
+    private Component addLimitsControl(final String styleKey) {
+        Limits limits = (Limits)styles.get(styleKey);
+
+        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
+        formSection.add(boxPane);
+        Form.setLabel(boxPane, styleKey);
+
+        FlowPane flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        TextInput textInput = new TextInput();
+        textInput.setTextSize(10);
+        textInput.setMaximumLength(10);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(limits.min));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Limits limits = (Limits)styles.get(styleKey);
+
+                    try {
+                        int min = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Limits(min, limits.max));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(limits.min));
+                    }
+                }
+            }
+        });
+
+        Label label = new Label("min");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        flowPane = new FlowPane();
+        flowPane.getStyles().put("alignToBaseline", true);
+        flowPane.getStyles().put("horizontalSpacing", 5);
+        boxPane.add(flowPane);
+
+        textInput = new TextInput();
+        textInput.setTextSize(10);
+        textInput.setMaximumLength(10);
+        textInput.setValidator(new IntValidator());
+        textInput.setText(String.valueOf(limits.max));
+        flowPane.add(textInput);
+
+        textInput.getComponentStateListeners().add(new ComponentStateListener.Adapter() {
+            @Override
+            public void focusedChanged(Component component, Component obverseComponent) {
+                if (!component.isFocused()) {
+                    TextInput textInput = (TextInput)component;
+                    Limits limits = (Limits)styles.get(styleKey);
+
+                    try {
+                        int max = Integer.parseInt(textInput.getText());
+                        styles.put(styleKey, new Limits(limits.min, max));
+                    } catch (Exception exception) {
+                        textInput.setText(String.valueOf(limits.max));
+                    }
+                }
+            }
+        });
+
+        label = new Label("max");
+        label.getStyles().put("font", "{italic:true}");
+        flowPane.add(label);
+
+        return boxPane;
+    }
+
+    private void updateLimitsControl(String styleKey) {
+        BoxPane boxPane = (BoxPane)inspectorComponents.get(styleKey);
+
+        if (boxPane != null) {
+            Limits limits = (Limits)styles.get(styleKey);
+
+            TextInput minTextInput = (TextInput)((FlowPane)boxPane.get(0)).get(0);
+            TextInput maxTextInput = (TextInput)((FlowPane)boxPane.get(1)).get(0);
+
+            minTextInput.setText(String.valueOf(limits.min));
+            maxTextInput.setText(String.valueOf(limits.max));
+        }
+    }
+}