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/26 00:12:17 UTC

svn commit: r758461 [22/47] - in /incubator/pivot/branches: ./ 1.1/ 1.1/charts-test/ 1.1/charts-test/src/ 1.1/charts-test/src/pivot/ 1.1/charts-test/src/pivot/charts/ 1.1/charts-test/src/pivot/charts/test/ 1.1/charts/ 1.1/charts/lib/ 1.1/charts/src/ 1....

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MessageType.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MessageType.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MessageType.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MessageType.java Wed Mar 25 23:08:38 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.wtk;
+
+/**
+ * Enumeration defining a message's type.
+ *
+ * @author gbrown
+ */
+public enum MessageType {
+    ERROR,
+    WARNING,
+    QUESTION,
+    INFO,
+    APPLICATION;
+
+    public static MessageType decode(String value) {
+        return valueOf(value.toUpperCase());
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Meter.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Meter.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Meter.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Meter.java Wed Mar 25 23:08:38 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;
+
+import pivot.util.ListenerList;
+
+/**
+ * Component that displays progress information.
+ *
+ * @author tvolkert
+ */
+public class Meter extends Component {
+    private static class MeterListenerList extends ListenerList<MeterListener>
+    implements MeterListener {
+        public void percentageChanged(Meter meter, double oldPercentage) {
+            for (MeterListener listener : this) {
+                listener.percentageChanged(meter, oldPercentage);
+            }
+        }
+
+        public void textChanged(Meter meter, String oldText) {
+            for (MeterListener listener : this) {
+                listener.textChanged(meter, oldText);
+            }
+        }
+    }
+
+    private double percentage = 0.0;
+    private String text = null;
+    private MeterListenerList meterListeners = new MeterListenerList();
+
+    public Meter() {
+        installSkin(Meter.class);
+    }
+
+    public double getPercentage() {
+        return percentage;
+    }
+
+    public void setPercentage(double percentage) {
+        if (percentage < 0.0 || percentage > 1.0) {
+            throw new IllegalArgumentException
+                ("Percentage must be a number between 0 and 1");
+        }
+
+        double previousPercentage = this.percentage;
+
+        if (previousPercentage != percentage) {
+            this.percentage = percentage;
+            meterListeners.percentageChanged(this, previousPercentage);
+        }
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        String previousText = this.text;
+        this.text = text;
+        meterListeners.textChanged(this, previousText);
+    }
+
+    public ListenerList<MeterListener> getMeterListeners() {
+        return meterListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MeterListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MeterListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MeterListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/MeterListener.java Wed Mar 25 23:08:38 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;
+
+/**
+ * Meter listener interface.
+ *
+ * @author tvolkert
+ */
+public interface MeterListener {
+    /**
+     * Called when a meter's percentage value has changed.
+     *
+     * @param meter
+     * @param previousPercentage
+     */
+    public void percentageChanged(Meter meter, double previousPercentage);
+
+    /**
+     * Called when a meter's text has changed.
+     *
+     * @param meter
+     * @param previousText
+     */
+    public void textChanged(Meter meter, String previousText);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Mouse.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Mouse.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Mouse.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Mouse.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,386 @@
+/*
+ * 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.MouseInfo;
+
+/**
+ * Class representing the system mouse.
+ *
+ * @author gbrown
+ */
+public final class Mouse {
+    /**
+     * Enumeration representing mouse buttons.
+     *
+     * @author gbrown
+     */
+    public enum Button {
+        LEFT,
+        RIGHT,
+        MIDDLE;
+
+        public int getMask() {
+            return 1 << ordinal();
+        }
+
+        public boolean isSelected(int buttons) {
+            return ((buttons & getMask()) > 0);
+        }
+
+        public static Button decode(String value) {
+            return valueOf(value.toUpperCase());
+        }
+    }
+
+    /**
+     * Enumeration defining supported scroll types.
+     *
+     * @author gbrown
+     */
+    public enum ScrollType {
+        UNIT,
+        BLOCK
+    }
+
+    private static int buttons = 0;
+    private static Component capturer = null;
+
+    /**
+     * Returns a bitfield representing the mouse buttons that are currently
+     * pressed.
+     */
+    public static int getButtons() {
+        return buttons;
+    }
+
+    protected static void setButtons(int buttons) {
+        Mouse.buttons = buttons;
+    }
+
+    /**
+     * Tests the pressed state of a button.
+     *
+     * @param button
+     *
+     * @return
+     * <tt>true</tt> if the button is pressed; <tt>false</tt>, otherwise.
+     */
+    public static boolean isPressed(Button button) {
+        return button.isSelected(getButtons());
+    }
+
+    /**
+     * Returns the number of mouse buttons.
+     */
+    public static int getButtonCount() {
+        return MouseInfo.getNumberOfButtons();
+    }
+
+    /**
+     * "Captures" the mouse, causing all mouse input to be delegated to the
+     * given component rather than propagating down the component hierarchy.
+     *
+     * @param capturer
+     * The component that wants to capture the mouse. The mouse pointer must
+     * currently be over the component.
+     */
+    public static void capture(Component capturer) {
+        if (capturer == null) {
+            throw new IllegalArgumentException("capturer is null.");
+        }
+
+        if (!capturer.isMouseOver()) {
+            throw new IllegalArgumentException("Mouse pointer is not currently over capturer.");
+        }
+
+        if (Mouse.capturer != null) {
+            throw new IllegalStateException("Mouse is already captured.");
+        }
+
+        Mouse.capturer = capturer;
+    }
+
+    /**
+     * Releases mouse capture, causing mouse input to resume propagation down
+     * the component hierarchy.
+     */
+    public static void release() {
+        if (capturer == null) {
+            throw new IllegalStateException("Mouse is not currently captured.");
+        }
+
+        Display display = capturer.getDisplay();
+        ApplicationContext.DisplayHost displayHost = display.getDisplayHost();
+
+        Point location = displayHost.getMouseLocation();
+        Component descendant = display.getDescendantAt(location.x, location.y);
+
+        while (descendant != null
+            && descendant != capturer) {
+            descendant = descendant.getParent();
+        }
+
+        if (descendant == null) {
+            // The mouse is no longer over the capturer
+            capturer.mouseOut();
+            display.mouseMove(location.x, location.y);
+        }
+
+        capturer = null;
+    }
+
+    /**
+     * Returns the mouse capturer.
+     *
+     * @return
+     * The component that has captured the mouse, or <tt>null</tt> if the mouse
+     * is not currently captured.
+     */
+    public static Component getCapturer() {
+        return capturer;
+    }
+
+    /**
+     * Returns the current cursor.
+     *
+     * @throws IllegalStateException
+     * If the mouse is not currently captured.
+     */
+    public static Cursor getCursor() {
+        if (capturer == null) {
+            throw new IllegalStateException("Mouse is not currently captured.");
+        }
+
+        Cursor cursor = null;
+
+        Display display = capturer.getDisplay();
+        ApplicationContext.DisplayHost displayHost = display.getDisplayHost();
+
+        int cursorID = displayHost.getCursor().getType();
+        switch (cursorID) {
+            case java.awt.Cursor.DEFAULT_CURSOR: {
+                cursor = Cursor.DEFAULT;
+                break;
+            }
+
+            case java.awt.Cursor.HAND_CURSOR: {
+                cursor = Cursor.HAND;
+                break;
+            }
+
+            case java.awt.Cursor.TEXT_CURSOR: {
+                cursor = Cursor.TEXT;
+                break;
+            }
+
+            case java.awt.Cursor.WAIT_CURSOR: {
+                cursor = Cursor.WAIT;
+                break;
+            }
+
+            case java.awt.Cursor.CROSSHAIR_CURSOR: {
+                cursor = Cursor.CROSSHAIR;
+                break;
+            }
+
+            case java.awt.Cursor.MOVE_CURSOR: {
+                cursor = Cursor.MOVE;
+                break;
+            }
+
+            case java.awt.Cursor.N_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_NORTH;
+                break;
+            }
+
+            case java.awt.Cursor.S_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_SOUTH;
+                break;
+            }
+
+            case java.awt.Cursor.E_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_EAST;
+                break;
+            }
+
+            case java.awt.Cursor.W_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_WEST;
+                break;
+            }
+
+            case java.awt.Cursor.NE_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_NORTH_EAST;
+                break;
+            }
+
+            case java.awt.Cursor.SW_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_SOUTH_WEST;
+                break;
+            }
+
+            case java.awt.Cursor.NW_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_NORTH_WEST;
+                break;
+            }
+
+            case java.awt.Cursor.SE_RESIZE_CURSOR: {
+                cursor = Cursor.RESIZE_SOUTH_EAST;
+                break;
+            }
+
+            default: {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        return cursor;
+    }
+
+    /**
+     * Sets the cursor to an explicit value.
+     *
+     * @param cursor
+     *
+     * @throws IllegalStateException
+     * If the mouse is not currently captured.
+     */
+    public static void setCursor(Cursor cursor) {
+        if (cursor == null) {
+            throw new IllegalArgumentException("cursor is null.");
+        }
+
+        if (capturer == null) {
+            throw new IllegalStateException("Mouse is not currently captured.");
+        }
+
+        Display display = capturer.getDisplay();
+        ApplicationContext.DisplayHost displayHost = display.getDisplayHost();
+        displayHost.setCursor(getCursor(cursor));
+    }
+
+    /**
+     * Sets the cursor based on a given component.
+     *
+     * @param component
+     */
+    public static void setCursor(Component component) {
+        if (component == null) {
+            throw new IllegalArgumentException("component is null.");
+        }
+
+        if (!component.isVisible()) {
+            throw new IllegalArgumentException("component is not visible.");
+        }
+
+        Cursor cursor = null;
+
+        if (component.isEnabled()) {
+            cursor = component.getCursor();
+            while (cursor == null
+                && !(component instanceof Display)) {
+                component = component.getParent();
+                cursor = component.getCursor();
+            }
+        }
+
+        Display display = component.getDisplay();
+        ApplicationContext.DisplayHost displayHost = display.getDisplayHost();
+        displayHost.setCursor((cursor == null) ? java.awt.Cursor.getDefaultCursor() : getCursor(cursor));
+    }
+
+    private static java.awt.Cursor getCursor(Cursor cursor) {
+        int cursorID = -1;
+
+        switch (cursor) {
+            case DEFAULT: {
+                cursorID = java.awt.Cursor.DEFAULT_CURSOR;
+                break;
+            }
+
+            case HAND: {
+                cursorID = java.awt.Cursor.HAND_CURSOR;
+                break;
+            }
+
+            case TEXT: {
+                cursorID = java.awt.Cursor.TEXT_CURSOR;
+                break;
+            }
+
+            case WAIT: {
+                cursorID = java.awt.Cursor.WAIT_CURSOR;
+                break;
+            }
+
+            case CROSSHAIR: {
+                cursorID = java.awt.Cursor.CROSSHAIR_CURSOR;
+                break;
+            }
+
+            case MOVE: {
+                cursorID = java.awt.Cursor.MOVE_CURSOR;
+                break;
+            }
+
+            case RESIZE_NORTH: {
+                cursorID = java.awt.Cursor.N_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_SOUTH: {
+                cursorID = java.awt.Cursor.S_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_EAST: {
+                cursorID = java.awt.Cursor.E_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_WEST: {
+                cursorID = java.awt.Cursor.W_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_NORTH_EAST: {
+                cursorID = java.awt.Cursor.NE_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_SOUTH_WEST: {
+                cursorID = java.awt.Cursor.SW_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_NORTH_WEST: {
+                cursorID = java.awt.Cursor.NW_RESIZE_CURSOR;
+                break;
+            }
+
+            case RESIZE_SOUTH_EAST: {
+                cursorID = java.awt.Cursor.SE_RESIZE_CURSOR;
+                break;
+            }
+
+            default: {
+                throw new IllegalArgumentException();
+            }
+        }
+
+        return new java.awt.Cursor(cursorID);
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Orientation.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Orientation.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Orientation.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Orientation.java Wed Mar 25 23:08:38 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;
+
+/**
+ * Enumeration defining a two-dimensional orientation.
+ *
+ * @author gbrown
+ */
+public enum Orientation {
+    HORIZONTAL,
+    VERTICAL;
+
+    public static Orientation decode(String value) {
+        return valueOf(value.toUpperCase());
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Palette.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Palette.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Palette.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Palette.java Wed Mar 25 23:08:38 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;
+
+/**
+ * Window representing a "tool palette". A tool palette is an auxiliary window
+ * whose visibility is tied to its owner's active state.
+ *
+ * @author gbrown
+ */
+public class Palette extends Window {
+    public Palette() {
+        this(null, null);
+    }
+
+    public Palette(String title) {
+        this(title, null);
+    }
+
+    public Palette(Component content) {
+        this(null, content);
+    }
+
+    public Palette(String title, Component content) {
+        super(content, true);
+
+        setTitle(title);
+        installSkin(Palette.class);
+    }
+
+    @Override
+    public final void setOwner(Window owner) {
+        if (owner == null) {
+            throw new UnsupportedOperationException("A palette must have an owner.");
+        }
+
+        if (owner.isAuxilliary()) {
+            throw new UnsupportedOperationException("A palette window must have a primary owner.");
+        }
+
+        super.setOwner(owner);
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Panorama.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Panorama.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Panorama.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Panorama.java Wed Mar 25 23:08:38 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;
+
+/**
+ * Container that provides a scrollable view of a component.
+ *
+ * @author gbrown
+ */
+public class Panorama extends Viewport {
+    public Panorama() {
+        this(null);
+    }
+
+    public Panorama(Component view) {
+        installSkin(Panorama.class);
+        setView(view);
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Platform.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Platform.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Platform.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Platform.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,98 @@
+/*
+ * 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.RenderingHints;
+import java.awt.Toolkit;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * Provides platform-specific information.
+ *
+ * @author gbrown
+ */
+public class Platform {
+    private static Object textAntialiasingHint = null;
+
+    private static final int DEFAULT_MULTI_CLICK_INTERVAL = 400;
+    private static final int DEFAULT_CURSOR_BLINK_RATE = 600;
+
+    /**
+     * Returns the system text anti-aliasing hint.
+     */
+    public static Object getTextAntialiasingHint() {
+        if (textAntialiasingHint == null) {
+            Toolkit toolkit = Toolkit.getDefaultToolkit();
+            java.util.Map<?, ?> fontDesktopHints =
+                (java.util.Map<?, ?>)toolkit.getDesktopProperty("awt.font.desktophints");
+
+            if (fontDesktopHints == null) {
+                textAntialiasingHint = RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
+            } else {
+                textAntialiasingHint = fontDesktopHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
+                if (textAntialiasingHint.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
+                    textAntialiasingHint = RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
+                }
+
+                // Listen for changes to the property
+                toolkit.addPropertyChangeListener("awt.font.desktophints", new PropertyChangeListener() {
+                    public void propertyChange(PropertyChangeEvent event) {
+                        Platform.textAntialiasingHint = null;
+                    }
+                });
+            }
+        }
+
+        return textAntialiasingHint;
+    }
+
+    /**
+     * Returns the system multi-click interval.
+     */
+    public static int getMultiClickInterval() {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        Integer multiClickInterval = (Integer)toolkit.getDesktopProperty("awt.multiClickInterval");
+
+        if (multiClickInterval == null) {
+            multiClickInterval = DEFAULT_MULTI_CLICK_INTERVAL;
+        }
+
+        return multiClickInterval;
+    }
+
+    /**
+     * Returns the system cursor blink rate.
+     */
+    public static int getCursorBlinkRate() {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        Integer cursorBlinkRate = (Integer)toolkit.getDesktopProperty("awt.cursorBlinkRate");
+
+        if (cursorBlinkRate == null) {
+            cursorBlinkRate = DEFAULT_CURSOR_BLINK_RATE;
+        }
+
+        return cursorBlinkRate;
+    }
+
+    /**
+     * Returns the system drag threshold.
+     */
+    public static int getDragThreshold() {
+        return java.awt.dnd.DragSource.getDragThreshold();
+    }
+
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Point.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Point.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Point.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Point.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,83 @@
+/*
+ * 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.Dictionary;
+
+/**
+ * Class representing the location of an object.
+ *
+ * @author gbrown
+ */
+public class Point {
+    public int x = 0;
+    public int y = 0;
+
+    public static final String X_KEY = "x";
+    public static final String Y_KEY = "y";
+
+    public Point() {
+    }
+
+    public Point(Dictionary<String, ?> point) {
+        if (point == null) {
+            throw new IllegalArgumentException("point is null.");
+        }
+
+        if (point.containsKey(X_KEY)) {
+            x = (Integer)point.get(X_KEY);
+        }
+
+        if (point.containsKey(Y_KEY)) {
+            y = (Integer)point.get(Y_KEY);
+        }
+    }
+
+    public Point(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public Point(Point point) {
+        if (point == null) {
+            throw new IllegalArgumentException("point is null.");
+        }
+
+        this.x = point.x;
+        this.y = point.y;
+    }
+
+    public void translate(int dx, int dy) {
+        this.x += dx;
+        this.y += dy;
+    }
+
+    public boolean equals(Object object) {
+        boolean equals = false;
+
+        if (object instanceof Point) {
+            Point point = (Point)object;
+            equals = (x == point.x
+                && y == point.y);
+        }
+
+        return equals;
+    }
+
+    public String toString() {
+        return getClass().getName() + " [" + x + "," + y + "]";
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,155 @@
+/*
+ * 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.ArrayList;
+import pivot.collections.List;
+import pivot.collections.Sequence;
+import pivot.util.ListenerList;
+import pivot.util.Resources;
+
+/**
+ * Class representing an "prompt", a sheet commonly used to perform simple
+ * user interaction.
+ * <p>
+ * <tt>Prompt</tt> is a semantic sibling of <tt>Alert</tt>, but whereas
+ * alerts are dialogs, prompts are sheets, meaning that an alert will be modal
+ * over its entire owner hierarchy (its entire "application", in common usage)
+ * but a prompt will be modal only over its owner's content.
+ *
+ * @author tvolkert
+ */
+public class Prompt extends Sheet {
+    private static class PromptListenerList extends ListenerList<PromptListener>
+        implements PromptListener {
+        public void selectedOptionChanged(Prompt prompt, int previousSelectedOption) {
+            for (PromptListener listener : this) {
+                listener.selectedOptionChanged(prompt, previousSelectedOption);
+            }
+        }
+    }
+
+    private MessageType type = null;
+    private String message = null;
+    private Component body = null;
+    private Sequence<?> options = null;
+    private int selectedOption = -1;
+
+    private PromptListenerList promptListeners = new PromptListenerList();
+
+    private static Resources resources = null;
+
+    static {
+        try {
+            resources = new Resources(Prompt.class.getName());
+        } catch(Exception exception) {
+            throw new RuntimeException(exception);
+        }
+    }
+
+    public Prompt(MessageType type, String message, Sequence<?> options) {
+        this(type, message, options, null);
+    }
+
+    public Prompt(MessageType type, String message, Sequence<?> options, Component body) {
+        if (type == null) {
+            throw new IllegalArgumentException("type is null.");
+        }
+
+        if (options == null) {
+            throw new IllegalArgumentException("options is null.");
+        }
+
+        this.type = type;
+        this.message = message;
+        this.options = options;
+        this.body = body;
+
+        installSkin(Prompt.class);
+    }
+
+    public MessageType getMessageType() {
+        return type;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public Object getOption(int index) {
+        return options.get(index);
+    }
+
+    public int getOptionCount() {
+        return options.getLength();
+    }
+
+    public Component getBody() {
+        return body;
+    }
+
+    public int getSelectedOption() {
+        return selectedOption;
+    }
+
+    public void setSelectedOption(int selectedOption) {
+        if (selectedOption < -1
+            || selectedOption >= options.getLength()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        int previousSelectedOption = this.selectedOption;
+
+        if (selectedOption != previousSelectedOption) {
+            this.selectedOption = selectedOption;
+            promptListeners.selectedOptionChanged(this, previousSelectedOption);
+        }
+    }
+
+    public ListenerList<PromptListener> getPromptListeners() {
+        return promptListeners;
+    }
+
+    public static void prompt(String message, Window owner) {
+        prompt(MessageType.INFO, message, owner, null);
+    }
+
+    public static void prompt(String message, Window owner,
+        SheetStateListener sheetStateListener) {
+        prompt(MessageType.INFO, message, owner, sheetStateListener);
+    }
+
+    public static void prompt(MessageType type, String message, Window owner) {
+        prompt(type, message, owner, null);
+    }
+
+    public static void prompt(MessageType type, String message, Window owner,
+        SheetStateListener sheetStateListener) {
+        Prompt prompt = createPrompt(type, message);
+        prompt.open(owner, sheetStateListener);
+    }
+
+    private static Prompt createPrompt(MessageType type, String message) {
+        List<Object> options = new ArrayList<Object>();
+        options.add(resources.get("defaultOption"));
+
+        Prompt prompt = new Prompt(type, message, options, null);
+        prompt.setTitle((String)resources.get("defaultTitle"));
+        prompt.setSelectedOption(0);
+
+        return prompt;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.json
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.json?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.json (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Prompt.json Wed Mar 25 23:08:38 2009
@@ -0,0 +1,3 @@
+{   defaultOption: "OK",
+    defaultTitle: "Prompt"
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PromptListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PromptListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PromptListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PromptListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * Prompt listener interface.
+ *
+ * @author tvolkert
+ */
+public interface PromptListener {
+    /**
+     * Called when an prompt's selected option has changed.
+     *
+     * @param prompt
+     * @param previousSelectedOption
+     */
+    public void selectedOptionChanged(Prompt prompt, int previousSelectedOption);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PushButton.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PushButton.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PushButton.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/PushButton.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,66 @@
+/*
+ * 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.content.ButtonDataRenderer;
+
+/**
+ * Component representing a push button.
+ *
+ * @author gbrown
+ */
+public class PushButton extends Button {
+    private static final Button.DataRenderer DEFAULT_DATA_RENDERER = new ButtonDataRenderer();
+
+    public PushButton() {
+        this(false, null);
+    }
+
+    public PushButton(boolean toggleButton) {
+        this(toggleButton, null);
+    }
+
+    public PushButton(Object buttonData) {
+        this(false, buttonData);
+    }
+
+    public PushButton(boolean toggleButton, Object buttonData) {
+        super(buttonData);
+
+        setToggleButton(toggleButton);
+        setDataRenderer(DEFAULT_DATA_RENDERER);
+
+        installSkin(PushButton.class);
+    }
+
+    public void press() {
+        if (isToggleButton()) {
+            State state = getState();
+
+            if (state == State.SELECTED) {
+                setState(State.UNSELECTED);
+            }
+            else if (state == State.UNSELECTED) {
+                setState(isTriState() ? State.MIXED : State.SELECTED);
+            }
+            else {
+                setState(State.SELECTED);
+            }
+        }
+
+        super.press();
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RadioButton.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RadioButton.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RadioButton.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RadioButton.java Wed Mar 25 23:08:38 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.wtk;
+
+import pivot.wtk.content.ButtonDataRenderer;
+
+/**
+ * Component representing a "radio button".
+ *
+ * @author gbrown
+ */
+public class RadioButton extends Button {
+    private static final Button.DataRenderer DEFAULT_DATA_RENDERER = new ButtonDataRenderer();
+
+    static {
+        DEFAULT_DATA_RENDERER.getStyles().put("horizontalAlignment", HorizontalAlignment.LEFT);
+    }
+
+    public RadioButton() {
+        this(null, null);
+    }
+
+    public RadioButton(Group group) {
+        this(group, null);
+    }
+
+    public RadioButton(Object buttonData) {
+        this(null, buttonData);
+    }
+
+    public RadioButton(Group group, Object buttonData) {
+        super(buttonData);
+        super.setToggleButton(true);
+
+        setGroup(group);
+        setDataRenderer(DEFAULT_DATA_RENDERER);
+
+        installSkin(RadioButton.class);
+    }
+
+    public void press() {
+        setSelected(getGroup() == null ? !isSelected() : true);
+
+        super.press();
+    }
+
+    @Override
+    public void setToggleButton(boolean toggleButton) {
+        throw new UnsupportedOperationException("Radio buttons are always toggle buttons.");
+    }
+
+    @Override
+    public void setTriState(boolean triState) {
+        throw new UnsupportedOperationException("Radio buttons can't be tri-state.");
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RemoteManifest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RemoteManifest.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RemoteManifest.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RemoteManifest.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,139 @@
+/*
+ * 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.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import pivot.io.FileList;
+import pivot.wtk.media.Image;
+import pivot.wtk.media.Picture;
+
+/**
+ * Manifest class that acts as a proxy to remote clipboard or drag/drop data.
+ *
+ * @author gbrown
+ */
+public class RemoteManifest implements Manifest {
+    private Transferable transferable;
+
+    private DataFlavor textDataFlavor = null;
+    private DataFlavor imageDataFlavor = null;
+    private DataFlavor fileListDataFlavor = null;
+    private DataFlavor urlDataFlavor = null;
+
+    RemoteManifest(Transferable transferable) {
+        assert(transferable != null);
+        this.transferable = transferable;
+
+        DataFlavor[] transferDataFlavors = transferable.getTransferDataFlavors();
+        if (transferDataFlavors != null) {
+            for (int i = 0, n = transferDataFlavors.length; i < n; i++) {
+                DataFlavor dataFlavor = transferDataFlavors[i];
+
+                if (dataFlavor.equals(DataFlavor.stringFlavor)) {
+                    textDataFlavor = dataFlavor;
+                } else if (dataFlavor.equals(DataFlavor.imageFlavor)) {
+                    imageDataFlavor = dataFlavor;
+                } else if (dataFlavor.equals(DataFlavor.javaFileListFlavor)) {
+                    fileListDataFlavor = dataFlavor;
+                } else if (dataFlavor.getRepresentationClass() == URL.class) {
+                    urlDataFlavor = dataFlavor;
+                } else if (dataFlavor.isRepresentationClassByteBuffer()) {
+                    // TODO If we have a serializer for the type, deserialize it
+
+                    // TODO Do we still need a workaround for Sun bug #4147507
+                    // (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4147507)
+                    // if we are using ByteBuffers?
+                }
+            }
+        }
+    }
+
+    public String getText() throws IOException {
+        String text = null;
+        try {
+            text = (String)transferable.getTransferData(textDataFlavor);
+        } catch(UnsupportedFlavorException exception) {
+            System.err.println(exception);
+        }
+
+        return text;
+    }
+
+    public boolean containsText() {
+        return (textDataFlavor != null);
+    }
+
+    public Image getImage() throws IOException {
+        Image image = null;
+        try {
+            image = new Picture((BufferedImage)transferable.getTransferData(imageDataFlavor));
+        } catch(UnsupportedFlavorException exception) {
+            System.err.println(exception);
+        }
+
+        return image;
+    }
+
+    public boolean containsImage() {
+        return (imageDataFlavor != null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public FileList getFileList() throws IOException {
+        FileList fileList = null;
+        try {
+            fileList = new FileList((java.util.List<File>)transferable.getTransferData(fileListDataFlavor));
+        } catch(UnsupportedFlavorException exception) {
+            System.err.println(exception);
+        }
+
+        return fileList;
+    }
+
+    public boolean containsFileList() {
+        return (fileListDataFlavor != null);
+    }
+
+    public URL getURL() throws IOException {
+        URL url = null;
+        try {
+            url = (URL)transferable.getTransferData(urlDataFlavor);
+        } catch(UnsupportedFlavorException exception) {
+            System.err.println(exception);
+        }
+
+        return url;
+    }
+
+    public boolean containsURL() {
+        return (urlDataFlavor != null);
+    }
+
+    public Object getValue(String key) {
+        return null;
+    }
+
+    public boolean containsValue(String key) {
+        return false;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Renderer.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Renderer.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Renderer.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Renderer.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,31 @@
+/*
+ * 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.Dictionary;
+
+/**
+ * Base interface for "renderers". Renderers are used to customize the
+ * appearance of a component's content.
+ *
+ * @author gbrown
+ */
+public interface Renderer extends ConstrainedVisual {
+    /**
+     * Returns the renderer's style dictionary.
+     */
+    public Dictionary<String, Object> getStyles();
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Rollup.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Rollup.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Rollup.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Rollup.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,101 @@
+/*
+ * 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.ListenerList;
+import pivot.util.Vote;
+
+/**
+ * Container that can be expanded or collapsed to respectively show or hide its
+ * children. When expanded, the rollup's children are displayed vertically like
+ * a vertical flow pane. When collapsed, only the rollup's first child is
+ * displayed.
+ *
+ * @author gbrown
+ * @author tvolkert
+ */
+public class Rollup extends pivot.wtk.Container {
+    private static class RollupListenerList extends ListenerList<RollupListener>
+        implements RollupListener {
+        public Vote previewExpandedChange(Rollup rollup) {
+            Vote vote = Vote.APPROVE;
+
+            for (RollupListener listener : this) {
+                vote = vote.tally(listener.previewExpandedChange(rollup));
+            }
+
+            return vote;
+        }
+
+        public void expandedChangeVetoed(Rollup rollup, Vote reason) {
+            for (RollupListener listener : this) {
+                listener.expandedChangeVetoed(rollup, reason);
+            }
+        }
+
+        public void expandedChanged(Rollup rollup) {
+            for (RollupListener listener : this) {
+                listener.expandedChanged(rollup);
+            }
+        }
+    }
+
+    private boolean expanded = true;
+    private RollupListenerList rollupListeners = new RollupListenerList();
+
+    public Rollup() {
+        this(false, null);
+    }
+
+    public Rollup(boolean expanded) {
+        this(expanded, null);
+    }
+
+    public Rollup(Component firstChild) {
+        this(false, firstChild);
+    }
+
+    public Rollup(boolean expanded, Component firstChild) {
+        this.expanded = expanded;
+
+        installSkin(Rollup.class);
+
+        if (firstChild != null) {
+            add(firstChild);
+        }
+    }
+
+    public boolean isExpanded() {
+        return expanded;
+    }
+
+    public void setExpanded(boolean expanded) {
+        if (expanded != this.expanded) {
+            Vote vote = rollupListeners.previewExpandedChange(this);
+
+            if (vote == Vote.APPROVE) {
+                this.expanded = expanded;
+                rollupListeners.expandedChanged(this);
+            } else {
+                rollupListeners.expandedChangeVetoed(this, vote);
+            }
+        }
+    }
+
+    public ListenerList<RollupListener> getRollupListeners() {
+        return rollupListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RollupListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RollupListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RollupListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/RollupListener.java Wed Mar 25 23:08:38 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.wtk;
+
+import pivot.util.Vote;
+
+/**
+ * Defines event listener methods that pertain to rollups. Developers register
+ * for such events by adding themselves to a rollup's list of "rollup
+ * listeners" (see {@link Rollup#getRollupListeners()}).
+ *
+ * @author tvolkert
+ */
+public interface RollupListener {
+    /**
+     * Called to preview a rollup expansion event.
+     *
+     * @param rollup
+     */
+    public Vote previewExpandedChange(Rollup rollup);
+
+    /**
+     * Called when a rollup expansion event has been vetoed.
+     *
+     * @param rollup
+     * @param reason
+     */
+    public void expandedChangeVetoed(Rollup rollup, Vote reason);
+
+    /**
+     * Called when a rollup's expanded state changed.
+     *
+     * @param rollup
+     */
+    public void expandedChanged(Rollup rollup);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScriptApplication.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScriptApplication.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScriptApplication.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScriptApplication.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,60 @@
+/*
+ * 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.Dictionary;
+import pivot.wtkx.WTKXSerializer;
+
+/**
+ * Script application loader.
+ *
+ * @author gbrown
+ */
+public class ScriptApplication implements Application {
+	private Window window = null;
+
+	private static final String SRC_ARGUMENT = "src";
+	private static final String TITLE_ARGUMENT = "title";
+
+	public void startup(Display display, Dictionary<String, String> properties)
+		throws Exception {
+		if (!properties.containsKey(SRC_ARGUMENT)) {
+			throw new IllegalArgumentException(SRC_ARGUMENT + " argument is required.");
+		}
+
+		String src = properties.get(SRC_ARGUMENT);
+		String title = properties.get(TITLE_ARGUMENT);
+
+		WTKXSerializer wtkxSerializer = new WTKXSerializer();
+
+		Component content = (Component)wtkxSerializer.readObject(src);
+		window = new Window(content);
+		window.setTitle(title);
+		window.setMaximized(true);
+		window.open(display);
+	}
+
+	public boolean shutdown(boolean optional) {
+		window.close();
+		return true;
+	}
+
+	public void resume() {
+	}
+
+	public void suspend() {
+	}
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBar.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBar.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBar.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBar.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,214 @@
+/*
+ * 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.ListenerList;
+
+/**
+ * Component that allows a user to select one of a range of values. Most often
+ * used by scroll panes.
+ *
+ * @author gbrown
+ */
+public class ScrollBar extends Container {
+    private static class ScrollBarListenerList extends ListenerList<ScrollBarListener>
+        implements ScrollBarListener {
+        public void orientationChanged(ScrollBar scrollBar,
+            Orientation previousOrientation) {
+            for (ScrollBarListener listener : this) {
+                listener.orientationChanged(scrollBar, previousOrientation);
+            }
+        }
+
+        public void scopeChanged(ScrollBar scrollBar, int previousRangeStart,
+           int previousRangeEnd, int previousExtent) {
+            for (ScrollBarListener listener : this) {
+                listener.scopeChanged(scrollBar, previousRangeStart,
+                    previousRangeEnd, previousExtent);
+            }
+        }
+
+        public void unitIncrementChanged(ScrollBar scrollBar, int previousUnitIncrement) {
+            for (ScrollBarListener listener : this) {
+                listener.unitIncrementChanged(scrollBar, previousUnitIncrement);
+            }
+        }
+
+        public void blockIncrementChanged(ScrollBar scrollBar,
+            int previousBlockIncrement) {
+            for (ScrollBarListener listener : this) {
+                listener.blockIncrementChanged(scrollBar, previousBlockIncrement);
+            }
+        }
+    }
+
+    private static class ScrollBarValueListenerList extends ListenerList<ScrollBarValueListener>
+        implements ScrollBarValueListener {
+        public void valueChanged(ScrollBar scrollBar, int previousValue) {
+            for (ScrollBarValueListener listener : this) {
+                listener.valueChanged(scrollBar, previousValue);
+            }
+        }
+    }
+
+    private Orientation orientation;
+    private int rangeStart = 0;
+    private int rangeEnd = 100;
+    private int extent = 100;
+    private int value = 0;
+    private int unitIncrement = 1;
+    private int blockIncrement = 1;
+
+    private ScrollBarListenerList scrollBarListeners = new ScrollBarListenerList();
+    private ScrollBarValueListenerList scrollBarValueListeners =
+        new ScrollBarValueListenerList();
+
+    public ScrollBar(Orientation orientation) {
+        if (orientation == null) {
+            throw new IllegalArgumentException("orientation is null");
+        }
+
+        this.orientation = orientation;
+
+        installSkin(ScrollBar.class);
+    }
+
+    public Orientation getOrientation() {
+        return orientation;
+    }
+
+    public void setOrientation(Orientation orientation) {
+        if (orientation == null) {
+            throw new IllegalArgumentException("orientation is null");
+        }
+
+        Orientation previousOrientation = this.orientation;
+
+        if (orientation != previousOrientation) {
+            this.orientation = orientation;
+            scrollBarListeners.orientationChanged(this, previousOrientation);
+        }
+    }
+
+    public int getRangeStart() {
+        return rangeStart;
+    }
+
+    public int getRangeEnd() {
+        return rangeEnd;
+    }
+
+    public Span getRange() {
+        return new Span(rangeStart, rangeEnd);
+    }
+
+    public int getExtent() {
+        return extent;
+    }
+
+    public void setScope(int rangeStart, int rangeEnd, int extent) {
+        int previousRangeStart = this.rangeStart;
+        int previousRangeEnd = this.rangeEnd;
+        int previousExtent = this.extent;
+
+        if (rangeStart != previousRangeStart
+            || rangeEnd != previousRangeEnd
+            || extent != previousExtent) {
+            if (rangeStart > value) {
+                throw new IllegalArgumentException("rangeStart is greater than value");
+            }
+
+            if (extent < 0) {
+                throw new IllegalArgumentException("extent is negative");
+            }
+
+            if (rangeEnd < value + extent) {
+                throw new IllegalArgumentException("rangeEnd is less than value+extent");
+            }
+
+            this.rangeStart = rangeStart;
+            this.rangeEnd = rangeEnd;
+            this.extent = extent;
+
+            scrollBarListeners.scopeChanged(this, previousRangeStart,
+                previousRangeEnd, previousExtent);
+        }
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        int previousValue = this.value;
+
+        if (value != previousValue) {
+            if (value < rangeStart) {
+                throw new IllegalArgumentException("value is less than rangeStart");
+            }
+
+            if (value + extent > rangeEnd) {
+                throw new IllegalArgumentException("value+extent is greater than rangeEnd");
+            }
+
+            this.value = value;
+
+            scrollBarValueListeners.valueChanged(this, previousValue);
+        }
+    }
+
+    public int getUnitIncrement() {
+        return unitIncrement;
+    }
+
+    public void setUnitIncrement(int unitIncrement) {
+        if (unitIncrement < 0) {
+            throw new IllegalArgumentException("unitIncrement is negative");
+        }
+
+        int previousUnitIncrement = this.unitIncrement;
+
+        if (unitIncrement != previousUnitIncrement) {
+            this.unitIncrement = unitIncrement;
+            scrollBarListeners.unitIncrementChanged(this, previousUnitIncrement);
+        }
+    }
+
+    public int getBlockIncrement() {
+        return blockIncrement;
+    }
+
+    public void setBlockIncrement(int blockIncrement) {
+        if (blockIncrement < 0) {
+            throw new IllegalArgumentException("blockIncrement is negative");
+        }
+
+        int previousBlockIncrement = this.blockIncrement;
+
+        if (blockIncrement != previousBlockIncrement) {
+            this.blockIncrement = blockIncrement;
+            scrollBarListeners.blockIncrementChanged(this, previousBlockIncrement);
+        }
+    }
+
+    public ListenerList<ScrollBarListener> getScrollBarListeners() {
+        return scrollBarListeners;
+    }
+
+    public ListenerList<ScrollBarValueListener> getScrollBarValueListeners() {
+        return scrollBarValueListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+/**
+ * Scroll bar listener interface.
+ *
+ * @author tvolkert
+ */
+public interface ScrollBarListener {
+    /**
+     * Called when a scroll bar's orientation has changed.
+     *
+     * @param scrollBar
+     * @param previousOrientation
+     */
+    public void orientationChanged(ScrollBar scrollBar, Orientation previousOrientation);
+
+    /**
+     * Called when a scroll bar's scope has changed.
+     *
+     * @param scrollBar
+     * @param previousRangeStart
+     * @param previousRangeEnd
+     * @param previousExtent
+     */
+    public void scopeChanged(ScrollBar scrollBar, int previousRangeStart,
+        int previousRangeEnd, int previousExtent);
+
+    /**
+     * Called when a scroll bar's unit increment has changed.
+     *
+     * @param scrollBar
+     * @param previousUnitIncrement
+     */
+    public void unitIncrementChanged(ScrollBar scrollBar, int previousUnitIncrement);
+
+    /**
+     * Called when a scroll bar's block increment ahs changed.
+     *
+     * @param scrollBar
+     * @param previousBlockIncrement
+     */
+    public void blockIncrementChanged(ScrollBar scrollBar, int previousBlockIncrement);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarValueListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarValueListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarValueListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollBarValueListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * Scroll bar value listener interface.
+ *
+ * @author tvolkert
+ */
+public interface ScrollBarValueListener {
+    /**
+     * Called when a scroll bar's value has changed.
+     *
+     * @param scrollBar
+     * @param previousValue
+     */
+    public void valueChanged(ScrollBar scrollBar, int previousValue);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPane.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPane.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPane.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPane.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,350 @@
+/*
+ * 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;
+
+/**
+ * Container that provides a scrollable view of a component, with optional
+ * fixed row and column headers.
+ *
+ * @author tvolkert
+ */
+public class ScrollPane extends Viewport {
+    /**
+     * Enumeration defining scroll pane scroll bar policies.
+     *
+     * @author gbrown
+     */
+    public enum ScrollBarPolicy {
+        AUTO,
+        NEVER,
+        ALWAYS,
+        FILL,
+        FILL_TO_CAPACITY;
+
+        public static ScrollBarPolicy decode(String value) {
+            if (value == null) {
+                throw new IllegalArgumentException("value is null.");
+            }
+
+            ScrollBarPolicy scrollBarPolicy = null;
+
+            if (value.equalsIgnoreCase("auto")) {
+                scrollBarPolicy = AUTO;
+            } else if (value.equalsIgnoreCase("never")) {
+                scrollBarPolicy = NEVER;
+            } else if (value.equalsIgnoreCase("always")) {
+                scrollBarPolicy = ALWAYS;
+            } else if (value.equalsIgnoreCase("fill")) {
+                scrollBarPolicy = FILL;
+            } else if (value.equalsIgnoreCase("fillToCapacity")) {
+                scrollBarPolicy = FILL_TO_CAPACITY;
+            } else {
+                throw new IllegalArgumentException("\"" + value
+                    + "\" is not a valid scroll bar policy.");
+            }
+
+            return scrollBarPolicy;
+        }
+    }
+
+    private static class ScrollPaneListenerList extends ListenerList<ScrollPaneListener>
+        implements ScrollPaneListener {
+
+        public void horizontalScrollBarPolicyChanged(ScrollPane scrollPane,
+            ScrollBarPolicy previousHorizontalScrollBarPolicy) {
+            for (ScrollPaneListener listener : this) {
+                listener.horizontalScrollBarPolicyChanged(scrollPane,
+                    previousHorizontalScrollBarPolicy);
+            }
+        }
+
+        public void verticalScrollBarPolicyChanged(ScrollPane scrollPane,
+            ScrollBarPolicy previousVerticalScrollBarPolicy) {
+            for (ScrollPaneListener listener : this) {
+                listener.verticalScrollBarPolicyChanged(scrollPane,
+                    previousVerticalScrollBarPolicy);
+            }
+        }
+
+        public void rowHeaderChanged(ScrollPane scrollPane, Component previousRowHeader) {
+            for (ScrollPaneListener listener : this) {
+                listener.rowHeaderChanged(scrollPane, previousRowHeader);
+            }
+        }
+
+        public void columnHeaderChanged(ScrollPane scrollPane,
+            Component previousColumnHeader) {
+            for (ScrollPaneListener listener : this) {
+                listener.columnHeaderChanged(scrollPane, previousColumnHeader);
+            }
+        }
+
+        public void cornerChanged(ScrollPane scrollPane, Component previousCorner) {
+            for (ScrollPaneListener listener : this) {
+                listener.cornerChanged(scrollPane, previousCorner);
+            }
+        }
+    }
+
+    /**
+     * Component class representing the components that will get placed in the
+     * corners of a <tt>ScrollPane</tt>. Skins will instantiate these
+     * components as needed when unfilled corners are introduced by a row
+     * header or column header.
+     *
+     * @author tvolkert
+     */
+    public static class Corner extends Component {
+        /**
+         * Enumeration defining placement values for scroll pane corners.
+         *
+         * @author tvolkert
+         */
+        public static enum Placement {
+            TOP_LEFT,
+            BOTTOM_LEFT,
+            BOTTOM_RIGHT,
+            TOP_RIGHT;
+        }
+
+        private Placement placement;
+
+        public Corner(Placement placement) {
+            if (placement == null) {
+                throw new IllegalArgumentException("Placement is null.");
+            }
+
+            this.placement = placement;
+
+            installSkin(Corner.class);
+        }
+
+        public Placement getPlacement() {
+            return placement;
+        }
+    }
+
+    private ScrollBarPolicy horizontalScrollBarPolicy;
+    private ScrollBarPolicy verticalScrollBarPolicy;
+    private Component rowHeader;
+    private Component columnHeader;
+    private Component corner;
+    private ScrollPaneListenerList scrollPaneListeners = new ScrollPaneListenerList();
+
+    public ScrollPane() {
+        this(ScrollBarPolicy.AUTO, ScrollBarPolicy.AUTO);
+    }
+
+    public ScrollPane(ScrollBarPolicy horizontalScrollBarPolicy,
+        ScrollBarPolicy verticalScrollBarPolicy) {
+        super();
+
+        if (horizontalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("horizontalScrollBarPolicy is null");
+        }
+
+        if (verticalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("verticalScrollBarPolicy is null");
+        }
+
+        this.horizontalScrollBarPolicy = horizontalScrollBarPolicy;
+        this.verticalScrollBarPolicy = verticalScrollBarPolicy;
+
+        installSkin(ScrollPane.class);
+    }
+
+    public ScrollBarPolicy getHorizontalScrollBarPolicy() {
+        return horizontalScrollBarPolicy;
+    }
+
+    public void setHorizontalScrollBarPolicy(ScrollBarPolicy horizontalScrollBarPolicy) {
+        if (horizontalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("horizontalScrollBarPolicy is null");
+        }
+
+        ScrollBarPolicy previousHorizontalScrollBarPolicy = this.horizontalScrollBarPolicy;
+
+        if (horizontalScrollBarPolicy != previousHorizontalScrollBarPolicy) {
+            this.horizontalScrollBarPolicy = horizontalScrollBarPolicy;
+            scrollPaneListeners.horizontalScrollBarPolicyChanged(this,
+                previousHorizontalScrollBarPolicy);
+        }
+    }
+
+    public void setHorizontalScrollBarPolicy(String horizontalScrollBarPolicy) {
+        if (horizontalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("horizontalScrollBarPolicy is null.");
+        }
+
+        setHorizontalScrollBarPolicy(ScrollBarPolicy.decode(horizontalScrollBarPolicy));
+    }
+
+    public ScrollBarPolicy getVerticalScrollBarPolicy() {
+        return verticalScrollBarPolicy;
+    }
+
+    public void setVerticalScrollBarPolicy(ScrollBarPolicy verticalScrollBarPolicy) {
+        if (verticalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("verticalScrollBarPolicy is null");
+        }
+
+        ScrollBarPolicy previousVerticalScrollBarPolicy = this.verticalScrollBarPolicy;
+
+        if (verticalScrollBarPolicy != previousVerticalScrollBarPolicy) {
+            this.verticalScrollBarPolicy = verticalScrollBarPolicy;
+            scrollPaneListeners.verticalScrollBarPolicyChanged(this,
+                previousVerticalScrollBarPolicy);
+        }
+    }
+
+    public void setVerticalScrollBarPolicy(String verticalScrollBarPolicy) {
+        if (verticalScrollBarPolicy == null) {
+            throw new IllegalArgumentException("verticalScrollBarPolicy is null.");
+        }
+
+        setVerticalScrollBarPolicy(ScrollBarPolicy.decode(verticalScrollBarPolicy));
+    }
+
+    public Component getRowHeader() {
+        return rowHeader;
+    }
+
+    public void setRowHeader(Component rowHeader) {
+        Component previousRowHeader = this.rowHeader;
+
+        if (rowHeader != previousRowHeader) {
+            // Remove any previous rowHeader component
+            if (previousRowHeader != null) {
+                remove(previousRowHeader);
+            }
+
+            this.rowHeader = null;
+
+            if (rowHeader != null) {
+                if (rowHeader.getParent() != null) {
+                    throw new IllegalArgumentException("Component already has a parent.");
+                }
+
+                int insertionIndex = 0;
+
+                if (getView() != null) {
+                    insertionIndex++;
+                }
+
+                // Add the component
+                insert(rowHeader, insertionIndex);
+            }
+
+            this.rowHeader = rowHeader;
+
+            scrollPaneListeners.rowHeaderChanged(this, previousRowHeader);
+        }
+    }
+
+    public Component getColumnHeader() {
+        return columnHeader;
+    }
+
+    public void setColumnHeader(Component columnHeader) {
+        Component previousColumnHeader = this.columnHeader;
+
+        if (columnHeader != previousColumnHeader) {
+            // Remove any previous columnHeader component
+            if (previousColumnHeader != null) {
+                remove(previousColumnHeader);
+            }
+
+            this.columnHeader = null;
+
+            if (columnHeader != null) {
+                int insertionIndex = 0;
+
+                if (getView() != null) {
+                    insertionIndex++;
+                }
+
+                // Add the component
+                insert(columnHeader, insertionIndex);
+            }
+
+            this.columnHeader = columnHeader;
+
+            scrollPaneListeners.columnHeaderChanged(this, previousColumnHeader);
+        }
+    }
+
+    public Component getCorner() {
+        return corner;
+    }
+
+    public void setCorner(Component corner) {
+        Component previousCorner = this.corner;
+
+        if (corner != this.corner) {
+            // Remove any previous corner component
+            if (previousCorner != null) {
+                remove(previousCorner);
+            }
+
+            this.corner = null;
+
+            if (corner != null) {
+                int insertionIndex = 0;
+
+                if (getView() != null) {
+                    insertionIndex++;
+                }
+
+                if (rowHeader != null) {
+                    insertionIndex++;
+                }
+
+                if (columnHeader != null) {
+                    insertionIndex++;
+                }
+
+                // Add the component
+                insert(corner, insertionIndex);
+            }
+
+            this.corner = corner;
+
+            scrollPaneListeners.cornerChanged(this, previousCorner);
+        }
+    }
+
+    @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 == rowHeader
+                || component == columnHeader
+                || component == corner) {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // Call the base method to remove the components
+        return super.remove(index, count);
+    }
+
+    public ListenerList<ScrollPaneListener> getScrollPaneListeners() {
+        return scrollPaneListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPaneListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPaneListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPaneListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/ScrollPaneListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+/**
+ * Scroll pane listener interface.
+ *
+ * @author tvolkert
+ */
+public interface ScrollPaneListener {
+    /**
+     * Called when the scroll pane's horizontal scroll bar policy changed.
+     *
+     * @param scrollPane
+     * @param previousPolicy
+     */
+    public void horizontalScrollBarPolicyChanged(ScrollPane scrollPane,
+        ScrollPane.ScrollBarPolicy previousPolicy);
+
+    /**
+     * Called when the scroll pane's vertical scroll bar policy changed.
+     *
+     * @param scrollPane
+     * @param previousPolicy
+     */
+    public void verticalScrollBarPolicyChanged(ScrollPane scrollPane,
+        ScrollPane.ScrollBarPolicy previousPolicy);
+
+    /**
+     * Called when the scroll pane's row header changed.
+     *
+     * @param scrollPane
+     * @param previousRowHeader
+     */
+    public void rowHeaderChanged(ScrollPane scrollPane, Component previousRowHeader);
+
+    /**
+     * Called when the scroll pane's column header changed.
+     *
+     * @param scrollPane
+     * @param previousColumnHeader
+     */
+    public void columnHeaderChanged(ScrollPane scrollPane,
+        Component previousColumnHeader);
+
+    /**
+     * Called when the scroll pane's corner component changed.
+     *
+     * @param scrollPane
+     * @param previousCorner
+     */
+    public void cornerChanged(ScrollPane scrollPane, Component previousCorner);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Separator.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Separator.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Separator.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Separator.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,61 @@
+package pivot.wtk;
+
+import pivot.util.ListenerList;
+
+/**
+ * Component representing a horizontal divider.
+ *
+ * @author gbrown
+ */
+public class Separator extends Component {
+    private static class SeparatorListenerList extends ListenerList<SeparatorListener>
+        implements SeparatorListener {
+        public void headingChanged(Separator separator, String previousHeading) {
+            for (SeparatorListener listener : this) {
+                listener.headingChanged(separator, previousHeading);
+            }
+        }
+    }
+
+    private String heading = null;
+
+    private SeparatorListenerList separatorListeners = new SeparatorListenerList();
+
+    public Separator() {
+        this(null);
+    }
+
+    public Separator(String heading) {
+        setHeading(heading);
+        installSkin(Separator.class);
+    }
+
+    /**
+     * Returns the separator's heading.
+     *
+     * @return
+     * The separator's heading, or <tt>null</tt> if no heading is set.
+     */
+    public String getHeading() {
+        return heading;
+    }
+
+    /**
+     * Sets the separator's heading.
+     *
+     * @param heading
+     * The new heading, or <tt>null</tt> for no heading.
+     */
+    public void setHeading(String heading) {
+        String previousHeading = this.heading;
+
+        if (previousHeading != heading) {
+            this.heading = heading;
+            separatorListeners.headingChanged(this, previousHeading);
+        }
+    }
+
+    public ListenerList<SeparatorListener> getSeparatorListeners() {
+        return separatorListeners;
+    }
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/SeparatorListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/SeparatorListener.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/SeparatorListener.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/SeparatorListener.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,16 @@
+package pivot.wtk;
+
+/**
+ * Separator listener interface.
+ *
+ * @author gbrown
+ */
+public interface SeparatorListener {
+    /**
+     * Called when a separator's heading has changed.
+     *
+     * @param separator
+     * @param previousHeading
+     */
+    public void headingChanged(Separator separator, String previousHeading);
+}

Added: incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Sheet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Sheet.java?rev=758461&view=auto
==============================================================================
--- incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Sheet.java (added)
+++ incubator/pivot/branches/1.1/wtk/src/pivot/wtk/Sheet.java Wed Mar 25 23:08:38 2009
@@ -0,0 +1,225 @@
+/*
+ * 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.ListenerList;
+import pivot.util.Vote;
+
+/**
+ * Window class representing a "sheet". A sheet behaves like a dialog that is
+ * modal only over a window's content component.
+ *
+ * @author gbrown
+ */
+public class Sheet extends Window {
+    private static class SheetStateListenerList extends ListenerList<SheetStateListener>
+        implements SheetStateListener {
+        public Vote previewSheetClose(Sheet sheet, boolean result) {
+            Vote vote = Vote.APPROVE;
+
+            for (SheetStateListener listener : this) {
+                vote = vote.tally(listener.previewSheetClose(sheet, result));
+            }
+
+            return vote;
+        }
+
+        public void sheetCloseVetoed(Sheet sheet, Vote reason) {
+            for (SheetStateListener listener : this) {
+                listener.sheetCloseVetoed(sheet, reason);
+            }
+        }
+
+        public void sheetClosed(Sheet sheet) {
+            for (SheetStateListener listener : this) {
+                listener.sheetClosed(sheet);
+            }
+        }
+    }
+
+    private boolean result = false;
+    private SheetCloseListener sheetCloseListener = null;
+
+    private ComponentListener ownerListener = new ComponentListener() {
+        public void parentChanged(Component component, Container previousParent) {
+            // No-op
+        }
+
+        public void sizeChanged(Component component, int previousWidth, int previousHeight) {
+            ApplicationContext.queueCallback(new Runnable() {
+                public void run() {
+                    alignToOwnerContent();
+                }
+            });
+        }
+
+        public void locationChanged(Component component, int previousX, int previousY) {
+            alignToOwnerContent();
+        }
+
+        public void visibleChanged(Component component) {
+            // No-op
+        }
+
+        public void styleUpdated(Component component, String styleKey, Object previousValue) {
+            // No-op
+        }
+
+        public void cursorChanged(Component component, Cursor previousCursor) {
+            // No-op
+        }
+
+        public void tooltipTextChanged(Component component, String previousTooltipText) {
+            // No-op
+        }
+    };
+
+    private SheetStateListenerList sheetStateListeners = new SheetStateListenerList();
+
+    /**
+     * Creates a new sheet.
+     */
+    public Sheet() {
+        this(null);
+    }
+
+    /**
+     * Creates a new sheet with an initial content component.
+     *
+     * @param content
+     * The sheet's content component.
+     */
+    public Sheet(Component content) {
+        super(content, true);
+
+        installSkin(Sheet.class);
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+    	super.setSize(width, height);
+
+        ApplicationContext.queueCallback(new Runnable() {
+            public void run() {
+                alignToOwnerContent();
+            }
+        });
+    }
+
+    @Override
+    public final void setOwner(Window owner) {
+        if (owner == null) {
+            throw new UnsupportedOperationException("A sheet must have an owner.");
+        }
+
+        if (owner.getContent() == null) {
+            throw new UnsupportedOperationException("A sheet's owner must have a content component.");
+        }
+
+        super.setOwner(owner);
+    }
+
+    @Override
+    public void open(Display display) {
+        super.open(display);
+
+        if (isOpen()) {
+            Window owner = getOwner();
+            owner.getComponentListeners().add(ownerListener);
+
+            Component content = owner.getContent();
+            if (content.isBlocked()) {
+            	throw new IllegalStateException("Owner content is already blocked.");
+            }
+
+            content.setEnabled(false);
+
+            ApplicationContext.queueCallback(new Runnable() {
+                public void run() {
+                    alignToOwnerContent();
+                }
+            });
+        }
+    }
+
+    public final void open(Window owner) {
+        open(owner, null);
+    }
+
+    public void open(Window owner, SheetCloseListener sheetCloseListener) {
+        super.open(owner);
+
+        if (isOpen()) {
+            this.sheetCloseListener = sheetCloseListener;
+        }
+    }
+
+    @Override
+    public final void close() {
+        close(false);
+    }
+
+    public void close(boolean result) {
+        if (!isClosed()) {
+            Vote vote = sheetStateListeners.previewSheetClose(this, result);
+
+            if (vote.isApproved()) {
+                super.close();
+
+                if (isClosed()) {
+                    this.result = result;
+
+                    Window owner = getOwner();
+                    owner.getComponentListeners().remove(ownerListener);
+
+                    Component content = owner.getContent();
+                    content.setEnabled(true);
+
+                    owner.moveToFront();
+
+                    if (sheetCloseListener != null) {
+                        sheetCloseListener.sheetClosed(this);
+                        sheetCloseListener = null;
+                    }
+
+                    sheetStateListeners.sheetClosed(this);
+                }
+            } else {
+                sheetStateListeners.sheetCloseVetoed(this, vote);
+            }
+        }
+    }
+
+    public SheetCloseListener getSheetCloseListener() {
+        return sheetCloseListener;
+    }
+
+    public boolean getResult() {
+        return result;
+    }
+
+    private void alignToOwnerContent() {
+        Window owner = getOwner();
+        Component content = owner.getContent();
+        Point contentLocation = content.mapPointToAncestor(owner.getDisplay(), 0, 0);
+        setLocation(contentLocation.x + (content.getWidth() - getWidth()) / 2,
+            contentLocation.y);
+    }
+
+    public ListenerList<SheetStateListener> getSheetStateListeners() {
+        return sheetStateListeners;
+    }
+}