You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/06/19 00:29:42 UTC

svn commit: r786320 - in /incubator/pivot/trunk: core/src/org/apache/pivot/util/ demos/src/org/apache/pivot/demos/dom/ demos/src/org/apache/pivot/demos/itunes/ tutorials/ wtk/src/org/apache/pivot/wtk/ wtk/src/org/apache/pivot/wtk/skin/terra/ wtk/src/or...

Author: gbrown
Date: Thu Jun 18 22:29:41 2009
New Revision: 786320

URL: http://svn.apache.org/viewvc?rev=786320&view=rev
Log:
Various fixes; add an iTunes Store search demo.

Added:
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/SearchDemo.java
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/cancel.png   (with props)
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/magnifier.png   (with props)
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/search_demo.wtkx
Modified:
    incubator/pivot/trunk/core/src/org/apache/pivot/util/Vote.java
    incubator/pivot/trunk/demos/src/org/apache/pivot/demos/dom/im_client.wtkx
    incubator/pivot/trunk/tutorials/.classpath
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraPushButtonSkin.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DecimalValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DoubleRangeValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatRangeValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntRangeValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntValidator.java
    incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java

Modified: incubator/pivot/trunk/core/src/org/apache/pivot/util/Vote.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/util/Vote.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/org/apache/pivot/util/Vote.java (original)
+++ incubator/pivot/trunk/core/src/org/apache/pivot/util/Vote.java Thu Jun 18 22:29:41 2009
@@ -34,30 +34,30 @@
     }
 
     public Vote tally(Vote vote) {
+        if (vote == null) {
+            throw new IllegalArgumentException();
+        }
+
         Vote tally;
 
-        if (vote == null) {
-            tally = this;
-        } else {
-            switch(vote) {
-                case APPROVE: {
-                    tally = this;
-                    break;
-                }
-
-                case DENY: {
-                    tally = vote;
-                    break;
-                }
-
-                case DEFER: {
-                    tally = (this == DENY) ? this : vote;
-                    break;
-                }
-
-                default: {
-                    throw new IllegalArgumentException();
-                }
+        switch(vote) {
+            case APPROVE: {
+                tally = this;
+                break;
+            }
+
+            case DENY: {
+                tally = vote;
+                break;
+            }
+
+            case DEFER: {
+                tally = (this == DENY) ? this : vote;
+                break;
+            }
+
+            default: {
+                throw new IllegalArgumentException();
             }
         }
 

Modified: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/dom/im_client.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/dom/im_client.wtkx?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/dom/im_client.wtkx (original)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/dom/im_client.wtkx Thu Jun 18 22:29:41 2009
@@ -16,7 +16,7 @@
 limitations under the License.
 -->
 
-<Window title="" maximized="true"
+<Window title="IM Client" maximized="true"
     xmlns:wtkx="http://pivot.apache.org/wtkx"
     xmlns="org.apache.pivot.wtk">
     <content>

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/SearchDemo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/SearchDemo.java?rev=786320&view=auto
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/SearchDemo.java (added)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/SearchDemo.java Thu Jun 18 22:29:41 2009
@@ -0,0 +1,246 @@
+/*
+ * 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.demos.itunes;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Locale;
+
+import org.apache.pivot.collections.List;
+import org.apache.pivot.collections.Map;
+import org.apache.pivot.util.concurrent.Task;
+import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.web.GetQuery;
+import org.apache.pivot.wtk.ActivityIndicator;
+import org.apache.pivot.wtk.Application;
+import org.apache.pivot.wtk.DesktopApplicationContext;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.FlowPane;
+import org.apache.pivot.wtk.ImageView;
+import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.PushButton;
+import org.apache.pivot.wtk.TableView;
+import org.apache.pivot.wtk.TaskAdapter;
+import org.apache.pivot.wtk.TextInput;
+import org.apache.pivot.wtk.Window;
+import org.apache.pivot.wtk.media.Image;
+import org.apache.pivot.wtkx.WTKX;
+import org.apache.pivot.wtkx.WTKXSerializer;
+
+public class SearchDemo implements Application {
+    private Window window = null;
+
+    @WTKX private TextInput termTextInput;
+    @WTKX private PushButton searchButton;
+    @WTKX private Label statusLabel;
+    @WTKX private TableView resultsTableView;
+    @WTKX private FlowPane activityIndicatorFlowPane;
+    @WTKX private ActivityIndicator activityIndicator;
+    @WTKX private ImageView artworkImageView;
+
+    private GetQuery getQuery = null;
+
+    private final Image searchImage;
+    private final Image cancelImage;
+
+    public static final String APPLICATION_KEY = "application";
+    public static final String QUERY_HOSTNAME = "ax.phobos.apple.com.edgesuite.net";
+    public static final String BASE_QUERY_PATH = "/WebObjects/MZStoreServices.woa/wa/itmsSearch";
+    public static final String MEDIA = "all";
+    public static final int LIMIT = 100;
+
+    public SearchDemo() {
+        searchImage = Image.load(getClass().getResource("magnifier.png"));
+        cancelImage = Image.load(getClass().getResource("cancel.png"));
+    }
+
+    @Override
+    public void startup(Display display, Map<String, String> properties) throws Exception {
+        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+        wtkxSerializer.put(APPLICATION_KEY, this);
+
+        window = (Window)wtkxSerializer.readObject(this, "search_demo.wtkx");
+        wtkxSerializer.bind(this, SearchDemo.class);
+
+        searchButton.setButtonData(searchImage);
+        window.open(display);
+
+        termTextInput.requestFocus();
+    }
+
+    @Override
+    public boolean shutdown(boolean optional) {
+        return true;
+    }
+
+    @Override
+    public void suspend() {
+        // No-op
+    }
+
+    @Override
+    public void resume() {
+        // No-op
+    }
+
+    /**
+     * Executes a search.
+     *
+     * @param term
+     * The search term.
+     *
+     * @throws IllegalArgumentException
+     * If <tt>term</tt> is <tt>null</tt> or empty.
+     *
+     * @throws IllegalStateException
+     * If a query is already executing.
+     */
+    @SuppressWarnings("unchecked")
+    public void executeQuery(String term) {
+        if (term == null
+            || term.length() == 0) {
+            throw new IllegalArgumentException();
+        }
+
+        if (getQuery != null) {
+            throw new IllegalStateException();
+        }
+
+        String country = Locale.getDefault().getCountry().toLowerCase();
+
+        getQuery = new GetQuery(QUERY_HOSTNAME, BASE_QUERY_PATH);
+        getQuery.getParameters().put("term", term);
+        getQuery.getParameters().put("country", country);
+        getQuery.getParameters().put("media", MEDIA);
+        getQuery.getParameters().put("limit", Integer.toString(LIMIT));
+        getQuery.getParameters().put("output", "json");
+
+        System.out.println(getQuery.getLocation());
+
+        statusLabel.setText("Searching...");
+        updateActivityState();
+
+        getQuery.execute(new TaskListener<Object>() {
+            @Override
+            public void taskExecuted(Task<Object> task) {
+                if (task == getQuery) {
+                    Map<String, Object> result = (Map<String, Object>)task.getResult();
+
+                    List<Object> results = (List<Object>)result.get("results");
+                    resultsTableView.setTableData(results);
+                    statusLabel.setText("Found " + results.getLength() + " matching items.");
+
+                    getQuery = null;
+                    updateActivityState();
+
+                    if (results.getLength() > 0) {
+                        resultsTableView.setSelectedIndex(0);
+                        resultsTableView.requestFocus();
+                    } else {
+                        termTextInput.requestFocus();
+                    }
+                }
+            }
+
+            @Override
+            public void executeFailed(Task<Object> task) {
+                if (task == getQuery) {
+                    statusLabel.setText(task.getFault().getMessage());
+
+                    getQuery = null;
+                    updateActivityState();
+
+                    termTextInput.requestFocus();
+                }
+            }
+        });
+    }
+
+    /**
+     * Aborts an executing query.
+     *
+     * @throws IllegalStateException
+     * If a query is not currently executing.
+     */
+    public void abortQuery() {
+        if (getQuery == null) {
+            throw new IllegalStateException();
+        }
+
+        getQuery.abort();
+
+        getQuery = null;
+        updateActivityState();
+    }
+
+    /**
+     * Tests whether a query is currently executing.
+     *
+     * @return
+     * <tt>true</tt> if a query is currently executing; <tt>false</tt>,
+     * otherwise.
+     */
+    public boolean isQueryExecuting() {
+        return (getQuery != null);
+    }
+
+    private void updateActivityState() {
+        boolean active = (getQuery != null);
+
+        activityIndicatorFlowPane.setVisible(active);
+        activityIndicator.setActive(active);
+
+        termTextInput.setEnabled(!active);
+        searchButton.setButtonData(active ? cancelImage : searchImage);
+    }
+
+    /**
+     * Updates the artwork to reflect the current selection.
+     */
+    @SuppressWarnings("unchecked")
+    public void updateArtwork() {
+        Map<String, Object> result = (Map<String, Object>)resultsTableView.getSelectedRow();
+
+        URL artworkURL = null;
+        if (result != null) {
+            try {
+                artworkURL = new URL((String)result.get("artworkUrl100"));
+            } catch (MalformedURLException exception) {
+            }
+        }
+
+        if (artworkURL == null) {
+            artworkImageView.setImage((Image)null);
+        } else {
+            Image.load(artworkURL, new TaskAdapter<Image>(new TaskListener<Image>() {
+                @Override
+                public void taskExecuted(Task<Image> task) {
+                    artworkImageView.setImage(task.getResult());
+                }
+
+                @Override
+                public void executeFailed(Task<Image> task) {
+                    artworkImageView.setImage((Image)null);
+                }
+            }));
+        }
+    }
+
+    public static void main(String[] args) {
+        DesktopApplicationContext.main(SearchDemo.class, args);
+    }
+}

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/cancel.png
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/cancel.png?rev=786320&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/cancel.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/magnifier.png
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/magnifier.png?rev=786320&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/magnifier.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/search_demo.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/search_demo.wtkx?rev=786320&view=auto
==============================================================================
--- incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/search_demo.wtkx (added)
+++ incubator/pivot/trunk/demos/src/org/apache/pivot/demos/itunes/search_demo.wtkx Thu Jun 18 22:29:41 2009
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<Window title="Search Demo" maximized="true"
+    xmlns:wtkx="http://pivot.apache.org/wtkx"
+    xmlns:content="org.apache.pivot.wtk.content"
+    xmlns="org.apache.pivot.wtk">
+    <content>
+        <TablePane styles="{padding:6, verticalSpacing:6}">
+            <columns>
+                <TablePane.Column width="1*"/>
+            </columns>
+            <rows>
+                <TablePane.Row height="-1">
+                    <TablePane>
+                        <columns>
+                            <TablePane.Column width="-1"/>
+                            <TablePane.Column width="1*"/>
+                        </columns>
+                        <rows>
+                            <TablePane.Row height="-1">
+                                <FlowPane styles="{verticalAlignment:'center'}">
+                                    <TextInput textSize="32" wtkx:id="termTextInput">
+                                        <componentKeyListeners>
+                                            <wtkx:script>
+                                            <![CDATA[
+                                            importPackage(org.apache.pivot.wtk);
+                                            function keyPressed(component, keyCode, keyLocation) {
+                                                var term = termTextInput.getText();
+
+                                                if (keyCode == Keyboard.KeyCode.ENTER) {
+                                                    if (!application.isQueryExecuting()
+                                                        && term.length() > 0) {
+                                                        searchButton.press();
+                                                    }
+                                                }
+
+                                                return false;
+                                            }
+                                            ]]>
+                                            </wtkx:script>
+                                        </componentKeyListeners>
+                                        <textInputTextListeners>
+                                            <wtkx:script>
+                                            <![CDATA[
+                                            function textChanged(textInput) {
+                                                var term = termTextInput.getText();
+                                                searchButton.setEnabled(term.length() > 0);
+                                            }
+                                            ]]>
+                                            </wtkx:script>
+                                        </textInputTextListeners>
+                                    </TextInput>
+                                    <PushButton wtkx:id="searchButton" enabled="false"
+                                        styles="{toolbar:true, padding:1}">
+                                        <buttonPressListeners>
+                                            <wtkx:script>
+                                            <![CDATA[
+                                            function buttonPressed(button) {
+                                                if (application.isQueryExecuting()) {
+                                                    application.abortQuery();
+                                                } else {
+                                                    application.executeQuery(termTextInput.getText());
+                                                }
+                                            }
+                                            ]]>
+                                            </wtkx:script>
+                                        </buttonPressListeners>
+                                        <componentKeyListeners>
+                                            <wtkx:script>
+                                            <![CDATA[
+                                            importPackage(org.apache.pivot.wtk);
+                                            function keyPressed(component, keyCode, keyLocation) {
+                                                if (keyCode == Keyboard.KeyCode.ESCAPE) {
+                                                    if (application.isQueryExecuting()) {
+                                                        application.abortQuery();
+                                                    }
+                                                }
+
+                                                return false;
+                                            }
+                                            ]]>
+                                            </wtkx:script>
+                                        </componentKeyListeners>
+                                    </PushButton>
+                                </FlowPane>
+                                <Label wtkx:id="statusLabel" styles="{horizontalAlignment:'right',
+                                    verticalAlignment:'center'}"/>
+                            </TablePane.Row>
+                        </rows>
+                    </TablePane>
+                </TablePane.Row>
+
+                <TablePane.Row height="1*">
+                    <TablePane styles="{horizontalSpacing:6}">
+                        <columns>
+                            <TablePane.Column width="1*"/>
+                            <TablePane.Column width="-1"/>
+                        </columns>
+                        <rows>
+                            <TablePane.Row height="1*">
+                                <StackPane>
+                                    <Border styles="{padding:0}">
+                                        <content>
+                                            <ScrollPane horizontalScrollBarPolicy="fill" verticalScrollBarPolicy="fillToCapacity">
+                                                <view>
+                                                    <TableView wtkx:id="resultsTableView">
+                                                        <columns>
+                                                            <TableView.Column name="itemName" width="3*" headerData="Name"/>
+                                                            <TableView.Column name="itemParentName" width="3*" headerData="Album"/>
+                                                            <TableView.Column name="artistName" width="3*" headerData="Artist"/>
+                                                            <TableView.Column name="mediaType" width="2*" headerData="Kind"/>
+                                                        </columns>
+
+                                                        <tableViewSelectionListeners>
+                                                            <wtkx:script>
+                                                            <![CDATA[
+                                                            function selectedRangeAdded(tableView, rangeStart, rangeEnd) {
+                                                                application.updateArtwork();
+                                                            }
+
+                                                            function selectedRangeRemoved(tableView, rangeStart, rangeEnd) {
+                                                                application.updateArtwork();
+                                                            }
+
+                                                            function selectedRangesChanged(tableView, previousSelectedRanges) {
+                                                                application.updateArtwork();
+                                                            }
+                                                            ]]>
+                                                            </wtkx:script>
+                                                        </tableViewSelectionListeners>
+                                                    </TableView>
+                                                </view>
+                                                <columnHeader>
+                                                    <TableViewHeader tableView="$resultsTableView">
+                                                        <tableViewHeaderPressListeners>
+                                                            <TableView.SortHandler/>
+                                                        </tableViewHeaderPressListeners>
+                                                    </TableViewHeader>
+                                                </columnHeader>
+                                            </ScrollPane>
+                                        </content>
+                                    </Border>
+
+                                    <FlowPane wtkx:id="activityIndicatorFlowPane" visible="false"
+                                        styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
+                                        <ActivityIndicator wtkx:id="activityIndicator"
+                                            preferredWidth="96" preferredHeight="96"/>
+                                    </FlowPane>
+                                </StackPane>
+
+                                <FlowPane orientation="vertical">
+                                    <Border styles="{padding:0}">
+                                        <content>
+                                            <ImageView wtkx:id="artworkImageView"
+                                                preferredWidth="120" preferredHeight="120"/>
+                                        </content>
+                                    </Border>
+                                </FlowPane>
+                            </TablePane.Row>
+                        </rows>
+                    </TablePane>
+                </TablePane.Row>
+            </rows>
+        </TablePane>
+    </content>
+</Window>

Modified: incubator/pivot/trunk/tutorials/.classpath
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/.classpath?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/.classpath (original)
+++ incubator/pivot/trunk/tutorials/.classpath Thu Jun 18 22:29:41 2009
@@ -5,6 +5,5 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/web"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/wtk"/>
-	<classpathentry kind="lib" path="/wtk/src"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/TableView.java Thu Jun 18 22:29:41 2009
@@ -509,7 +509,19 @@
             Comparable<Object> comparable = (Comparable<Object>)row1.get(columnName);
             Object value = row2.get(columnName);
 
-            return (comparable.compareTo(value)) * (sortDirection == SortDirection.ASCENDING ? 1 : -1);
+            int result;
+            if (comparable == null
+                && value == null) {
+                result = 0;
+            } else if (comparable == null) {
+                result = 1;
+            } else if (value == null) {
+                result = -1;
+            } else {
+                result = (comparable.compareTo(value)) * (sortDirection == SortDirection.ASCENDING ? 1 : -1);
+            }
+
+            return result;
         }
     }
 

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraPushButtonSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraPushButtonSkin.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraPushButtonSkin.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraPushButtonSkin.java Thu Jun 18 22:29:41 2009
@@ -182,7 +182,8 @@
         Color borderColor = null;
 
         if (!toolbar
-            || highlighted) {
+            || highlighted
+            || pushButton.isFocused()) {
             if (pushButton.isEnabled()) {
                 backgroundColor = this.backgroundColor;
                 bevelColor = (pressed
@@ -222,7 +223,8 @@
         contentGraphics.dispose();
 
         // Paint the focus state
-        if (pushButton.isFocused()) {
+        if (pushButton.isFocused()
+            && !toolbar) {
             BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
                 BasicStroke.JOIN_ROUND, 1.0f, new float[] {0.0f, 2.0f}, 0.0f);
 
@@ -239,7 +241,7 @@
 
     @Override
     public boolean isFocusable() {
-        return !toolbar;
+        return true;
     }
 
     public Font getFont() {

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DecimalValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DecimalValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DecimalValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DecimalValidator.java Thu Jun 18 22:29:41 2009
@@ -36,7 +36,7 @@
     public DecimalValidator(Locale locale) {
         super(NumberFormat.getInstance(locale));
     }
-    
+
     /** helper method that wraps the ParseException in a RuntimeException. */
     protected final Number parseNumber(String text) {
         try {

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DoubleRangeValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DoubleRangeValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DoubleRangeValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/DoubleRangeValidator.java Thu Jun 18 22:29:41 2009
@@ -33,7 +33,7 @@
         this.minValue = 0;
         this.maxValue = 1;
     }
-    
+
     public DoubleRangeValidator(double minValue, double maxValue) {
         this.minValue = minValue;
         this.maxValue = maxValue;
@@ -44,7 +44,7 @@
         this.minValue = minValue;
         this.maxValue = maxValue;
     }
-    
+
     public double getMinimum() {
         return minValue;
     }
@@ -72,7 +72,7 @@
 
         return valid;
     }
-    
+
     private final Double textToObject(String text) {
         return parseNumber(text).doubleValue();
     }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatRangeValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatRangeValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatRangeValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatRangeValidator.java Thu Jun 18 22:29:41 2009
@@ -33,7 +33,7 @@
         this.minValue = 0;
         this.maxValue = 1;
     }
-    
+
     public FloatRangeValidator(float minValue, float maxValue) {
         this.minValue = minValue;
         this.maxValue = maxValue;
@@ -44,7 +44,7 @@
         this.minValue = minValue;
         this.maxValue = maxValue;
     }
-    
+
     public float getMinimum() {
         return minValue;
     }
@@ -72,7 +72,7 @@
 
         return valid;
     }
-    
+
     private final Float textToObject(String text) {
         return parseNumber(text).floatValue();
     }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/FloatValidator.java Thu Jun 18 22:29:41 2009
@@ -17,7 +17,7 @@
 
 /**
  * A validator for a float value.
- * 
+ *
  * @author Noel Grandin
  */
 public class FloatValidator extends DecimalValidator {

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntRangeValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntRangeValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntRangeValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntRangeValidator.java Thu Jun 18 22:29:41 2009
@@ -33,7 +33,7 @@
         this.minValue = 0;
         this.maxValue = 1;
     }
-    
+
     public IntRangeValidator(int minValue, int maxValue) {
         this.minValue = minValue;
         this.maxValue = maxValue;
@@ -44,7 +44,7 @@
         this.minValue = minValue;
         this.maxValue = maxValue;
     }
-    
+
     public int getMinimum() {
         return minValue;
     }
@@ -72,7 +72,7 @@
 
         return valid;
     }
-    
+
     private final Integer textToObject(String text) {
         return parseNumber(text).intValue();
     }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntValidator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntValidator.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntValidator.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/text/validation/IntValidator.java Thu Jun 18 22:29:41 2009
@@ -29,5 +29,5 @@
         super(locale);
         format.setParseIntegerOnly(true);
     }
-    
+
 }

Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java?rev=786320&r1=786319&r2=786320&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtkx/WTKXSerializer.java Thu Jun 18 22:29:41 2009
@@ -58,6 +58,7 @@
 import org.apache.pivot.util.ListenerList;
 import org.apache.pivot.util.Resources;
 import org.apache.pivot.util.ThreadUtilities;
