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 [22/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/c...

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,56 @@
+/*
+ * 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.wtk;
+
+import pivot.collections.List;
+
+/**
+ * Tree view listener interface.
+ *
+ * @author gbrown
+ */
+public interface TreeViewListener {
+    /**
+     * Called when a tree view's data has changed.
+     *
+     * @param treeView
+     * @param previousTreeData
+     */
+    public void treeDataChanged(TreeView treeView, List<?> previousTreeData);
+
+    /**
+     * Called when a tree view's node renderer has changed.
+     *
+     * @param treeView
+     * @param previousNodeRenderer
+     */
+    public void nodeRendererChanged(TreeView treeView, TreeView.NodeRenderer previousNodeRenderer);
+
+    /**
+     * Called when a tree view's select mode has changed.
+     *
+     * @param treeView
+     * @param previousSelectMode
+     */
+    public void selectModeChanged(TreeView treeView, TreeView.SelectMode previousSelectMode);
+
+    /**
+     * Called when a tree view's check enabled flag has changed.
+     *
+     * @param treeView
+     */
+    public void checkEnabledChanged(TreeView treeView);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.wtk;
+
+import pivot.collections.Sequence;
+
+/**
+ * Tree view node listener interface.
+ *
+ * @author gbrown
+ */
+public interface TreeViewNodeListener {
+    /**
+     * Called when a node has been inserted into the tree view.
+     *
+     * @param treeView
+     * @param path
+     * @param index
+     */
+    public void nodeInserted(TreeView treeView, Sequence<Integer> path, int index);
+
+    /**
+     * Called when nodes have been removed from the tree view.
+     *
+     * @param treeView
+     * @param path
+     * @param index
+     * @param count
+     * The number of nodes that were removed, or <tt>-1</tt> if all nodes
+     * were removed.
+     */
+    public void nodesRemoved(TreeView treeView, Sequence<Integer> path, int index, int count);
+
+    /**
+     * Called when a node in the tree view has been updated.
+     *
+     * @param treeView
+     * @param path
+     * @param index
+     */
+    public void nodeUpdated(TreeView treeView, Sequence<Integer> path, int index);
+
+    /**
+     * Called when the nodes in a branch have been sorted.
+     *
+     * @param treeView
+     * @param path
+     */
+    public void nodesSorted(TreeView treeView, Sequence<Integer> path);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeStateListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeStateListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeStateListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewNodeStateListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,52 @@
+/*
+ * 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.wtk;
+
+import pivot.collections.Sequence;
+import pivot.util.Vote;
+
+/**
+ * Tree view node state listener interface.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public interface TreeViewNodeStateListener {
+    /**
+     * Called to preview a node disabled change event.
+     *
+     * @param treeView
+     * @param path
+     */
+    public Vote previewNodeDisabledChange(TreeView treeView, Sequence<Integer> path);
+
+    /**
+     * Called when a node disabled change event has been vetoed.
+     *
+     * @param treeView
+     * @param path
+     * @param reason
+     */
+    public void nodeDisabledChangeVetoed(TreeView treeView, Sequence<Integer> path, Vote reason);
+
+    /**
+     * Called when a node's disabled state has changed.
+     *
+     * @param treeView
+     * @param path
+     */
+    public void nodeDisabledChanged(TreeView treeView, Sequence<Integer> path);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionDetailListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionDetailListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionDetailListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionDetailListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,50 @@
+/*
+ * 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.wtk;
+
+import pivot.collections.Sequence;
+
+/**
+ * Tree view selection detail listener.
+ *
+ * @author gbrown
+ */
+public interface TreeViewSelectionDetailListener {
+    /**
+     * Called when a selected path has been added to a tree view.
+     *
+     * @param treeView
+     * @param path
+     */
+    public void selectedPathAdded(TreeView treeView, Sequence<Integer> path);
+
+    /**
+     * Called when a selected path has been removed from a tree view.
+     *
+     * @param treeView
+     * @param path
+     */
+    public void selectedPathRemoved(TreeView treeView, Sequence<Integer> path);
+
+    /**
+     * Called when a tree view's selection state has been reset.
+     *
+     * @param treeView
+     * @param previousSelectedPaths
+     */
+    public void selectionReset(TreeView treeView,
+        Sequence<Sequence<Integer>> previousSelectedPaths);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/TreeViewSelectionListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,30 @@
+/*
+ * 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.wtk;
+
+/**
+ * Tree view selection listener interface.
+ *
+ * @author gbrown
+ */
+public interface TreeViewSelectionListener {
+    /**
+     * Called when a tree view's selection has changed.
+     *
+     * @param treeView
+     */
+    public void selectionChanged(TreeView treeView);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/VerticalAlignment.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/VerticalAlignment.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/VerticalAlignment.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/VerticalAlignment.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,32 @@
+/*
+ * 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.wtk;
+
+/**
+ * Enumeration representing vertical alignment values.
+ *
+ * @author gbrown
+ */
+public enum VerticalAlignment {
+    TOP,
+    BOTTOM,
+    CENTER,
+    JUSTIFY;
+
+    public static VerticalAlignment decode(String value) {
+        return valueOf(value.toUpperCase());
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Viewport.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Viewport.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Viewport.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Viewport.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,156 @@
+/*
+ * 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.wtk;
+
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+
+/**
+ * Abstract base class for viewport components. Viewports provide a windowed
+ * view on a component (called the "view") that is too large to fit within a
+ * given area. They are generally scrollable.
+ *
+ * @author tvolkert
+ */
+public abstract class Viewport extends Container {
+    /**
+     * Viewport skin interface. Viewport skins must implement this.
+     *
+     * @author tvolkert
+     */
+    public interface Skin {
+        public Bounds getViewportBounds();
+    }
+
+    private static class ViewportListenerList extends ListenerList<ViewportListener>
+        implements ViewportListener {
+
+        public void scrollTopChanged(Viewport viewport, int previousScrollTop) {
+            for (ViewportListener listener : this) {
+                listener.scrollTopChanged(viewport, previousScrollTop);
+            }
+        }
+
+        public void scrollLeftChanged(Viewport viewport, int previousScrollLeft) {
+            for (ViewportListener listener : this) {
+                listener.scrollLeftChanged(viewport, previousScrollLeft);
+            }
+        }
+
+        public void viewChanged(Viewport viewport, Component previousView) {
+            for (ViewportListener listener : this) {
+                listener.viewChanged(viewport, previousView);
+            }
+        }
+    }
+
+    private int scrollTop = 0;
+    private int scrollLeft = 0;
+    private Component view;
+    private ViewportListenerList viewportListeners = new ViewportListenerList();
+
+    @Override
+    protected void setSkin(pivot.wtk.Skin skin) {
+        if (!(skin instanceof Viewport.Skin)) {
+            throw new IllegalArgumentException("Skin class must implement "
+                + Viewport.Skin.class.getName());
+        }
+
+        super.setSkin(skin);
+    }
+
+    public int getScrollTop() {
+        return scrollTop;
+    }
+
+    public void setScrollTop(int scrollTop) {
+        if (scrollTop < 0) {
+            throw new IllegalArgumentException("Scroll top must be positive");
+        }
+
+        int previousScrollTop = this.scrollTop;
+
+        if (scrollTop != previousScrollTop) {
+            this.scrollTop = scrollTop;
+            viewportListeners.scrollTopChanged(this, previousScrollTop);
+        }
+    }
+
+    public int getScrollLeft() {
+        return scrollLeft;
+    }
+
+    public void setScrollLeft(int scrollLeft) {
+        if (scrollLeft < 0) {
+            throw new IllegalArgumentException("Scroll left must be positive");
+        }
+
+        int previousScrollLeft = this.scrollLeft;
+
+        if (scrollLeft != previousScrollLeft) {
+            this.scrollLeft = scrollLeft;
+            viewportListeners.scrollLeftChanged(this, previousScrollLeft);
+        }
+    }
+
+    public Component getView() {
+        return view;
+    }
+
+    public void setView(Component view) {
+       Component previousView = this.view;
+
+        if (view != previousView) {
+            // Remove any previous view component
+            this.view = null;
+
+            if (previousView != null) {
+                remove(previousView);
+            }
+
+            // Set the new view component
+            if (view != null) {
+                insert(view, 0);
+            }
+
+            this.view = view;
+
+            viewportListeners.viewChanged(this, previousView);
+        }
+    }
+
+    public Bounds getViewportBounds() {
+        Viewport.Skin viewportSkin = (Viewport.Skin)getSkin();
+        return viewportSkin.getViewportBounds();
+    }
+
+    @Override
+    public Sequence<Component> remove(int index, int count) {
+        for (int i = index, n = index + count; i < n; i++) {
+            Component component = get(i);
+            if (component == view) {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // Call the base method to remove the components
+        return super.remove(index, count);
+    }
+
+    public ListenerList<ViewportListener> getViewportListeners() {
+        return viewportListeners;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/ViewportListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/ViewportListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/ViewportListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/ViewportListener.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.wtk;
+
+/**
+ * Viewport listener interface.
+ *
+ * @author tvolkert
+ */
+public interface ViewportListener {
+    /**
+     * Called when a viewport's scroll top has changed.
+     *
+     * @param scrollPane
+     * @param previousScrollTop
+     */
+    public void scrollTopChanged(Viewport scrollPane, int previousScrollTop);
+
+    /**
+     * Called when a viewport's scroll left has changed.
+     *
+     * @param scrollPane
+     * @param previousScrollLeft
+     */
+    public void scrollLeftChanged(Viewport scrollPane, int previousScrollLeft);
+
+    /**
+     * Called when a viewport's view component has changed.
+     *
+     * @param scrollPane
+     * @param previousView
+     */
+    public void viewChanged(Viewport scrollPane, Component previousView);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Visual.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Visual.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Visual.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Visual.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,44 @@
+/*
+ * 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.wtk;
+
+import java.awt.Graphics2D;
+
+/**
+ * Interface representing a "visual". A visual is an object that can be drawn
+ * to the screen or other output device.
+ *
+ * @author gbrown
+ */
+public interface Visual {
+    /**
+     * Returns the visual's width.
+     */
+    public int getWidth();
+
+    /**
+     * Returns the visual's height.
+     */
+    public int getHeight();
+
+    /**
+     * Paints the visual.
+     *
+     * @param graphics
+     * The graphics context in which to paint the visual.
+     */
+    public void paint(Graphics2D graphics);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Window.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Window.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Window.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/Window.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,951 @@
+/*
+ * 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.wtk;
+
+import java.net.URL;
+
+import pivot.collections.ArrayList;
+import pivot.collections.ArrayStack;
+import pivot.collections.Dictionary;
+import pivot.collections.HashMap;
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+import pivot.util.Vote;
+import pivot.wtk.media.Image;
+
+/**
+ * Top-level container representing the entry point into a user interface.
+ * Windows are direct descendants of the display.
+ *
+ * @author gbrown
+ */
+public class Window extends Container {
+    /**
+     * Action dictionary implementation.
+     *
+     * @author gbrown
+     */
+    public final class ActionDictionary
+        implements Dictionary<Keyboard.KeyStroke, Action> {
+        private ActionDictionary() {
+        }
+
+        public Action get(Keyboard.KeyStroke key) {
+            return actions.get(key);
+        }
+
+        public Action put(Keyboard.KeyStroke key, Action value) {
+            return actions.put(key, value);
+
+            // TODO Fire WindowActionListener#actionAdded()/actionUpdated()
+        }
+
+        public Action remove(Keyboard.KeyStroke key) {
+            return actions.remove(key);
+
+            // TODO Fire WindowActionListener#actionRemoved()
+        }
+
+        public boolean containsKey(Keyboard.KeyStroke key) {
+            return actions.containsKey(key);
+        }
+
+        public boolean isEmpty() {
+            return actions.isEmpty();
+        }
+    }
+
+    /**
+     * Window listener list.
+     *
+     * @author gbrown
+     */
+    private static class WindowListenerList extends ListenerList<WindowListener>
+        implements WindowListener {
+        public void titleChanged(Window window, String previousTitle) {
+            for (WindowListener listener : this) {
+                listener.titleChanged(window, previousTitle);
+            }
+        }
+
+        public void iconChanged(Window window, Image previousIcon) {
+            for (WindowListener listener : this) {
+                listener.iconChanged(window, previousIcon);
+            }
+        }
+
+        public void contentChanged(Window window, Component previousContent) {
+            for (WindowListener listener : this) {
+                listener.contentChanged(window, previousContent);
+            }
+        }
+
+        public void ownerChanged(Window window, Window previousOwner) {
+            for (WindowListener listener : this) {
+                listener.ownerChanged(window, previousOwner);
+            }
+        }
+
+        public void activeChanged(Window window) {
+            for (WindowListener listener : this) {
+                listener.activeChanged(window);
+            }
+        }
+
+        public void maximizedChanged(Window window) {
+            for (WindowListener listener : this) {
+                listener.maximizedChanged(window);
+            }
+        }
+    }
+
+    /**
+     * Window state listener list.
+     *
+     * @author gbrown
+     */
+    private static class WindowStateListenerList extends ListenerList<WindowStateListener>
+        implements WindowStateListener {
+        public Vote previewWindowOpen(Window window, Display display) {
+            Vote vote = Vote.APPROVE;
+
+            for (WindowStateListener listener : this) {
+                vote = vote.tally(listener.previewWindowOpen(window, display));
+            }
+
+            return vote;
+        }
+
+        public void windowOpenVetoed(Window window, Vote reason) {
+            for (WindowStateListener listener : this) {
+                listener.windowOpenVetoed(window, reason);
+            }
+        }
+
+        public void windowOpened(Window window) {
+            for (WindowStateListener listener : this) {
+                listener.windowOpened(window);
+            }
+        }
+
+        public Vote previewWindowClose(Window window) {
+            Vote vote = Vote.APPROVE;
+
+            for (WindowStateListener listener : this) {
+                vote = vote.tally(listener.previewWindowClose(window));
+            }
+
+            return vote;
+        }
+
+        public void windowCloseVetoed(Window window, Vote reason) {
+            for (WindowStateListener listener : this) {
+                listener.windowCloseVetoed(window, reason);
+            }
+        }
+
+        public void windowClosed(Window window, Display display) {
+            for (WindowStateListener listener : this) {
+                listener.windowClosed(window, display);
+            }
+        }
+    }
+
+    /**
+     * Window class listener list.
+     *
+     * @author tvolkert
+     */
+    private static class WindowClassListenerList
+        extends ListenerList<WindowClassListener>
+        implements WindowClassListener {
+        public void activeWindowChanged(Window previousActiveWindow) {
+            for (WindowClassListener listener : this) {
+                listener.activeWindowChanged(previousActiveWindow);
+            }
+        }
+    }
+
+    private Window owner = null;
+    private ArrayList<Window> ownedWindows = new ArrayList<Window>();
+
+    private HashMap<Keyboard.KeyStroke, Action> actions = new HashMap<Keyboard.KeyStroke, Action>();
+    private ActionDictionary actionDictionary = new ActionDictionary();
+
+    private String title = null;
+    private Image icon = null;
+    private Component content = null;
+    private Component activeDescendant = null;
+
+    private boolean opening = false;
+    private boolean closing = false;
+
+    private boolean maximized = false;
+
+    private WindowListenerList windowListeners = new WindowListenerList();
+    private WindowStateListenerList windowStateListeners = new WindowStateListenerList();
+    private static WindowClassListenerList windowClassListeners = new WindowClassListenerList();
+
+    private static Window activeWindow = null;
+
+    public Window() {
+        this(null, null);
+    }
+
+    public Window(String title) {
+        this(title, null);
+    }
+
+    public Window(Component content) {
+        this(null, content);
+    }
+
+    public Window(String title, Component content) {
+        setTitle(title);
+        setContent(content);
+        installSkin(Window.class);
+    }
+
+    @Override
+    protected void setParent(Container parent) {
+        if (parent != null
+            && (!(parent instanceof Display))) {
+            throw new IllegalArgumentException("Window parent must be null or display.");
+        }
+
+        if (parent == null
+            && isActive()) {
+            setActiveWindow(null);
+        }
+
+        super.setParent(parent);
+    }
+
+    @Override
+    public Sequence<Component> remove(int index, int count) {
+        for (int i = index, n = index + count; i < n; i++) {
+            Component component = get(i);
+            if (component == content) {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // Call the base method to remove the components
+        return super.remove(index, count);
+    }
+
+    /**
+     * Sets the displayable state of this window and all of its owned
+     * descendant windows.
+     *
+     * @param displayable
+     * If <tt>true</tt>, the window and its owned descendants are displayable;
+     * otherwise, they are not displayable.
+     */
+    @Override
+    public void setDisplayable(boolean displayable) {
+        super.setDisplayable(displayable);
+
+        if (!displayable) {
+            if (isActive()) {
+                setActiveWindow(null);
+            }
+        }
+
+        // Show/hide owned windows
+        for (Window ownedWindow : ownedWindows) {
+            ownedWindow.setDisplayable(displayable);
+        }
+    }
+
+    /**
+     * Sets the enabled state of this window and all of its owned
+     * descendant windows.
+     *
+     * @param enabled
+     * If <tt>true</tt>, the window and its owned descendants are enabled;
+     * otherwise, they are not enabled.
+     */
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (isEnabled() != enabled) {
+            super.setEnabled(enabled);
+
+            if (isEnabled() == enabled) {
+                if (!enabled
+                    && isActive()) {
+                    setActiveWindow(null);
+                }
+
+                // Enable/disable owned windows
+                for (Window ownedWindow : ownedWindows) {
+                    ownedWindow.setEnabled(enabled);
+                }
+            }
+        }
+    }
+
+    public Window getOwner() {
+        return owner;
+    }
+
+    public void setOwner(Window owner) {
+        if (owner != null
+            && owner.isAuxilliary()
+            && !isAuxilliary()) {
+            throw new IllegalArgumentException("Primary windows must have a"
+                + " primary owner.");
+        }
+
+        Window previousOwner = this.owner;
+
+        if (previousOwner != owner) {
+            if (previousOwner != null) {
+                previousOwner.ownedWindows.remove(this);
+            }
+
+            if (owner != null) {
+                owner.ownedWindows.add(this);
+                setDisplayable(owner.isDisplayable());
+                setEnabled(owner.isEnabled());
+            }
+
+            this.owner = owner;
+
+            windowListeners.ownerChanged(this, previousOwner);
+        }
+    }
+
+    public Window getRootOwner() {
+        return (owner == null) ? this : owner.getRootOwner();
+    }
+
+    public Window getOwnedWindow(int index) {
+        return ownedWindows.get(index);
+    }
+
+    public int getOwnedWindowCount() {
+        return ownedWindows.getLength();
+    }
+
+    public boolean isOwningAncestorOf(Window window) {
+        Window owner = window;
+
+        while (owner != null
+            && owner != this) {
+            owner = owner.getOwner();
+        }
+
+        return (owner == this);
+    }
+
+    /**
+     * Returns this window's open state.
+     *
+     * @return
+     * <tt>true</tt> if the window is open; <tt>false</tt>, otherwise.
+     */
+    public boolean isOpen() {
+        return (getParent() != null);
+    }
+
+    /**
+     * Returns this window's opening state.
+     *
+     * @return
+     * <tt>true</tt> if the window is open; <tt>false</tt>, otherwise.
+     */
+    public boolean isOpening() {
+        return opening;
+    }
+
+    /**
+     * Opens the window. Opening a window adds it to the display's component
+     * sequence. If the window is activatable, it will become the active
+     * window.
+     *
+     * @param display
+     * The display on which the window will be opened.
+     */
+    public void open(Display display) {
+        if (display == null) {
+            throw new IllegalArgumentException("display is null.");
+        }
+
+        if (isOpen()
+            && getDisplay() != display) {
+            throw new IllegalStateException("Window is already open on a different display.");
+        }
+
+        if (owner != null
+            && !owner.isOpen()) {
+            throw new IllegalArgumentException("Owner is not open.");
+        }
+
+        if (owner != null
+            && owner.getDisplay() != display) {
+            throw new IllegalArgumentException("Owner is opened on a different display.");
+        }
+
+        if (!isOpen()
+            && !opening) {
+            Vote vote = windowStateListeners.previewWindowOpen(this, display);
+
+            if (vote == Vote.APPROVE) {
+                opening = true;
+
+                // Add this as child of display
+                display.add(this);
+
+                // Notify listeners
+                windowStateListeners.windowOpened(this);
+
+                // Move this window to the front (which, unless this window is
+                // disabled or incapable of becoming active, will activate the
+                // window)
+                moveToFront();
+
+                opening = false;
+            } else {
+                windowStateListeners.windowOpenVetoed(this, vote);
+            }
+        }
+    }
+
+    /**
+     * Opens the window.
+     *
+     * @param owner
+     * The window's owner.
+     */
+    public void open(Window owner) {
+        if (owner == null) {
+            throw new IllegalArgumentException("owner is null.");
+        }
+
+        if (isOpen()
+            && getOwner() != owner) {
+            throw new IllegalStateException("Window is already open with a different owner.");
+        }
+
+        setOwner(owner);
+        open(owner.getDisplay());
+    }
+
+    /**
+     * Returns this window's closed state.
+     *
+     * @return
+     * <tt>true</tt> if the window is closed; <tt>false</tt>, otherwise.
+     */
+    public boolean isClosed() {
+        return !isOpen();
+    }
+
+    /**
+     * Returns this window's closing state.
+     *
+     * @return
+     * <tt>true</tt> if the window is closing; <tt>false</tt>, otherwise.
+     */
+    public boolean isClosing() {
+        return closing;
+    }
+
+    /**
+     * Closes the window. Closing a window closes all owned windows and
+     * removes the window from the display's component sequence. If the window
+     * was the active window, the active window will be cleared. If the window
+     * was the focus host, the focused component will be cleared.
+     */
+    public void close() {
+        if (!isClosed()
+            && !closing) {
+            Vote vote = windowStateListeners.previewWindowClose(this);
+
+            if (vote.isApproved()) {
+                closing = true;
+
+                if (isActive()) {
+                    setActiveWindow(null);
+                }
+
+                // Close all owned windows (create a copy of the owned window
+                // list so owned windows can remove themselves from the list
+                // without interrupting the iteration)
+                for (Window ownedWindow : new ArrayList<Window>(this.ownedWindows)) {
+                    ownedWindow.close();
+                }
+
+                // Detach from display
+                Display display = getDisplay();
+                display.remove(this);
+
+                // Notify listeners
+                windowStateListeners.windowClosed(this, display);
+
+                closing = false;
+            } else {
+                windowStateListeners.windowCloseVetoed(this, vote);
+            }
+        }
+    }
+
+    /**
+     * Returns the window's title.
+     *
+     * @return
+     * The pane's title, or <tt>null</tt> if no title is set.
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Sets the window's title.
+     *
+     * @param title
+     * The new title, or <tt>null</tt> for no title.
+     */
+    public void setTitle(String title) {
+        String previousTitle = this.title;
+
+        if (previousTitle == null ^ title == null) {
+            this.title = title;
+            windowListeners.titleChanged(this, previousTitle);
+        }
+    }
+
+    /**
+     * Returns the window's icon.
+     *
+     * @return
+     * The window's icon, or <tt>null</tt> if the window has no icon.
+     */
+    public Image getIcon() {
+        return icon;
+    }
+
+    /**
+     * Sets the window's icon.
+     *
+     * @param icon
+     * The window's icon, or <tt>null</tt> for no icon.
+     */
+    public void setIcon(Image icon) {
+        Image previousIcon = this.icon;
+
+        if (previousIcon != icon) {
+            this.icon = icon;
+            windowListeners.iconChanged(this, previousIcon);
+        }
+    }
+
+    /**
+     * Sets the window's icon by URL.
+     *
+     * @param icon
+     * The location of the icon to set.
+     */
+    public void setIcon(URL icon) {
+        if (icon == null) {
+            throw new IllegalArgumentException("icon is null.");
+        }
+
+        setIcon(Image.load(icon));
+    }
+
+    /**
+     * Sets the window's icon by resource name.
+     *
+     * @param icon
+     * The resource name of the icon to set.
+     */
+    public void setIcon(String icon) {
+        if (icon == null) {
+            throw new IllegalArgumentException("icon is null.");
+        }
+
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        setIcon(classLoader.getResource(icon));
+    }
+
+    public Component getContent() {
+        return content;
+    }
+
+    public void setContent(Component content) {
+        Component previousContent = this.content;
+
+        if (content != previousContent) {
+            this.content = null;
+
+            // Remove any previous content component
+            if (previousContent != null) {
+                remove(previousContent);
+            }
+
+            // Add the component
+            if (content != null) {
+                insert(content, 0);
+            }
+
+            this.content = content;
+
+            windowListeners.contentChanged(this, previousContent);
+        }
+    }
+
+    /**
+     * Returns the window's auxilliary state. Auxilliary windows must have an
+     * owner, can't become active, and can only own other auxilliary windows.
+     *
+     * @return
+     * <tt>true</tt> if this is an auxilliary window; <tt>false</tt>, otherwise.
+     */
+    public boolean isAuxilliary() {
+        return false;
+    }
+
+    /**
+     * Returns the window's active state.
+     *
+     * @return
+     * <tt>true</tt> if the window is active; <tt>false</tt>; otherwise.
+     */
+    public boolean isActive() {
+        return activeWindow == this;
+    }
+
+    /**
+     * Called to notify a window that its active state has changed.
+     *
+     * @param active
+     */
+    protected void setActive(boolean active) {
+        if (active) {
+            // If this window is still an ancestor of the active descendant
+            // and the active descendant can be focused, restore focus to it;
+            // otherwise, clear the active descendant
+            if (activeDescendant != null) {
+                if (isAncestor(activeDescendant)
+                    && !activeDescendant.isBlocked()
+                    && activeDescendant.isShowing()) {
+                    activeDescendant.requestFocus(true);
+                } else {
+                    activeDescendant = null;
+                }
+            }
+        } else {
+            // Temporarily clear the focus
+            clearFocus(true);
+        }
+
+        windowListeners.activeChanged(this);
+    }
+
+    /**
+     * Returns the currently active window.
+     *
+     * @return
+     * The window that is currently active, or <tt>null</tt> if no window
+     * is active.
+     */
+    public static Window getActiveWindow() {
+        return activeWindow;
+    }
+
+    /**
+     * Sets the active window. The window must be activatable, open, and
+     * enabled. If the window is not currently visible, it will be made
+     * visible.
+     *
+     * @param activeWindow
+     * The window to activate, or <tt>null</tt> to clear the active window.
+     */
+    public static void setActiveWindow(Window activeWindow) {
+        Window previousActiveWindow = Window.activeWindow;
+
+        if (previousActiveWindow != activeWindow) {
+            if (activeWindow != null) {
+                if (activeWindow.isAuxilliary()) {
+                    throw new IllegalArgumentException("activeWindow is auxilliary.");
+                }
+
+                if (!activeWindow.isOpen()) {
+                    throw new IllegalArgumentException("activeWindow is not open.");
+                }
+
+                if (!activeWindow.isEnabled()) {
+                    throw new IllegalArgumentException("activeWindow is not enabled.");
+                }
+            }
+
+            // Set the active window
+            Window.activeWindow = activeWindow;
+
+            // Notify the windows of the state change
+            if (previousActiveWindow != null) {
+                previousActiveWindow.setActive(false);
+            }
+
+            // Activate the window
+            if (activeWindow != null) {
+                activeWindow.setActive(true);
+            }
+
+            windowClassListeners.activeWindowChanged(previousActiveWindow);
+        }
+    }
+
+    /**
+     * Returns the window descendant that currently has the focus.
+     */
+    public Component getActiveDescendant() {
+        return activeDescendant;
+    }
+
+    /**
+     * Sets the window's active descendant, the descendant that currently
+     * has the focus.
+     *
+     * @param activeDescendant
+     */
+    protected void setActiveDescendant(Component activeDescendant) {
+        this.activeDescendant = activeDescendant;
+    }
+
+    /**
+     * Returns the global action map for this window.
+     */
+    public ActionDictionary getActions() {
+        return actionDictionary;
+    }
+
+    /**
+     * Moves the window to the top of the window stack. The window is removed
+     * from its current position in the display's component sequence and
+     * appended to the end. It is also moved to the top of its owner's owned
+     * window list so it becomes top-most of all windows owned by its owner.
+     * <p>
+     * All windows owned by this window are subsequently moved to the front,
+     * ensuring that this window's owned windows remain on top of it.
+     * <p>
+     * Finally, the window is made active and focus is restored to the most
+     * recently focused decendant component.
+     */
+    public void moveToFront() {
+        if (!isOpen()) {
+            throw new IllegalStateException("Window is not open.");
+        }
+
+        // If this window is not currently top-most, move it to the top
+        Display display = getDisplay();
+
+        Window window = this;
+        ArrayStack<Integer> ownedWindowIndexes = new ArrayStack<Integer>();
+        ownedWindowIndexes.push(0);
+
+        while (ownedWindowIndexes.getLength() > 0) {
+            // Get the next owned window index for this window
+            int j = ownedWindowIndexes.peek();
+
+            if (j == 0) {
+                // Move the window within the window stack
+                int i = display.indexOf(window);
+
+                if (i < display.getLength() - 1) {
+                    display.remove(i, 1);
+                    display.add(window);
+                }
+            }
+
+            if (j < window.ownedWindows.getLength()) {
+                // There is another owned window to traverse; move down
+                // the tree
+                ownedWindowIndexes.poke(j + 1);
+                window = window.ownedWindows.get(j);
+
+                // If the window is not open, ignore it
+                if (window.isOpen()) {
+                    ownedWindowIndexes.push(0);
+                } else {
+                    window = window.owner;
+                }
+            } else {
+                // Activate the window
+                if (window.isEnabled()
+                    && !window.isAuxilliary()) {
+                    setActiveWindow(window);
+                }
+
+                // This was the last owned window for the current window; move
+                // up the tree
+                ownedWindowIndexes.pop();
+                window = window.owner;
+            }
+        }
+
+        // Move this window to the top of its owner's owned window list,
+        // so it becomes top-most of all windows owned by this window's
+        // owner
+        if (owner != null) {
+            int j = owner.ownedWindows.indexOf(this);
+
+            if (j < owner.ownedWindows.getLength() - 1) {
+                owner.ownedWindows.remove(j, 1);
+                owner.ownedWindows.add(this);
+            }
+        }
+    }
+
+    /**
+     * Moves the window to the bottom of the window stack. If the window is
+     * active, the active window will be cleared. If the window is the focus
+     * host, the focus will be cleared.
+     */
+    public void moveToBack() {
+        if (!isOpen()) {
+            throw new IllegalStateException("Window is not open.");
+        }
+
+        if (isActive()) {
+            setActiveWindow(null);
+        }
+
+        Display display = getDisplay();
+
+        // Ensure that the window and all of its owning ancestors are moved
+        // to the back
+        Window window = this;
+        while (window != null) {
+            // If this window is not currently bottom-most, move it to the
+            // bottom
+            int i = display.indexOf(window);
+
+            if (i > 0) {
+                display.remove(i, 1);
+                display.insert(window, 0);
+            }
+
+            window = window.getOwner();
+        }
+
+        // Move this window to the bottom of its owner's owned window list
+        if (owner != null) {
+            int j = owner.ownedWindows.indexOf(this);
+
+            if (j > 0) {
+                owner.ownedWindows.remove(j, 1);
+                owner.ownedWindows.insert(this, 0);
+            }
+        }
+    }
+
+    public boolean isMaximized() {
+        return maximized;
+    }
+
+    public void setMaximized(boolean maximized) {
+        if (maximized != this.maximized) {
+            this.maximized = maximized;
+
+            invalidate();
+
+            windowListeners.maximizedChanged(this);
+        }
+    }
+
+    public void align(Bounds bounds,
+        HorizontalAlignment horizontalAlignment,
+        VerticalAlignment verticalAlignment) {
+        align(bounds, horizontalAlignment, 0, verticalAlignment, 0);
+    }
+
+    public void align(Bounds bounds,
+        HorizontalAlignment horizontalAlignment, int horizontalOffset,
+        VerticalAlignment verticalAlignment, int verticalOffset) {
+
+        int x = 0;
+        int y = 0;
+
+        Dimensions size = getSize();
+
+        if (horizontalAlignment == HorizontalAlignment.LEFT) {
+            x = bounds.x - size.width;
+        }
+        else if (horizontalAlignment == HorizontalAlignment.RIGHT) {
+            x = bounds.x + bounds.width - size.width;
+        }
+        else if (horizontalAlignment == HorizontalAlignment.CENTER) {
+            x = bounds.x + (int)Math.round((double)(bounds.width - size.width) / 2);
+        }
+        else {
+            throw new IllegalArgumentException("Unsupported horizontal alignment.");
+        }
+
+        x += horizontalOffset;
+
+        if (verticalAlignment == VerticalAlignment.TOP) {
+            y = bounds.y - size.height;
+        }
+        else if (verticalAlignment == VerticalAlignment.BOTTOM) {
+            y = bounds.y + bounds.height;
+        }
+        else if (verticalAlignment == VerticalAlignment.CENTER) {
+            y = bounds.y + (int)Math.round((double)(bounds.height - size.height) / 2);
+        }
+        else {
+            throw new IllegalArgumentException("Unsupported vertical alignment.");
+        }
+
+        y += verticalOffset;
+
+        setLocation(x, y);
+    }
+
+    @Override
+    protected boolean mouseDown(Mouse.Button button, int x, int y) {
+        // NOTE This is done here rather than in WindowSkin because the
+        // user input methods are not called on the skin when the component
+        // is disabled
+
+        if (isEnabled()) {
+            // Bring this window to the front
+            moveToFront();
+        } else {
+            ApplicationContext.beep();
+
+            // Bring the window's owner tree to the front
+            Window rootOwner = getRootOwner();
+            rootOwner.moveToFront();
+        }
+
+        return super.mouseDown(button, x, y);
+    }
+
+    public ListenerList<WindowListener> getWindowListeners() {
+        return windowListeners;
+    }
+
+    public ListenerList<WindowStateListener> getWindowStateListeners() {
+        return windowStateListeners;
+    }
+
+    public static ListenerList<WindowClassListener> getWindowClassListeners() {
+        return windowClassListeners;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowClassListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowClassListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowClassListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowClassListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,30 @@
+/*
+ * 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.wtk;
+
+/**
+ * Window class listener interface.
+ *
+ * @author tvolkert
+ */
+public interface WindowClassListener {
+    /**
+     * Called when the active window has changed.
+     *
+     * @param previousActiveWindow
+     */
+    public void activeWindowChanged(Window previousActiveWindow);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,71 @@
+/*
+ * 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.wtk;
+
+import pivot.wtk.media.Image;
+
+/**
+ * Window listener interface.
+ *
+ * @author gbrown
+ */
+public interface WindowListener {
+    /**
+     * Called when a window's title has changed.
+     *
+     * @param window
+     * @param previousTitle
+     */
+    public void titleChanged(Window window, String previousTitle);
+
+    /**
+     * Called when a window's icon has changed.
+     *
+     * @param window
+     * @param previousIcon
+     */
+    public void iconChanged(Window window, Image previousIcon);
+
+    /**
+     * Called when a window's content component has changed.
+     *
+     * @param window
+     * @param previousContent
+     */
+    public void contentChanged(Window window, Component previousContent);
+
+    /**
+     * Called when a window's owner has changed.
+     *
+     * @param window
+     * @param previousOwner
+     */
+    public void ownerChanged(Window window, Window previousOwner);
+
+    /**
+     * Called when a window's active state has changed.
+     *
+     * @param window
+     */
+    public void activeChanged(Window window);
+
+    /**
+     * Called when a window's maximized state has changed.
+     *
+     * @param window
+     */
+    public void maximizedChanged(Window window);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowStateListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowStateListener.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowStateListener.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/WindowStateListener.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,72 @@
+/*
+ * 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.wtk;
+
+import pivot.util.Vote;
+
+/**
+ * Window state listener interface.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public interface WindowStateListener {
+    /**
+     * Called to preview a window open event.
+     *
+     * @param window
+     * @param display
+     */
+    public Vote previewWindowOpen(Window window, Display display);
+
+    /**
+     * Called when a window open event has been vetoed.
+     *
+     * @param window
+     * @param reason
+     */
+    public void windowOpenVetoed(Window window, Vote reason);
+
+    /**
+     * Called when a window has opened.
+     *
+     * @param window
+     */
+    public void windowOpened(Window window);
+
+    /**
+     * Called to preview a window close event.
+     *
+     * @param window
+     */
+    public Vote previewWindowClose(Window window);
+
+    /**
+     * Called when a window close event has been vetoed.
+     *
+     * @param window
+     * @param reason
+     */
+    public void windowCloseVetoed(Window window, Vote reason);
+
+    /**
+     * Called when a window has closed.
+     *
+     * @param window
+     * @param display
+     */
+    public void windowClosed(Window window, Display display);
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonData.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonData.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonData.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonData.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.wtk.content;
+
+import java.net.URL;
+
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.media.Image;
+
+/**
+ * Default button data implementation.
+ *
+ * @author gbrown
+ */
+public class ButtonData {
+    private Image icon;
+    private String text;
+
+    public ButtonData() {
+        this(null, null);
+    }
+
+    public ButtonData(Image icon) {
+        this(icon, null);
+    }
+
+    public ButtonData(String text) {
+        this(null, text);
+    }
+
+    public ButtonData(Image icon, String text) {
+        this.icon = icon;
+        this.text = text;
+    }
+
+    public Image getIcon() {
+        return icon;
+    }
+
+    public void setIcon(Image icon) {
+        this.icon = icon;
+    }
+
+    public void setIcon(URL iconURL) {
+        Image icon = (Image)ApplicationContext.getResourceCache().get(iconURL);
+
+        if (icon == null) {
+            icon = Image.load(iconURL);
+            ApplicationContext.getResourceCache().put(iconURL, icon);
+        }
+
+        setIcon(icon);
+    }
+
+    public void setIcon(String iconName) {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        setIcon(classLoader.getResource(iconName));
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ButtonDataRenderer.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,108 @@
+/*
+ * 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.wtk.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Button;
+import pivot.wtk.Component;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Label;
+import pivot.wtk.media.Image;
+
+/**
+ * Default button data renderer.
+ *
+ * @author gbrown
+ */
+public class ButtonDataRenderer extends FlowPane implements Button.DataRenderer {
+    protected ImageView imageView = new ImageView();
+    protected Label label = new Label();
+
+    public ButtonDataRenderer() {
+        getStyles().put("horizontalAlignment", HorizontalAlignment.CENTER);
+        getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+
+        add(imageView);
+        add(label);
+
+        imageView.getStyles().put("backgroundColor", null);
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        super.setSize(width, height);
+
+        // Since this component doesn't have a parent, it won't be validated
+        // via layout; ensure that it is valid here
+        validate();
+    }
+
+    public void render(Object data, Button button, boolean highlighted) {
+        Image icon = null;
+        String text = null;
+
+        if (data instanceof ButtonData) {
+            ButtonData buttonData = (ButtonData)data;
+            icon = buttonData.getIcon();
+            text = buttonData.getText();
+        } else if (data instanceof Image) {
+            icon = (Image)data;
+        } else {
+            if (data != null) {
+                text = data.toString();
+            }
+        }
+
+        // Show/hide the image view
+        if (icon == null) {
+            imageView.setDisplayable(false);
+        } else {
+            imageView.setDisplayable(true);
+            imageView.setImage(icon);
+
+            imageView.getStyles().put("opacity", button.isEnabled() ? 1.0f : 0.5f);
+        }
+
+        // Show/hide the label
+        if (text == null) {
+            label.setDisplayable(false);
+        } else {
+            label.setDisplayable(true);
+            label.setText(text);
+
+            // Update the label styles
+            Component.StyleDictionary labelStyles = label.getStyles();
+
+            Object labelFont = button.getStyles().get("font");
+            if (labelFont instanceof Font) {
+                labelStyles.put("font", labelFont);
+            }
+
+            Object color = button.isEnabled() ?
+                button.getStyles().get("color") :
+                    button.getStyles().get("disabledColor");
+
+            if (color instanceof Color) {
+                labelStyles.put("color", color);
+            }
+        }
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/CalendarDateSpinnerData.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,241 @@
+/*
+ * 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.wtk.content;
+
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.TimeZone;
+
+import pivot.collections.List;
+import pivot.collections.ListListener;
+import pivot.collections.Sequence;
+import pivot.util.CalendarDate;
+import pivot.util.ListenerList;
+
+/**
+ * Spinner data model that presents a bounded list of calendar dates.
+ * <p>
+ * This is a lightweight class that spoofs the actual list data by using an
+ * internal calendar instance from which <tt>CalendarDate</tt> instances are
+ * created on demand.
+ *
+ * @author tvolkert
+ */
+public class CalendarDateSpinnerData implements List<CalendarDate> {
+    /**
+     * Iterator that simply wraps calls to the list. Since the internal list
+     * data is spoofed, each accessor runs in constant time, so there's no
+     * performance hit in making the iterator delegate its implementation to
+     * the list.
+     *
+     * @author tvolkert
+     */
+    private class DataIterator implements Iterator<CalendarDate> {
+        private int index = 0;
+
+        public boolean hasNext() {
+            return (index < length);
+        }
+
+        public CalendarDate next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+
+            return get(index++);
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private GregorianCalendar calendar;
+    private int calendarIndex;
+
+    // Calculated during construction
+    private transient int length;
+
+    private ListListenerList<CalendarDate> listListeners =
+        new ListListenerList<CalendarDate>();
+
+    /**
+     * Creates a new <tt>CalendarDateSpinnerData</tt> bounded from
+     * <tt>1900-01-01</tt> to <tt>2099-12-31</tt>.
+     */
+    public CalendarDateSpinnerData() {
+        this(new CalendarDate(1900, 0, 0), new CalendarDate(2099, 11, 30));
+    }
+
+    /**
+     * Creates a new <tt>CalendarDateSpinnerData</tt> bounded by the specified
+     * calendar dates (inclusive).
+     *
+     * @param lowerBound
+     * The earliest date to include in this spinner data.
+     *
+     * @param upperBound
+     * The latest date to include in this spinner data.
+     */
+    public CalendarDateSpinnerData(CalendarDate lowerBound, CalendarDate upperBound) {
+        if (lowerBound == null) {
+            throw new IllegalArgumentException("lowerBound is null.");
+        }
+
+        if (upperBound == null) {
+            throw new IllegalArgumentException("upperBound is null.");
+        }
+
+        if (lowerBound.compareTo(upperBound) >= 0) {
+            throw new IllegalArgumentException("lowerBound must be before upperBound.");
+        }
+
+        calendar = new GregorianCalendar(lowerBound.getYear(), lowerBound.getMonth(),
+            lowerBound.getDay() + 1);
+        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+        calendarIndex = 0;
+
+        // Calculate our length and cache it, since it is guaranteed to
+        // remain fixed
+        GregorianCalendar upperBoundCalendar = new GregorianCalendar(upperBound.getYear(),
+            upperBound.getMonth(), upperBound.getDay() + 1);
+        upperBoundCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+        long lowerBoundMilliseconds = calendar.getTimeInMillis();
+        long upperBoundMilliseconds = upperBoundCalendar.getTimeInMillis();
+        long indexDiff = (upperBoundMilliseconds - lowerBoundMilliseconds) /
+            (1000 * 60 * 60 * 24);
+        length = (int)indexDiff + 1;
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public int add(CalendarDate item) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public void insert(CalendarDate item, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public CalendarDate update(int index, CalendarDate item) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public int remove(CalendarDate item) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public Sequence<CalendarDate> remove(int index, int count) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets the calendar date at the specified index.
+     *
+     * @param index
+     * The index of the calendar date to retrieve.
+     */
+    public CalendarDate get(int index) {
+        if (index < 0 || index >= length) {
+            throw new IndexOutOfBoundsException("Index out of bounds: " + index);
+        }
+
+        // Move the calendar's fields to match the specified index
+        calendar.add(Calendar.DAY_OF_YEAR, index - calendarIndex);
+        calendarIndex = index;
+
+        // Calculate the desired fields
+        int year = calendar.get(Calendar.YEAR);
+        int month = calendar.get(Calendar.MONTH);
+        int day = calendar.get(Calendar.DAY_OF_MONTH) - 1;
+
+        return new CalendarDate(year, month, day);
+    }
+
+    public int indexOf(CalendarDate item) {
+        long currentMilliseconds = calendar.getTimeInMillis();
+
+        int year = item.getYear();
+        int month = item.getMonth();
+        int day = item.getDay() + 1;
+
+        GregorianCalendar tmpCalendar = new GregorianCalendar(year, month, day);
+        tmpCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+        long itemMilliseconds = tmpCalendar.getTimeInMillis();
+
+        long indexDiff = (itemMilliseconds - currentMilliseconds) / (1000 * 60 * 60 * 24);
+        int index = calendarIndex + (int)indexDiff;
+
+        return (index < 0 || index >= length) ? -1 : index;
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Gets the number of entries in this list.
+     *
+     * @return
+     * The number of calendar dates in this list.
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Gets the comparator for this list, which is guaranteed to always be
+     * <tt>null</tt>. This class does not support comparators since there's no
+     * real data to sort (it's all spoofed).
+     */
+    public Comparator<CalendarDate> getComparator() {
+        return null;
+    }
+
+    /**
+     * Throws <tt>UnsupportedOperationException</tt>.
+     */
+    public void setComparator(Comparator<CalendarDate> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<CalendarDate> iterator() {
+        return new DataIterator();
+    }
+
+    public ListenerList<ListListener<CalendarDate>> getListListeners() {
+        return listListeners;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/LinkButtonDataRenderer.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.wtk.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.TextDecoration;
+
+/**
+ * Default link button data renderer.
+ *
+ * @author gbrown
+ */
+public class LinkButtonDataRenderer extends ButtonDataRenderer {
+    public LinkButtonDataRenderer() {
+        label.getStyles().put("wrapText", true);
+    }
+
+    @Override
+    public void render(Object data, Button button, boolean highlighted) {
+        super.render(data, button, highlighted);
+
+        label.getStyles().put("textDecoration", highlighted ?
+            TextDecoration.UNDERLINE : null);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListButtonDataRenderer.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.wtk.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.HorizontalAlignment;
+
+/**
+ * Default list button data renderer.
+ * <p>
+ * TODO Add showIcon property to this class so the size of the button doesn't
+ * change when changing selection between items with and without icons.
+ *
+ * @author gbrown
+ */
+public class ListButtonDataRenderer extends ButtonDataRenderer {
+    public ListButtonDataRenderer() {
+        getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+    }
+
+    @Override
+    public void render(Object data, Button button, boolean highlight) {
+        if (data == null) {
+            data = "";
+        } else {
+            if (data instanceof ListItem) {
+                ListItem listItem = (ListItem)data;
+                data = new ButtonData(listItem.getIcon(), listItem.getText());
+            }
+        }
+
+        super.render(data, button, highlight);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListItem.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListItem.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListItem.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListItem.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,80 @@
+/*
+ * 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.wtk.content;
+
+import java.net.URL;
+
+import pivot.wtk.ApplicationContext;
+import pivot.wtk.media.Image;
+
+/**
+ * Default list item implementation.
+ *
+ * @author gbrown
+ */
+public class ListItem {
+    private Image icon;
+    private String text;
+
+    public ListItem() {
+        this(null, null);
+    }
+
+    public ListItem(Image icon) {
+        this(icon, null);
+    }
+
+    public ListItem(String text) {
+        this(null, text);
+    }
+
+    public ListItem(Image icon, String text) {
+        this.icon = icon;
+        this.text = text;
+    }
+
+    public Image getIcon() {
+        return icon;
+    }
+
+    public void setIcon(Image icon) {
+        this.icon = icon;
+    }
+
+    public void setIcon(URL iconURL) {
+        Image icon = (Image)ApplicationContext.getResourceCache().get(iconURL);
+
+        if (icon == null) {
+            icon = Image.load(iconURL);
+            ApplicationContext.getResourceCache().put(iconURL, icon);
+        }
+
+        setIcon(icon);
+    }
+
+    public void setIcon(String iconName) {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        setIcon(classLoader.getResource(iconName));
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/ListViewItemRenderer.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,160 @@
+/*
+ * 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.wtk.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Component;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Insets;
+import pivot.wtk.Label;
+import pivot.wtk.ListView;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.media.Image;
+
+/**
+ * Default list view item renderer.
+ *
+ * @author gbrown
+ */
+public class ListViewItemRenderer extends FlowPane implements ListView.ItemRenderer {
+    protected ImageView imageView = new ImageView();
+    protected Label label = new Label();
+
+    public static final int DEFAULT_ICON_WIDTH = 16;
+    public static final int DEFAULT_ICON_HEIGHT = 16;
+    public static boolean DEFAULT_SHOW_ICON = false;
+
+    public ListViewItemRenderer() {
+        super();
+
+        getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+        getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+        getStyles().put("padding", new Insets(2, 3, 2, 3));
+
+        add(imageView);
+        add(label);
+
+        imageView.setPreferredSize(DEFAULT_ICON_WIDTH, DEFAULT_ICON_HEIGHT);
+        imageView.setDisplayable(DEFAULT_SHOW_ICON);
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        super.setSize(width, height);
+
+        // Since this component doesn't have a parent, it won't be validated
+        // via layout; ensure that it is valid here
+        validate();
+    }
+
+    public void render(Object item, ListView listView, boolean selected,
+        boolean highlighted, boolean disabled) {
+        Image icon = null;
+        String text = null;
+
+        if (item instanceof ListItem) {
+            ListItem listItem = (ListItem)item;
+            icon = listItem.getIcon();
+            text = listItem.getText();
+        } else if (item instanceof Image) {
+            icon = (Image)item;
+        } else {
+            if (item != null) {
+                text = (String)item;
+            }
+        }
+
+        // Update the image view
+        imageView.setImage(icon);
+
+        // Show/hide the label
+        label.setText(text);
+
+        renderStyles(listView, selected, highlighted, disabled);
+    }
+
+    protected void renderStyles(ListView listView, boolean selected,
+        boolean highlighted, boolean disabled) {
+        Component.StyleDictionary listViewStyles = listView.getStyles();
+
+        Component.StyleDictionary imageViewStyles = imageView.getStyles();
+        Component.StyleDictionary labelStyles = label.getStyles();
+
+        imageViewStyles.put("opacity", listView.isEnabled() ? 1.0f : 0.5f);
+
+        if (label.getText() != null) {
+            Object labelFont = listViewStyles.get("font");
+            if (labelFont instanceof Font) {
+                labelStyles.put("font", labelFont);
+            }
+
+            Object color = null;
+            if (listView.isEnabled() && !disabled) {
+                if (selected) {
+                    if (listView.isFocused()) {
+                        color = listViewStyles.get("selectionColor");
+                    } else {
+                        color = listViewStyles.get("inactiveSelectionColor");
+                    }
+                } else {
+                    color = listViewStyles.get("color");
+                }
+            } else {
+                color = listViewStyles.get("disabledColor");
+            }
+
+            if (color instanceof Color) {
+                labelStyles.put("color", color);
+            }
+        }
+    }
+
+    public int getIconWidth() {
+        return imageView.getPreferredWidth(-1);
+    }
+
+    public void setIconWidth(int iconWidth) {
+        if (iconWidth == -1) {
+            throw new IllegalArgumentException();
+        }
+
+        imageView.setPreferredWidth(iconWidth);
+    }
+
+    public int getIconHeight() {
+        return imageView.getPreferredHeight(-1);
+    }
+
+    public void setIconHeight(int iconHeight) {
+        if (iconHeight == -1) {
+            throw new IllegalArgumentException();
+        }
+
+        imageView.setPreferredHeight(iconHeight);
+    }
+
+    public boolean getShowIcon() {
+        return imageView.isDisplayable();
+    }
+
+    public void setShowIcon(boolean showIcon) {
+        imageView.setDisplayable(showIcon);
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuBarItemDataRenderer.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,115 @@
+/*
+ * 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.wtk.content;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import pivot.wtk.Button;
+import pivot.wtk.FlowPane;
+import pivot.wtk.HorizontalAlignment;
+import pivot.wtk.MenuBar;
+import pivot.wtk.VerticalAlignment;
+import pivot.wtk.ImageView;
+import pivot.wtk.Label;
+import pivot.wtk.media.Image;
+
+/**
+ * Default menu bar item data renderer.
+ *
+ * @author gbrown
+ */
+public class MenuBarItemDataRenderer extends FlowPane implements Button.DataRenderer {
+    protected ImageView imageView = new ImageView();
+    protected Label label = new Label();
+
+    public MenuBarItemDataRenderer() {
+        getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+        getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
+        getStyles().put("padding", 3);
+
+        add(imageView);
+        add(label);
+
+        imageView.getStyles().put("backgroundColor", null);
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        super.setSize(width, height);
+
+        // Since this component doesn't have a parent, it won't be validated
+        // via layout; ensure that it is valid here
+        validate();
+    }
+
+    public void render(Object data, Button button, boolean highlighted) {
+        Image icon = null;
+        String text = null;
+
+        if (data instanceof ButtonData) {
+            ButtonData buttonData = (ButtonData)data;
+            icon = buttonData.getIcon();
+            text = buttonData.getText();
+        } else if (data instanceof Image) {
+            icon = (Image)data;
+        } else {
+            if (data != null) {
+                text = data.toString();
+            }
+        }
+
+        // Update the image view
+        MenuBar.Item menuBarItem = (MenuBar.Item)button;
+        MenuBar menuBar = menuBarItem.getMenuBar();
+
+        if (icon == null) {
+            imageView.setDisplayable(false);
+        } else {
+            imageView.setDisplayable(true);
+            imageView.setImage(icon);
+            imageView.getStyles().put("opacity", button.isEnabled() ? 1.0f : 0.5f);
+        }
+
+        // Update the label
+        if (text == null) {
+            label.setDisplayable(false);
+        } else {
+            label.setDisplayable(true);
+            Object font = menuBar.getStyles().get("font");
+            if (font instanceof Font) {
+                label.getStyles().put("font", font);
+            }
+
+            Object color;
+            if (button.isEnabled()) {
+                if (highlighted) {
+                    color = menuBar.getStyles().get("highlightColor");
+                } else {
+                    color = menuBar.getStyles().get("color");
+                }
+            } else {
+                color = menuBar.getStyles().get("disabledColor");
+            }
+
+            if (color instanceof Color) {
+                label.getStyles().put("color", color);
+            }
+
+            label.setText(text);
+        }
+    }
+}

Added: incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java?rev=754936&view=auto
==============================================================================
--- incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java (added)
+++ incubator/pivot/tags/v1.0.1/wtk/src/pivot/wtk/content/MenuButtonDataRenderer.java Mon Mar 16 16:36:10 2009
@@ -0,0 +1,39 @@
+/*
+ * 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.wtk.content;
+
+import pivot.wtk.Button;
+import pivot.wtk.HorizontalAlignment;
+
+/**
+ * Default menu button data renderer.
+ *
+ * @author gbrown
+ */
+public class MenuButtonDataRenderer extends ButtonDataRenderer {
+    public MenuButtonDataRenderer() {
+        getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+    }
+
+    @Override
+    public void render(Object data, Button button, boolean highlight) {
+        if (data == null) {
+            data = "";
+        }
+
+        super.render(data, button, highlight);
+    }
+}