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/03/16 17:36:28 UTC

svn commit: r754936 [6/38] - in /incubator/pivot/tags/v1.0.1: ./ charts-test/ charts-test/src/ charts-test/src/pivot/ charts-test/src/pivot/charts/ charts-test/src/pivot/charts/test/ charts/ charts/lib/ charts/src/ charts/src/pivot/ charts/src/pivot/ch...

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/ImmutableIterator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/ImmutableIterator.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/ImmutableIterator.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/ImmutableIterator.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util;
+
+import java.util.Iterator;
+
+/**
+ * Immutable implementation of the {@link Iterator} interface.
+ *
+ * @author gbrown
+ */
+public class ImmutableIterator<T> implements Iterator<T> {
+    Iterator<T> iterator;
+
+    public ImmutableIterator(Iterator<T> iterator) {
+        if (iterator == null) {
+            throw new IllegalArgumentException("iterator is null.");
+        }
+
+        this.iterator = iterator;
+    }
+
+    public boolean hasNext() {
+        return iterator.hasNext();
+    }
+
+    public T next() {
+        return iterator.next();
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/ListenerList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/ListenerList.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/ListenerList.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/ListenerList.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util;
+
+import java.util.Iterator;
+
+/**
+ * Abstract base class for listener lists.
+ * <p>
+ * NOTE This class is not thread-safe.
+ * <p>
+ * IMPORTANT This class does not implement Sequence, since this would
+ * provide direct access to listeners via index, enabling concurrent
+ * modification by removing listeners during iteration.
+ * <p>
+ * TODO Eliminate dependency on java.util.ArrayList and use an internal
+ * linked list (not an instance of pivot.collections.LinkedList, since
+ * that will create a circular dependency).
+ *
+ * @author gbrown
+ */
+public abstract class ListenerList<T> implements Iterable<T> {
+    private java.util.ArrayList<T> list = new java.util.ArrayList<T>();
+
+    public void add(T listener) {
+        assert (list.indexOf(listener) != -1)
+            : "Duplicate listener " + listener + " added to " + this;
+
+        list.add(listener);
+    }
+
+    public void remove(T listener) {
+        assert (list.indexOf(listener) == -1)
+            : "Nonexistent listener " + listener + " removed from " + this;
+
+        list.remove(listener);
+    }
+
+    public int getCount() {
+        return list.size();
+    }
+
+    public Iterator<T> iterator() {
+        // TODO For now, return an iterator on a copy of the list; this will
+        // allow callers to remove themselves as listeners while an event is
+        // being fired
+
+        // In the future, we can use the linked list nodes to support this;
+        // when a node is removed, the previous node will be updated to point
+        // to the following node, but the node itself does not need to be
+        // updated - it will continue to point to the following node, allowing
+        // iteration to continue
+
+        java.util.ArrayList<T> list = new java.util.ArrayList<T>(this.list);
+        return new ImmutableIterator<T>(list.iterator());
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/Resources.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/Resources.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/Resources.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/Resources.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.Locale;
+import java.util.MissingResourceException;
+
+import pivot.collections.Dictionary;
+import pivot.collections.Map;
+import pivot.serialization.JSONSerializer;
+import pivot.serialization.SerializationException;
+
+/**
+ * Reads a JSON resource at {@link #baseName} using
+ * {@link ClassLoader#getResourceAsStream(String)}. It applies localization to
+ * the resource using a method similar to that of
+ * {@link java.util.ResourceBundle} in that it loads the base resource, then
+ * applies a country specified resource over-writing the values in the base
+ * using the country specified. It then does the same for country/language
+ * specific.
+ *
+ * @see java.util.ResourceBundle
+ *
+ * @author brindy
+ */
+public class Resources implements Dictionary<String, Object> {
+    private String baseName = null;
+    private Locale locale = null;
+    private Charset charset = null;
+
+    private Map<String, Object> resourceMap = null;
+
+    public Resources(String baseName)
+        throws IOException, SerializationException {
+        this(baseName, Locale.getDefault(), Charset.defaultCharset());
+    }
+
+    public Resources(String baseName, Locale locale)
+        throws IOException, SerializationException {
+        this(baseName, locale, Charset.defaultCharset());
+    }
+
+    public Resources(String baseName, String charsetName)
+        throws IOException, SerializationException {
+        this(baseName, Locale.getDefault(), charsetName);
+    }
+
+    public Resources(String baseName, Charset charset)
+        throws IOException, SerializationException {
+        this(baseName, Locale.getDefault(), charset);
+    }
+
+    public Resources(String baseName, Locale locale, String charsetName)
+        throws IOException, SerializationException {
+        this(baseName, locale, Charset.forName(charsetName));
+    }
+
+    /**
+     * Creates a new resource bundle.
+     *
+     * @param baseName
+     * The base name of this resource as a fully qualified class name.
+     *
+     * @param locale
+     * The locale to use when reading this resource.
+     *
+     * @param charset
+     * The character encoding to use when reading this resource.
+     *
+     * @throws IOException
+     * If there is a problem when reading the resource.
+     *
+     * @throws SerializationException
+     * If there is a problem deserializing the resource from its JSON format.
+     *
+     * @throws IllegalArgumentException
+     * If baseName or locale is null.
+     *
+     * @throws MissingResourceException
+     * If no resource for the specified base name can be found.
+     */
+    public Resources(String baseName, Locale locale, Charset charset) throws IOException,
+        SerializationException {
+
+        if (locale == null) {
+            throw new IllegalArgumentException("locale is null");
+        }
+
+        if (charset == null) {
+            throw new IllegalArgumentException("charset is null.");
+        }
+
+        this.baseName = baseName;
+        this.locale = locale;
+        this.charset = charset;
+
+        String resourceName = baseName.replace('.', '/');
+        resourceMap = readJSONResource(resourceName + ".json");
+        if (resourceMap == null) {
+            throw new MissingResourceException("Can't find resource for base name "
+                + baseName + ", locale " + locale, baseName, "");
+        }
+
+        // try to find resource for the language (e.g. resourceName_en)
+        Map<String, Object> overrideMap = readJSONResource(resourceName + "_"
+            + locale.getLanguage() + ".json");
+        if (overrideMap != null) {
+            applyOverrides(resourceMap, overrideMap);
+        }
+
+        // try to find resource for the entire locale (e.g. resourceName_en_GB)
+        overrideMap = readJSONResource(resourceName + "_" + locale.toString() + ".json");
+        if (null != overrideMap) {
+            applyOverrides(resourceMap, overrideMap);
+        }
+    }
+
+    public boolean containsKey(String key) {
+        return resourceMap.containsKey(key);
+    }
+
+    public Object get(String key) {
+        return resourceMap.get(key);
+    }
+
+    public String getBaseName() {
+        return baseName;
+    }
+
+    public Locale getLocale() {
+        return locale;
+    }
+
+    public boolean isEmpty() {
+        return resourceMap.isEmpty();
+    }
+
+    public Object put(String key, Object value) {
+        throw new UnsupportedOperationException("Resources instances are immutable");
+    }
+
+    public Object remove(String key) {
+        throw new UnsupportedOperationException("Resources instances are immutable");
+    }
+
+    @SuppressWarnings("unchecked")
+    private void applyOverrides(Map<String, Object> sourceMap,
+        Map<String, Object> overridesMap) {
+
+        for (String key : overridesMap) {
+            if (sourceMap.containsKey(key)) {
+                Object source = sourceMap.get(key);
+                Object override = overridesMap.get(key);
+
+                if (source instanceof Map && override instanceof Map) {
+                    applyOverrides((Map<String, Object>) source,
+                        (Map<String, Object>) override);
+                } else {
+                    sourceMap.put(key, overridesMap.get(key));
+                }
+            }
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> readJSONResource(String name) throws IOException,
+        SerializationException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(name);
+        if (in == null) {
+            return null;
+        }
+
+        JSONSerializer serializer = new JSONSerializer(charset);
+        Map<String, Object> resourceMap = null;
+        try {
+            resourceMap = (Map<String, Object>) serializer.readObject(in);
+        } finally {
+            in.close();
+        }
+
+        return resourceMap;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/Version.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/Version.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/Version.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/Version.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util;
+
+import java.io.Serializable;
+
+/**
+ * Represents a version number. Version numbers are defined as:
+ * <p>
+ * <i>major</i>.<i>minor</i>.<i>maintenance</i>_<i>update</i>
+ * <p>
+ * for example, "JDK 1.6.0_10".
+ *
+ * @author gbrown
+ */
+public class Version implements Comparable<Version>, Serializable {
+    public static final long serialVersionUID = 0;
+
+    private byte majorRevision = 0;
+    private byte minorRevision = 0;
+    private byte maintenanceRevision = 0;
+    private byte updateRevision = 0;
+
+    public Version(int majorRevision, int minorRevision, int maintenanceRevision,
+        int updateRevision) {
+        if (majorRevision > 0x7f) {
+            throw new IllegalArgumentException("majorRevision must be less than "
+                + 0x7f + ".");
+        }
+
+        if (minorRevision > 0xff) {
+            throw new IllegalArgumentException("minorRevision must be less than "
+                + 0xff + ".");
+        }
+
+        if (maintenanceRevision > 0xff) {
+            throw new IllegalArgumentException("maintenanceRevision must be less than "
+                + 0xff + ".");
+        }
+
+        if (updateRevision > 0xff) {
+            throw new IllegalArgumentException("updateRevision must be less than "
+                + 0xff + ".");
+        }
+
+        this.majorRevision = (byte)majorRevision;
+        this.minorRevision = (byte)minorRevision;
+        this.maintenanceRevision = (byte)maintenanceRevision;
+        this.updateRevision = (byte)updateRevision;
+    }
+
+    public byte getMajorRevision() {
+        return majorRevision;
+    }
+
+    public byte getMinorRevision() {
+        return minorRevision;
+    }
+
+    public byte getMaintenanceRevision() {
+        return maintenanceRevision;
+    }
+
+    public byte getUpdateRevision() {
+        return updateRevision;
+    }
+
+    public int getNumber() {
+        int number = (((int)majorRevision) & 0xff) << (8 * 3)
+            | (((int)minorRevision) & 0xff) << (8 * 2)
+            | (((int)maintenanceRevision) & 0xff) << (8 * 1)
+            | (((int)updateRevision) & 0xff) << (8 * 0);
+
+        return number;
+    }
+
+    public int compareTo(Version version) {
+        return (getNumber() - version.getNumber());
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        return (compareTo((Version)object) == 0);
+    }
+
+    @Override
+    public int hashCode() {
+        return getNumber();
+    }
+
+    @Override
+    public String toString() {
+        String string = majorRevision
+            + "." + minorRevision
+            + "." + maintenanceRevision
+            + "_" + updateRevision;
+
+        return string;
+    }
+
+    public static Version decode(String string) {
+        byte majorRevision = 0;
+        byte minorRevision = 0;
+        byte maintenanceRevision = 0;
+        byte updateRevision = 0;
+
+        String[] revisionNumbers = string.split("\\.");
+
+        if (revisionNumbers.length > 0) {
+            majorRevision = Byte.parseByte(revisionNumbers[0]);
+
+            if (revisionNumbers.length > 1) {
+                minorRevision = Byte.parseByte(revisionNumbers[1]);
+
+                if (revisionNumbers.length > 2) {
+                    String[] maintenanceRevisionNumbers = revisionNumbers[2].split("_");
+
+                    if (maintenanceRevisionNumbers.length > 0) {
+                        maintenanceRevision = Byte.parseByte(maintenanceRevisionNumbers[0]);
+
+                        if (maintenanceRevisionNumbers.length > 1) {
+                            updateRevision = Byte.parseByte(maintenanceRevisionNumbers[1]);
+                        }
+                    }
+                }
+            }
+        }
+
+        return new Version(majorRevision, minorRevision, maintenanceRevision,
+            updateRevision);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/Vote.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/Vote.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/Vote.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/Vote.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util;
+
+/**
+ * Enumeration representing a vote. Votes are often used to determine the
+ * result of an event preview.
+ *
+ * @author gbrown
+ */
+public enum Vote {
+    APPROVE(true),
+    DENY(false),
+    DEFER(false);
+
+    private boolean approved;
+
+    private Vote(boolean approved) {
+        this.approved = approved;
+    }
+
+    public Vote tally(Vote vote) {
+        Vote tally;
+
+        switch(vote) {
+            case APPROVE: {
+                tally = this;
+                break;
+            }
+
+            case DENY: {
+                tally = vote;
+                break;
+            }
+
+            case DEFER: {
+                tally = (this == DENY) ? this : vote;
+                break;
+            }
+
+            default: {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        return tally;
+    }
+
+    public boolean isApproved() {
+        return approved;
+    }
+
+    public static Vote decode(String value) {
+        return valueOf(value.toUpperCase());
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/AbortException.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/AbortException.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/AbortException.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/AbortException.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+/**
+ * Thrown when a task is aborted.
+ *
+ * @author gbrown
+ */
+public class AbortException extends RuntimeException {
+    public static final long serialVersionUID = 0;
+
+    public AbortException() {
+        super();
+    }
+
+    public AbortException(String message) {
+        super(message);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Dispatcher.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Dispatcher.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Dispatcher.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Dispatcher.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+import pivot.collections.ArrayList;
+import pivot.collections.ArrayQueue;
+import pivot.collections.Queue;
+import pivot.collections.List;
+import pivot.collections.concurrent.SynchronizedQueue;
+
+/**
+ * Operates a thread pool for dispatching runnable tasks. Runnables are
+ * added to a pending queue and dispatched as threads become available to
+ * execute them.
+ * <p>
+ * TODO This class is currently functional but not complete. Runnables are
+ * currently dispatched as soon as they are added to the queue. Need to complete
+ * the pooling implementation.
+ * <p>
+ * TODO Is there a way to throw an AbortException when an item is removed
+ * from the queue, without having to rely on methods like abort()?
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public class Dispatcher {
+    private class MonitorThread extends Thread {
+        public MonitorThread() {
+            super(Dispatcher.this.getClass().getName() + "-MonitorThread");
+
+            // Mark this thread as a daemon
+            setDaemon(true);
+        }
+
+        public void run() {
+            while (true) {
+                // Block until an entry is available
+                Runnable runnable = pendingQueue.dequeue();
+
+                // TODO Use the thread pool
+                Thread workerThread = new Thread(runnable,
+                    Dispatcher.this.getClass().getName() + "-WorkerThread");
+                workerThread.start();
+            }
+        }
+    }
+
+    private int minimumThreadCount = 0;
+    private int maximumThreadCount = 0;
+
+    private Queue<Runnable> pendingQueue = null;
+    private List<Thread> threadPool = null;
+
+    private Thread queueMonitorThread = null;
+
+    public Dispatcher() {
+        this(0, 10);
+    }
+
+    public Dispatcher(int minimumThreadCount, int maximumThreadCount) {
+        this.minimumThreadCount = minimumThreadCount;
+        this.maximumThreadCount = maximumThreadCount;
+
+        // TODO Use a linked queue for performance
+        pendingQueue = new SynchronizedQueue<Runnable>(new ArrayQueue<Runnable>());
+
+        // TODO Start minimum number of pool threads
+        threadPool = new ArrayList<Thread>(maximumThreadCount);
+    }
+
+    /**
+     * Returns a reference to the dispatcher's pending runnable queue.
+     *
+     * @return
+     * A synchronized queue from which the dispatcher will withdraw runnables.
+     */
+    public Queue<Runnable> getPendingQueue() {
+        // TODO We need to check for isAlive() here because the Java Plugin
+        // appears to kill the thread when navigating between pages. Revisit
+        // this after J6u10 is generally available.
+
+        if (queueMonitorThread == null
+            || !queueMonitorThread.isAlive()) {
+            queueMonitorThread = new MonitorThread();
+            queueMonitorThread.start();
+        }
+
+        return pendingQueue;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/SynchronizedListenerList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/SynchronizedListenerList.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/SynchronizedListenerList.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/SynchronizedListenerList.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+import java.util.Iterator;
+
+import pivot.util.ListenerList;
+
+/**
+ * Abstract base class for synchronized listener lists.
+ *
+ * @see pivot.util.ListenerList
+ *
+ * @author gbrown
+ */
+public abstract class SynchronizedListenerList<T> extends ListenerList<T> {
+    public synchronized void add(T listener) {
+        super.add(listener);
+    }
+
+    public synchronized void remove(T listener) {
+        super.remove(listener);
+    }
+
+    public synchronized int getCount() {
+        return super.getCount();
+    }
+
+    /**
+     * NOTE Callers must manually synchronize on the SynchronizedListenerList
+     * instance to ensure thread safety during iteration.
+     */
+    public Iterator<T> iterator() {
+        return super.iterator();
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Task.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Task.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Task.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/Task.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+/**
+ * Abstract base class for "tasks". A task is an asynchronous operation that
+ * may optionally return a value.
+ *
+ * @param V
+ * The type of the value returned by the operation. May be {@link Void} to
+ * indicate that the task does not return a value.
+ *
+ * @author gbrown
+ */
+public abstract class Task<V> {
+    /**
+     * Task execution callback that is posted to the dispatcher queue.
+     */
+    private class ExecuteCallback implements Runnable {
+        public void run() {
+            V result = null;
+            Exception fault = null;
+
+            try {
+                result = execute();
+            }
+            catch(Exception exception) {
+                fault = exception;
+            }
+
+            synchronized(Task.this) {
+                Task.this.result = result;
+                Task.this.fault = fault;
+
+                if (fault == null) {
+                    taskListener.taskExecuted(Task.this);
+                }
+                else {
+                    taskListener.executeFailed(Task.this);
+                }
+
+                abort = false;
+                taskListener = null;
+            }
+
+        }
+    }
+
+    private Dispatcher dispatcher = null;
+
+    private V result = null;
+    private Exception fault = null;
+    private TaskListener<V> taskListener = null;
+
+    protected volatile long timeout = Long.MAX_VALUE;
+    protected volatile boolean abort = false;
+
+    private ExecuteCallback executeCallback = null;
+
+    private static Dispatcher DEFAULT_DISPATCHER = new Dispatcher();
+
+    public Task() {
+        this(DEFAULT_DISPATCHER);
+    }
+
+    public Task(Dispatcher dispatcher) {
+        if (dispatcher == null) {
+            throw new IllegalArgumentException("dispatcher is null.");
+        }
+
+        this.dispatcher = dispatcher;
+    }
+
+    /**
+     * Synchronously executes the task.
+     *
+     * @return
+     * The result of the task's execution.
+     *
+     * @throws TaskExecutionException
+     * If an error occurs while executing the task.
+     */
+    public abstract V execute() throws TaskExecutionException;
+
+    /**
+     * Asynchronously executes the task. The caller is notified of the task's
+     * completion via the listener argument. Note that the listener will be
+     * notified on the task's worker thread, not on the thread that executed
+     * the task.
+     *
+     * @param taskListener
+     * The listener to be notified when the task completes.
+     */
+    public synchronized void execute(TaskListener<V> taskListener) {
+        if (taskListener == null) {
+            throw new IllegalArgumentException("taskListener is null.");
+        }
+
+        if (this.taskListener != null) {
+            throw new IllegalThreadStateException("Task is already pending.");
+        }
+
+        this.taskListener = taskListener;
+
+        result = null;
+        fault = null;
+        abort = false;
+
+        // Create a new execute callback and post it to the dispatcher
+        executeCallback = new ExecuteCallback();
+        dispatcher.getPendingQueue().enqueue(executeCallback);
+    }
+
+    /**
+     * Returns the dispatcher used to execute this task.
+     */
+    public Dispatcher getDispatcher() {
+        return dispatcher;
+    }
+
+    /**
+     * Returns the result of executing the task.
+     *
+     * @return
+     * The task result, or <tt>null</tt> if the task is still executing or
+     * has failed. The result itself may also be <tt>null</tt>; callers should
+     * call {@link #isPending()} and {@link #getFault()} to distinguish
+     * between these cases.
+     */
+    public synchronized V getResult() {
+        return result;
+    }
+
+    /**
+     * Returns the fault that occurred while executing the task.
+     *
+     * @return
+     * The task fault, or <tt>null</tt> if the task is still executing or
+     * has succeeded. Callers should call {@link #isPending()} to distinguish
+     * between these cases.
+     */
+    public synchronized Exception getFault() {
+        return fault;
+    }
+
+    /**
+     * Returns the pending state of the task.
+     *
+     * @return
+     * <tt>true</tt> if the task is awaiting execution or currently executing;
+     * <tt>false</tt>, otherwise.
+     */
+    public synchronized boolean isPending() {
+        return (taskListener != null);
+    }
+
+
+    /**
+     * Returns the timeout value for this task.
+     *
+     * @see #setTimeout(long)
+     */
+    public synchronized long getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * Sets the timeout value for this task. It is the responsibility of the
+     * implementing class to respect this value.
+     *
+     * @param timeout
+     * The time by which the task must complete execution. If the timeout is
+     * exceeded, a {@link TimeoutException} will be thrown.
+     */
+    public synchronized void setTimeout(long timeout) {
+        this.timeout = timeout;
+    }
+
+    /**
+     * Sets the abort flag for this task to <tt>true</tt>. It is the
+     * responsibility of the implementing class to respect this value and
+     * throw a {@link AbortException}.
+     */
+    public synchronized void abort() {
+        if (taskListener == null) {
+            throw new IllegalStateException("Task is not currently pending.");
+        }
+
+        abort = true;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskExecutionException.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskExecutionException.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskExecutionException.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskExecutionException.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+/**
+ * Thrown when an error occurs during task execution.
+ *
+ * @author gbrown
+ */
+public class TaskExecutionException extends Exception {
+    public static final long serialVersionUID = 0;
+
+    public TaskExecutionException() {
+        super();
+    }
+
+    public TaskExecutionException(String message) {
+        super(message);
+    }
+
+    public TaskExecutionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public TaskExecutionException(Throwable cause) {
+        super(cause);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskGroup.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskGroup.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskGroup.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskGroup.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+import java.util.Iterator;
+
+import pivot.collections.Group;
+import pivot.collections.HashMap;
+import pivot.util.ImmutableIterator;
+
+/**
+ * Class that runs a group of tasks in parallel and notifies listeners
+ * when all tasks are complete. Callers can retrieve task results or faults by
+ * calling {@link Task#getResult()} and {@link Task#getFault()},
+ * respectively.
+ *
+ * @author tvolkert
+ * @author gbrown
+ */
+public class TaskGroup<V> extends Task<Void>
+    implements Group<Task<V>>, Iterable<Task<V>> {
+    private class TaskHandler implements TaskListener<V> {
+        public void taskExecuted(Task<V> task) {
+            synchronized (TaskGroup.this) {
+                tasks.put(task, Boolean.TRUE);
+                TaskGroup.this.notify();
+            }
+        }
+
+        public void executeFailed(Task<V> task) {
+            synchronized (TaskGroup.this) {
+                tasks.put(task, Boolean.TRUE);
+                TaskGroup.this.notify();
+            }
+        }
+    }
+
+    private HashMap<Task<V>, Boolean> tasks = new HashMap<Task<V>, Boolean>();
+    private boolean executing = false;
+
+    public TaskGroup() {
+        super();
+    }
+
+    public TaskGroup(Dispatcher dispatcher) {
+        super(dispatcher);
+    }
+
+    @Override
+    public synchronized Void execute() throws TaskExecutionException {
+        executing = true;
+
+        try {
+            TaskHandler taskHandler = new TaskHandler();
+
+            for (Task<V> task : tasks) {
+                tasks.put(task, Boolean.FALSE);
+                task.execute(taskHandler);
+            }
+
+            boolean complete = false;
+
+            while (!complete) {
+                try {
+                    wait();
+                } catch (InterruptedException ex) {
+                    throw new TaskExecutionException(ex);
+                }
+
+                complete = true;
+                for (Task<V> task : tasks) {
+                    if (!tasks.get(task)) {
+                        complete = false;
+                        break;
+                    }
+                }
+            }
+        } finally {
+            executing = false;
+        }
+
+        return null;
+    }
+
+    public synchronized void add(Task<V> element) {
+        if (executing) {
+            throw new IllegalStateException("Task group is executing.");
+        }
+
+        tasks.put(element, Boolean.FALSE);
+    }
+
+    public synchronized void remove(Task<V> element) {
+        if (executing) {
+            throw new IllegalStateException("Task group is executing.");
+        }
+
+        tasks.remove(element);
+    }
+
+    public boolean contains(Task<V> element) {
+        return tasks.containsKey(element);
+    }
+
+    public boolean isEmpty() {
+        return tasks.isEmpty();
+    }
+
+    public Iterator<Task<V>> iterator() {
+        return new ImmutableIterator<Task<V>>(tasks.iterator());
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskListener.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+/**
+ * Task listener interface.
+ *
+ * @param <V>
+ * The return type of the task.
+ *
+ * @author gbrown
+ */
+public interface TaskListener<V> {
+    /**
+     * Called when the task has completed successfully.
+     *
+     * @param task
+     * The source of the task event.
+     */
+    public void taskExecuted(Task<V> task);
+
+    /**
+     * Called when task execution has failed.
+     *
+     * @param task
+     * The source of the task event.
+     */
+    public void executeFailed(Task<V> task);
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskSequence.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskSequence.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskSequence.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TaskSequence.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+import java.util.Iterator;
+
+import pivot.collections.ArrayList;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+
+/**
+ * Class that runs a sequence of tasks in series and notifies listeners
+ * when all tasks are complete. Callers can retrieve task results or faults by
+ * calling {@link Task#getResult()} and {@link Task#getFault()},
+ * respectively.
+ *
+ * @author gbrown
+ */
+public class TaskSequence<V> extends Task<Void>
+    implements Sequence<Task<V>>, Iterable<Task<V>> {
+    private ArrayList<Task<V>> tasks = new ArrayList<Task<V>>();
+    private int activeTaskIndex = -1;
+
+    public TaskSequence() {
+        super();
+    }
+
+    public TaskSequence(Dispatcher dispatcher) {
+        super(dispatcher);
+    }
+
+    @Override
+    public synchronized Void execute() throws TaskExecutionException {
+        TaskListener<V> taskListener = new TaskListener<V>() {
+            public void taskExecuted(Task<V> task) {
+                synchronized (TaskSequence.this) {
+                    TaskSequence.this.notify();
+                }
+            }
+
+            public void executeFailed(Task<V> task) {
+                synchronized (TaskSequence.this) {
+                    TaskSequence.this.notify();
+                }
+            }
+        };
+
+        activeTaskIndex = 0;
+
+        while (activeTaskIndex < tasks.getLength()) {
+            Task<V> activeTask = tasks.get(activeTaskIndex);
+            activeTask.execute(taskListener);
+
+            try {
+                wait();
+            } catch (InterruptedException exception) {
+                throw new TaskExecutionException(exception);
+            }
+
+            activeTaskIndex++;
+        }
+
+        activeTaskIndex = -1;
+
+        return null;
+    }
+
+    public int add(Task<V> task) {
+        int index = tasks.getLength();
+        insert(task, index);
+
+        return index;
+    }
+
+    public synchronized void insert(Task<V> task, int index) {
+        if (activeTaskIndex != -1) {
+            throw new IllegalStateException();
+        }
+
+        tasks.insert(task, index);
+    }
+
+    public synchronized Task<V> update(int index, Task<V> task) {
+        if (activeTaskIndex != -1) {
+            throw new IllegalStateException();
+        }
+
+        return tasks.update(index, task);
+    }
+
+    public int remove(Task<V> task) {
+        int index = tasks.indexOf(task);
+        if (index != -1) {
+            tasks.remove(index, 1);
+        }
+
+        return index;
+    }
+
+    public synchronized Sequence<Task<V>> remove(int index, int count) {
+        if (activeTaskIndex != -1) {
+            throw new IllegalStateException();
+        }
+
+        return tasks.remove(index, count);
+    }
+
+    public Task<V> get(int index) {
+        return tasks.get(index);
+    }
+
+
+    public int indexOf(Task<V> task) {
+        return tasks.indexOf(task);
+    }
+
+    public int getLength() {
+        return tasks.getLength();
+    }
+
+    public Iterator<Task<V>> iterator() {
+        return new ImmutableIterator<Task<V>>(tasks.iterator());
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TimeoutException.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TimeoutException.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TimeoutException.java (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/TimeoutException.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.util.concurrent;
+
+/**
+ * Thrown when an executing task has timed out.
+ *
+ * @author gbrown
+ */
+public class TimeoutException extends RuntimeException {
+    public static final long serialVersionUID = 0;
+
+    public TimeoutException() {
+        super();
+    }
+
+    public TimeoutException(String message) {
+        super(message);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/package.html?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/package.html (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/concurrent/package.html Mon Mar 16 16:36:10 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Provides a set of classes to simplify the execution of background tasks.</p>
+</body>
+</html>

Added: incubator/pivot/tags/v1.0.1/core/src/pivot/util/package.html
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/core/src/pivot/util/package.html?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/core/src/pivot/util/package.html (added)
+++ incubator/pivot/tags/v1.0.1/core/src/pivot/util/package.html Mon Mar 16 16:36:10 2009
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>Contains a collection of common utility classes.</p>
+</body>
+</html>

Added: incubator/pivot/tags/v1.0.1/demos/.classpath
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/.classpath?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/.classpath (added)
+++ incubator/pivot/tags/v1.0.1/demos/.classpath Mon Mar 16 16:36:10 2009
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/web"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/wtk"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: incubator/pivot/tags/v1.0.1/demos/.project
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/.project?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/.project (added)
+++ incubator/pivot/tags/v1.0.1/demos/.project Mon Mar 16 16:36:10 2009
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>demos</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/DecoratorDemo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/DecoratorDemo.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/DecoratorDemo.java (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/DecoratorDemo.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.demos.decorator;
+
+import pivot.collections.Dictionary;
+import pivot.wtk.Application;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentMouseListener;
+import pivot.wtk.Display;
+import pivot.wtk.Frame;
+import pivot.wtk.Window;
+import pivot.wtk.effects.FadeDecorator;
+import pivot.wtk.effects.ReflectionDecorator;
+import pivot.wtkx.WTKXSerializer;
+
+public class DecoratorDemo implements Application {
+    private Window reflectionWindow = null;
+    private Frame fadeFrame = null;
+
+    public void startup(Display display, Dictionary<String, String> properties)
+        throws Exception {
+        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+
+        reflectionWindow =
+            new Window((Component)wtkxSerializer.readObject(getClass().getResource("reflection.wtkx")));
+        reflectionWindow.setTitle("Reflection Window");
+        reflectionWindow.getDecorators().add(new ReflectionDecorator());
+        reflectionWindow.setLocation(20, 20);
+        reflectionWindow.open(display);
+
+        fadeFrame =
+            new Frame((Component)wtkxSerializer.readObject(getClass().getResource("translucent.wtkx")));
+        fadeFrame.setTitle("Translucent Window");
+
+        final FadeDecorator fadeDecorator = new FadeDecorator();
+        fadeFrame.getDecorators().update(0, fadeDecorator);
+
+        fadeFrame.getComponentMouseListeners().add(new ComponentMouseListener() {
+            public boolean mouseMove(Component component, int x, int y) {
+                return false;
+            }
+
+            public void mouseOver(Component component) {
+                fadeDecorator.setOpacity(0.9f);
+                component.repaint();
+            }
+
+            public void mouseOut(Component component) {
+                fadeDecorator.setOpacity(0.5f);
+                component.repaint();
+            }
+        });
+
+        fadeFrame.setLocation(80, 80);
+        fadeFrame.open(display);
+    }
+
+    public boolean shutdown(boolean optional) {
+        reflectionWindow.close();
+        fadeFrame.close();
+        return true;
+    }
+
+    public void suspend() {
+    }
+
+    public void resume() {
+    }
+}

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/IMG_0767_2.jpg
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/IMG_0767_2.jpg?rev=754936&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/IMG_0767_2.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/reflection.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/reflection.wtkx?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/reflection.wtkx (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/reflection.wtkx Mon Mar 16 16:36:10 2009
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2008 VMware, Inc.
+
+Licensed 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.
+-->
+
+<ImageView image="@IMG_0767_2.jpg"
+    xmlns:wtkx="http://pivot-toolkit.org/wtkx/2008" xmlns="pivot.wtk"/>
+

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/translucent.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/translucent.wtkx?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/translucent.wtkx (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/decorator/translucent.wtkx Mon Mar 16 16:36:10 2009
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2008 VMware, Inc.
+
+Licensed 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.
+-->
+
+<FlowPane orientation="vertical" styles="{horizontalAlignment:'justify'}"
+    xmlns:wtkx="http://pivot-toolkit.org/wtkx/2008" xmlns="pivot.wtk">
+    <Label text="A Translucent Window"/>
+    <Border styles="{color:13, padding:0}">
+        <content>
+            <ListView listData="['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']"/>
+        </content>
+    </Border>
+</FlowPane>
+

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/FixedColumnTable.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/FixedColumnTable.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/FixedColumnTable.java (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/FixedColumnTable.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2008 VMware, Inc.
+ *
+ * Licensed 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 pivot.demos.tables;
+
+import pivot.collections.Dictionary;
+import pivot.wtk.Application;
+import pivot.wtk.Component;
+import pivot.wtk.Display;
+import pivot.wtk.SortDirection;
+import pivot.wtk.TableView;
+import pivot.wtk.TableViewHeader;
+import pivot.wtk.TableViewSelectionListener;
+import pivot.wtk.Window;
+import pivot.wtkx.WTKXSerializer;
+
+public class FixedColumnTable implements Application {
+    private Window window = null;
+
+    public void startup(Display display, Dictionary<String, String> properties)
+        throws Exception {
+        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+
+        Component content =
+            (Component)wtkxSerializer.readObject(getClass().getResource("fixed_column_table.wtkx"));
+
+        // Get references to the table views and table view headers
+        final TableView primaryTableView =
+            (TableView)wtkxSerializer.getObjectByName("primaryTableView");
+        final TableViewHeader primaryTableViewHeader =
+            (TableViewHeader)wtkxSerializer.getObjectByName("primaryTableViewHeader");
+
+        final TableView fixedTableView =
+            (TableView)wtkxSerializer.getObjectByName("fixedTableView");
+        final TableViewHeader fixedTableViewHeader =
+            (TableViewHeader)wtkxSerializer.getObjectByName("fixedTableViewHeader");
+
+        // Keep selection state in sync
+        primaryTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener() {
+            public void selectionChanged(TableView tableView) {
+                int selectedIndex = tableView.getSelectedIndex();
+                if (fixedTableView.getSelectedIndex() != selectedIndex) {
+                    fixedTableView.setSelectedIndex(selectedIndex);
+                }
+            }
+        });
+
+        fixedTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener() {
+            public void selectionChanged(TableView tableView) {
+                int selectedIndex = tableView.getSelectedIndex();
+                if (primaryTableView.getSelectedIndex() != selectedIndex) {
+                    primaryTableView.setSelectedIndex(selectedIndex);
+                }
+            }
+        });
+
+        // Keep header state in sync
+        primaryTableViewHeader.getTableViewHeaderPressListeners().add(new TableView.SortHandler() {
+            public void headerPressed(TableViewHeader tableViewHeader, int index) {
+                super.headerPressed(tableViewHeader, index);
+
+                TableView.ColumnSequence columns = fixedTableView.getColumns();
+                for (int i = 0, n = columns.getLength(); i < n; i++) {
+                    TableView.Column column = columns.get(i);
+                    column.setSortDirection((SortDirection)null);
+                }
+            }
+        });
+
+        fixedTableViewHeader.getTableViewHeaderPressListeners().add(new TableView.SortHandler() {
+            public void headerPressed(TableViewHeader tableViewHeader, int index) {
+                super.headerPressed(tableViewHeader, index);
+
+                TableView.ColumnSequence columns = primaryTableView.getColumns();
+                for (int i = 0, n = columns.getLength(); i < n; i++) {
+                    TableView.Column column = columns.get(i);
+                    column.setSortDirection((SortDirection)null);
+                }
+            }
+        });
+
+        // Open the window
+        window = new Window(content);
+        window.setTitle("Fixed Column Table Demo");
+        window.setMaximized(true);
+        window.open(display);
+    }
+
+    public boolean shutdown(boolean optional) {
+        window.close();
+        return true;
+    }
+
+    public void suspend() {
+    }
+
+    public void resume() {
+    }
+}

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/fixed_column_table.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/fixed_column_table.wtkx?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/fixed_column_table.wtkx (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/tables/fixed_column_table.wtkx Mon Mar 16 16:36:10 2009
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2008 VMware, Inc.
+
+Licensed 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.
+-->
+
+<Border styles="{color:10, padding:0}"
+    xmlns:wtkx="http://pivot-toolkit.org/wtkx/2008"
+    xmlns:collections="pivot.collections"
+    xmlns:content="pivot.wtk.content" xmlns="pivot.wtk">
+    <content>
+        <ScrollPane horizontalScrollBarPolicy="fillToCapacity">
+            <view>
+                <TableView wtkx:id="primaryTableView" selectMode="single"
+                    styles="{selectionColor:'#ffffff', inactiveSelectionColor:'#ffffff',
+                        selectionBackgroundColor:'#144f8b', inactiveSelectionBackgroundColor:'#144f8b',
+                        showHighlight:false}">
+                    <columns>
+                        <TableView.Column name="colA" headerData="Column A"/>
+                        <TableView.Column name="colB" headerData="Column B"/>
+                        <TableView.Column name="colC" headerData="Column C"/>
+                    </columns>
+                    <tableData>
+                        <collections:ArrayList wtkx:id="tableData">
+	                        <content:TableRow name="User 1" colA="1.A" colB="1.B" colC="1.C" />
+	                        <content:TableRow name="User 2" colA="2.A" colB="2.B" colC="2.C" />
+	                        <content:TableRow name="User 3" colA="3.A" colB="3.B" colC="3.C" />
+	                        <content:TableRow name="User 4" colA="4.A" colB="4.B" colC="4.C" />
+	                        <content:TableRow name="User 5" colA="5.A" colB="5.B" colC="5.C" />
+	                        <content:TableRow name="User 6" colA="6.A" colB="6.B" colC="6.C" />
+	                        <content:TableRow name="User 7" colA="7.A" colB="7.B" colC="7.C" />
+	                        <content:TableRow name="User 8" colA="8.A" colB="8.B" colC="8.C" />
+                        </collections:ArrayList>
+                    </tableData>
+                </TableView>
+            </view>
+            <columnHeader>
+                <TableViewHeader wtkx:id="primaryTableViewHeader" tableView="$primaryTableView"/>
+            </columnHeader>
+            <rowHeader>
+                <TableView wtkx:id="fixedTableView" tableData="$tableData" selectMode="single"
+                    styles="{selectionColor:'#ffffff', inactiveSelectionColor:'#ffffff',
+                        selectionBackgroundColor:'#144f8b', inactiveSelectionBackgroundColor:'#144f8b',
+                        showHighlight:false, includeTrailingVerticalGridLine:true}">
+                    <columns>
+                        <TableView.Column name="name" headerData="Name"/>
+                    </columns>
+                </TableView>
+            </rowHeader>
+            <corner>
+                <TableViewHeader wtkx:id="fixedTableViewHeader" tableView="$fixedTableView"
+                    styles="{includeTrailingVerticalGridLine:true}"/>
+            </corner>
+        </ScrollPane>
+    </content>
+</Border>

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/CollapseTransition.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/CollapseTransition.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/CollapseTransition.java (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/CollapseTransition.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,55 @@
+package pivot.demos.transition;
+
+import pivot.wtk.Component;
+import pivot.wtk.effects.FadeDecorator;
+import pivot.wtk.effects.Transition;
+import pivot.wtk.effects.TransitionListener;
+import pivot.wtk.effects.easing.Easing;
+import pivot.wtk.effects.easing.Quadratic;
+
+public class CollapseTransition extends Transition {
+    private Component component;
+    private int initialWidth;
+    private Easing easing = new Quadratic();
+    private FadeDecorator fadeDecorator = new FadeDecorator();
+
+    public CollapseTransition(Component component, int duration, int rate) {
+        super(duration, rate, false);
+
+        this.component = component;
+        initialWidth = component.getWidth();
+    }
+
+    @Override
+    public void start(TransitionListener transitionListener) {
+        component.getDecorators().add(fadeDecorator);
+
+        super.start(transitionListener);
+    }
+
+    @Override
+    public void stop() {
+        component.getDecorators().remove(fadeDecorator);
+
+        super.stop();
+    }
+
+    @Override
+    protected void update() {
+        float percentComplete = getPercentComplete();
+
+        if (percentComplete < 1.0f) {
+            int duration = getDuration();
+
+            int width = (int)((float)initialWidth * (1.0f - percentComplete));
+
+            width = (int)easing.easeInOut(getElapsedTime(), initialWidth, width - initialWidth, duration);
+            component.setPreferredWidth(width);
+
+            fadeDecorator.setOpacity(1.0f - percentComplete);
+            component.repaint();
+        } else {
+            component.getParent().remove(component);
+        }
+    }
+}

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/TransitionDemo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/TransitionDemo.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/TransitionDemo.java (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/TransitionDemo.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,60 @@
+package pivot.demos.transition;
+
+import pivot.collections.Dictionary;
+import pivot.wtk.Application;
+import pivot.wtk.Button;
+import pivot.wtk.ButtonPressListener;
+import pivot.wtk.Component;
+import pivot.wtk.Display;
+import pivot.wtk.Window;
+import pivot.wtkx.WTKXSerializer;
+
+public class TransitionDemo implements Application {
+    private Window window = null;
+
+    public void startup(Display display, Dictionary<String, String> properties)
+        throws Exception {
+        WTKXSerializer wtkxSerializer = new WTKXSerializer();
+
+        Component content =
+            (Component)wtkxSerializer.readObject(getClass().getResource("transition.wtkx"));
+
+        ButtonPressListener trigger = new ButtonPressListener() {
+            public void buttonPressed(Button button) {
+                button.setEnabled(false);
+
+                CollapseTransition transition = new CollapseTransition(button, 300, 30);
+                transition.start();
+            }
+        };
+
+        Button button1 = (Button)wtkxSerializer.getObjectByName("button1");
+        button1.getButtonPressListeners().add(trigger);
+
+        Button button2 = (Button)wtkxSerializer.getObjectByName("button2");
+        button2.getButtonPressListeners().add(trigger);
+
+        Button button3 = (Button)wtkxSerializer.getObjectByName("button3");
+        button3.getButtonPressListeners().add(trigger);
+
+        Button button4 = (Button)wtkxSerializer.getObjectByName("button4");
+        button4.getButtonPressListeners().add(trigger);
+
+        // Open the window
+        window = new Window(content);
+        window.setTitle("Transition Demo");
+        window.setMaximized(true);
+        window.open(display);
+    }
+
+    public boolean shutdown(boolean optional) {
+        window.close();
+        return true;
+    }
+
+    public void suspend() {
+    }
+
+    public void resume() {
+    }
+}

Added: incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/transition.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/transition.wtkx?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/transition.wtkx (added)
+++ incubator/pivot/tags/v1.0.1/demos/src/pivot/demos/transition/transition.wtkx Mon Mar 16 16:36:10 2009
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2008 VMware, Inc.
+
+Licensed 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.
+-->
+
+<FlowPane styles="{padding:4, spacing:4}"
+    xmlns:wtkx="http://pivot-toolkit.org/wtkx/2008" xmlns="pivot.wtk">
+    <PushButton wtkx:id="button1" buttonData="One"/>
+    <PushButton wtkx:id="button2" buttonData="Two"/>
+    <PushButton wtkx:id="button3" buttonData="Three"/>
+    <PushButton wtkx:id="button4" buttonData="Four"/>
+</FlowPane>

Added: incubator/pivot/tags/v1.0.1/junit.jar
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/junit.jar?rev=754936&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/pivot/tags/v1.0.1/junit.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/pivot/tags/v1.0.1/tools/.classpath
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/.classpath?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/.classpath (added)
+++ incubator/pivot/tags/v1.0.1/tools/.classpath Mon Mar 16 16:36:10 2009
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/wtk"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/tutorials"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: incubator/pivot/tags/v1.0.1/tools/.project
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/.project?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/.project (added)
+++ incubator/pivot/tags/v1.0.1/tools/.project Mon Mar 16 16:36:10 2009
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>tools</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: incubator/pivot/tags/v1.0.1/tools/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/.settings/org.eclipse.jdt.core.prefs?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/.settings/org.eclipse.jdt.core.prefs (added)
+++ incubator/pivot/tags/v1.0.1/tools/.settings/org.eclipse.jdt.core.prefs Mon Mar 16 16:36:10 2009
@@ -0,0 +1,12 @@
+#Sat Aug 16 12:31:17 EDT 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5

Added: incubator/pivot/tags/v1.0.1/tools/Explorer.launch
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/Explorer.launch?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/Explorer.launch (added)
+++ incubator/pivot/tags/v1.0.1/tools/Explorer.launch Mon Mar 16 16:36:10 2009
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/wtk/src/pivot/wtk/DesktopApplicationContext.java"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="pivot.wtk.DesktopApplicationContext"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="pivot.tools.explorer.Explorer applicationClassName:pivot.tutorials.Demo"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tools"/>
+</launchConfiguration>

Added: incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentAdapter.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentAdapter.java (added)
+++ incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentAdapter.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,103 @@
+package pivot.tools.explorer;
+
+import java.net.URL;
+import java.util.Iterator;
+
+import pivot.beans.BeanDictionary;
+import pivot.collections.ArrayList;
+import pivot.collections.List;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentInfo;
+import pivot.wtk.Component.Attributes;
+import pivot.wtk.Component.StyleDictionary;
+
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.media.Image;
+
+public class ComponentAdapter {
+    private Component component;
+    private List<TableEntryAdapter> properties, styles, attributes;
+
+    public ComponentAdapter(Component component) {
+        if (component == null) {
+            throw new IllegalArgumentException( "Component cannot be null");
+        }
+
+        this.component = component;
+    }
+
+    public Component getComponent() {
+        return component;
+    }
+
+    public List<TableEntryAdapter> getProperties() {
+        if (properties == null) {
+
+            BeanDictionary beanDictionary = new BeanDictionary(component, true);
+            properties = new ArrayList<TableEntryAdapter>( TableEntryAdapter.COMPARATOR );
+
+            for ( String s: beanDictionary ) {
+                properties.add( new TableEntryAdapter( beanDictionary, s ));
+            }
+        }
+
+        return properties;
+    }
+
+    public List<TableEntryAdapter> getStyles() {
+        if (styles == null) {
+            styles = new ArrayList<TableEntryAdapter>( TableEntryAdapter.COMPARATOR );
+            StyleDictionary sd = component.getStyles();
+            Iterator<String> i = sd.iterator();
+            while( i.hasNext() ) {
+                styles.add( new TableEntryAdapter( component.getStyles(), i.next() ));
+            }
+        }
+        return styles;
+    }
+
+    public List<TableEntryAdapter> getAttributes() {
+        if (attributes == null) {
+
+            attributes = new ArrayList<TableEntryAdapter>(TableEntryAdapter.COMPARATOR);
+            Attributes attrs = component.getAttributes();
+            if (attrs != null) {
+                BeanDictionary beanDictionary = new BeanDictionary(attrs);
+                for ( String s: beanDictionary ) {
+                    attributes.add( new TableEntryAdapter(beanDictionary, s));
+                }
+            }
+
+
+        }
+        return attributes;
+    }
+
+
+    @Override
+    public String toString() {
+        return component.getClass().getSimpleName();
+    }
+
+    public Image getIcon() {
+        ComponentInfo componentInfo = component.getClass().getAnnotation(ComponentInfo.class);
+        URL iconURL = component.getClass().getResource(componentInfo != null ?
+            componentInfo.icon() : "component.png");
+
+        Image icon = null;
+
+        if (iconURL != null) {
+            icon = (Image)ApplicationContext.getResourceCache().get(iconURL);
+            if (icon == null) {
+                icon = Image.load(iconURL);
+                ApplicationContext.getResourceCache().put(iconURL, icon);
+            }
+        }
+
+        return icon;
+    }
+
+    public String getText() {
+        return toString() + (component.isDisplayable()? "": " (hidden)");
+    }
+}

Added: incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlightDecorator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlightDecorator.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlightDecorator.java (added)
+++ incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlightDecorator.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,42 @@
+/**
+ *
+ */
+package pivot.tools.explorer;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+import pivot.wtk.Component;
+import pivot.wtk.effects.ShadeDecorator;
+
+/**
+ * Currently based on ShadDecorator
+ * plus slightly darker border around the component
+ *
+ * @author Eugene Ryzhikov
+ * @date   Sep 10, 2008
+ *
+ */
+final class ComponentHighlightDecorator extends ShadeDecorator {
+
+	private Graphics2D graphics;
+	private Component component;
+
+	ComponentHighlightDecorator(float opacity, Color color) {
+		super(opacity, color);
+	}
+
+	@Override
+    public void update() {
+		super.update();
+        graphics.setColor(getColor().darker().darker());
+        graphics.drawRect(0, 0, component.getWidth()-1, component.getHeight()-1);
+    }
+
+	@Override
+	public Graphics2D prepare(Component component, Graphics2D graphics) {
+		this.component = component;
+		return this.graphics = super.prepare(component, graphics);
+	}
+
+}
\ No newline at end of file

Added: incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlighter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlighter.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlighter.java (added)
+++ incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ComponentHighlighter.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,69 @@
+/**
+ *
+ */
+package pivot.tools.explorer;
+
+import java.awt.Color;
+
+import pivot.collections.List;
+import pivot.collections.Sequence;
+import pivot.wtk.Component;
+import pivot.wtk.ComponentMouseListener;
+import pivot.wtk.Decorator;
+import pivot.wtk.TreeView;
+
+
+/**
+ * Mouse Listener to highlight components under mouse
+ *
+ * @author Eugene Ryzhikov
+ * @date   Sep 10, 2008
+ *
+ */
+//TODO: Color and opacity should come from preferences
+final class ComponentHighlighter implements ComponentMouseListener {
+
+	private final TreeView tree;
+	private Decorator componentDecorator = new ComponentHighlightDecorator(0.33f, Color.CYAN.brighter());
+	private Component lastDecoratedComponent;
+
+	public ComponentHighlighter(TreeView tree) {
+		this.tree = tree;
+	}
+
+	public boolean mouseMove(Component component, int x, int y) {
+		if (component == tree) {
+			Sequence<Integer> nodePath = tree.getNodeAt(y);
+
+			if (nodePath.getLength() != 0) {
+			    List<?> treeData = tree.getTreeData();
+				ComponentAdapter componentAdapter = (ComponentAdapter)Sequence.Tree.get(treeData, nodePath);
+
+				highlightComponent(componentAdapter.getComponent());
+				return false;
+			}
+		}
+		highlightComponent(null);
+		return false;
+	}
+
+	public void mouseOut(Component component) {
+		highlightComponent(null);
+	}
+
+	public void mouseOver(Component component) {}
+
+	private void highlightComponent(Component component) {
+
+		if (lastDecoratedComponent != null) {
+			lastDecoratedComponent.getDecorators().remove(componentDecorator);
+		}
+
+		lastDecoratedComponent = component;
+
+		if (lastDecoratedComponent != null) {
+			lastDecoratedComponent.getDecorators().add(componentDecorator);
+		}
+
+	}
+}
\ No newline at end of file

Added: incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ContainerAdapter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ContainerAdapter.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ContainerAdapter.java (added)
+++ incubator/pivot/tags/v1.0.1/tools/src/pivot/tools/explorer/ContainerAdapter.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,97 @@
+package pivot.tools.explorer;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.collections.ArrayList;
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.ImmutableIterator;
+import pivot.util.ListenerList;
+import pivot.wtk.Component;
+import pivot.wtk.Container;
+
+public class ContainerAdapter extends ComponentAdapter
+    implements List<ComponentAdapter> {
+    public ContainerAdapter(Container container) {
+        super(container);
+
+        for (Component c : container) {
+            add(c instanceof Container ? new ContainerAdapter((Container)c) : new ComponentAdapter(c));
+        }
+    }
+
+    private ArrayList<ComponentAdapter> componentAdapters = new ArrayList<ComponentAdapter>();
+    private ListListenerList<ComponentAdapter> listListeners = new ListListenerList<ComponentAdapter>();
+
+    public int add(ComponentAdapter componentAdapter) {
+        int index = componentAdapters.getLength();
+        insert(componentAdapter, index);
+
+        return index;
+    }
+
+    public void insert(ComponentAdapter componentAdapter, int index) {
+        componentAdapters.insert(componentAdapter, index);
+        listListeners.itemInserted(this, index);
+    }
+
+    public ComponentAdapter update(int index, ComponentAdapter componentAdapter) {
+        ComponentAdapter previousComponentAdapter = componentAdapters.update(index, componentAdapter);
+        listListeners.itemUpdated(this, index, previousComponentAdapter);
+
+        return previousComponentAdapter;
+    }
+
+    public int remove(ComponentAdapter componentAdapter) {
+        int index = componentAdapters.indexOf(componentAdapter);
+        if (index != -1) {
+            remove(index, 1);
+        }
+
+        return index;
+    }
+
+    public Sequence<ComponentAdapter> remove(int index, int count) {
+        Sequence<ComponentAdapter> removed = componentAdapters.remove(index, count);
+        listListeners.itemsRemoved(this, index, removed);
+
+        return removed;
+    }
+
+    public void clear() {
+        componentAdapters.clear();
+        listListeners.itemsRemoved(this, 0, null);
+    }
+
+    public ComponentAdapter get(int index) {
+        return componentAdapters.get(index);
+    }
+
+    public int indexOf(ComponentAdapter componentAdapter) {
+        return componentAdapters.indexOf(componentAdapter);
+    }
+
+    public int getLength() {
+        return componentAdapters.getLength();
+    }
+
+    public Comparator<ComponentAdapter> getComparator() {
+        return componentAdapters.getComparator();
+    }
+
+    public void setComparator(Comparator<ComponentAdapter> comparator) {
+        Comparator<ComponentAdapter> previousComparator = componentAdapters.getComparator();
+        componentAdapters.setComparator(comparator);
+        listListeners.comparatorChanged(this, previousComparator);
+    }
+
+    public Iterator<ComponentAdapter> iterator() {
+        return new ImmutableIterator<ComponentAdapter>(componentAdapters.iterator());
+    }
+
+    public ListenerList<ListListener<ComponentAdapter>> getListListeners() {
+        return listListeners;
+    }
+}