+import org.apache.pivot.util.Vote;
 
 /**
  * Loads an object hierarchy from an XML document.
@@ -310,13 +311,6 @@
             throw new IllegalArgumentException("inputStream is null.");
         }
 
-        // Clear the root object
-        root = null;
-
-        // Clear any previous named objects and include serializers
-        namedObjects.clear();
-        includeSerializers.clear();
-
         // Add the initial bindings
         for (String key : initialBindings) {
             namedObjects.put(key, initialBindings.get(key));
@@ -479,6 +473,13 @@
 
                         // Set the current element
                         element = new Element(element, elementType, attributes, value);
+
+                        // If this is the root, set it
+                        if (element.parent == null) {
+                            root = element.value;
+                            namedObjects.put(ROOT_OBJECT_ID, root);
+                        }
+
                         break;
                     }
 
@@ -677,6 +678,11 @@
                                     }
                                 }
 
+                                if (element.value != null
+                                    && language == null) {
+                                    language = "javascript";
+                                }
+
                                 Bindings bindings;
                                 if (element.parent.value instanceof ListenerList<?>) {
                                     // Don't pollute the engine namespace with the listener functions
@@ -774,7 +780,7 @@
                                     InvocationHandler handler = new InvocationHandler() {
                                         public Object invoke(Object proxy, Method method, Object[] args)
                                             throws Throwable {
-                                            Object result = null;
+                                            Object result;
                                             String methodName = method.getName();
 
                                             Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
@@ -787,6 +793,16 @@
                                                 }
 
                                                 result = invocable.invokeFunction(methodName, args);
+                                            } else {
+                                                Class<?> returnType = method.getReturnType();
+
+                                                if (returnType == Vote.class) {
+                                                    result = Vote.APPROVE;
+                                                } else if (returnType == Boolean.TYPE) {
+                                                    result = false;
+                                                } else {
+                                                    result = null;
+                                                }
                                             }
 
                                             return result;
@@ -814,12 +830,8 @@
                             }
                         }
 
-                        // If this is the top of the stack, return this element's value;
-                        // otherwise, move up the stack
-                        if (element.parent == null) {
-                            root = element.value;
-                            namedObjects.put(ROOT_OBJECT_ID, root);
-                        } else {
+                        // Move up the stack
+                        if (element.parent != null) {
                             element = element.parent;
                         }
 
@@ -850,47 +862,6 @@
     }
 
     /**
-     * Retrieves a included serializer by its ID.
-     *
-     * @param id
-     * The ID of the serializer, relative to this loader. The serializer's ID
-     * is the concatentation of its parent IDs and its ID, separated by periods
-     * (e.g. "foo.bar.baz").
-     *
-     * @return The named serializer, or <tt>null</tt> if a serializer with the
-     * given name does not exist.
-     */
-    public WTKXSerializer getSerializer(String id) {
-        if (id == null) {
-            throw new IllegalArgumentException("id is null.");
-        }
-
-        WTKXSerializer serializer = this;
-        String[] namespacePath = id.split("\\.");
-
-        int i = 0;
-        int n = namespacePath.length;
-        while (i < n && serializer != null) {
-            String namespace = namespacePath[i++];
-            serializer = serializer.includeSerializers.get(namespace);
-        }
-
-        return serializer;
-    }
-
-    /**
-     * Retrieves the root of the object hierarchy most recently processed by
-     * this serializer.
-     *
-     * @return
-     * The root object, or <tt>null</tt> if this serializer has not yet read an
-     * object from an input stream.
-     */
-    public Object getRoot() {
-        return root;
-    }
-
-    /**
      * Retrieves a named object.
      *
      * @param name
@@ -938,9 +909,9 @@
             throw new IllegalArgumentException("id is null.");
         }
 
-        if (root != null) {
-            throw new IllegalStateException("Object has already been read.");
-        }
+        root = null;
+        namedObjects.clear();
+        includeSerializers.clear();
 
         return initialBindings.put(id, value);
     }
@@ -951,7 +922,7 @@
         }
 
         if (root != null) {
-            throw new IllegalStateException("Object has already been read.");
+            throw new IllegalStateException();
         }
 
         return initialBindings.remove(id);
@@ -1000,6 +971,47 @@
     }
 
     /**
+     * Retrieves the root of the object hierarchy most recently processed by
+     * this serializer.
+     *
+     * @return
+     * The root object, or <tt>null</tt> if this serializer has not yet read an
+     * object from an input stream.
+     */
+    public Object getRoot() {
+        return root;
+    }
+
+    /**
+     * Retrieves an include serializer by its ID.
+     *
+     * @param id
+     * The ID of the serializer, relative to this loader. The serializer's ID
+     * is the concatentation of its parent IDs and its ID, separated by periods
+     * (e.g. "foo.bar.baz").
+     *
+     * @return The named serializer, or <tt>null</tt> if a serializer with the
+     * given name does not exist.
+     */
+    public WTKXSerializer getSerializer(String id) {
+        if (id == null) {
+            throw new IllegalArgumentException("id is null.");
+        }
+
+        WTKXSerializer serializer = this;
+        String[] namespacePath = id.split("\\.");
+
+        int i = 0;
+        int n = namespacePath.length;
+        while (i < n && serializer != null) {
+            String namespace = namespacePath[i++];
+            serializer = serializer.includeSerializers.get(namespace);
+        }
+
+        return serializer;
+    }
+
+    /**
      * Applies WTKX binding annotations to an object.
      * <p>
      * If this method will be called by untrusted code, a bind processor must