You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2010/04/23 15:09:26 UTC

svn commit: r937280 - in /pivot/trunk: core/src/org/apache/pivot/beans/ wtk-terra/src/org/apache/pivot/wtk/skin/terra/ wtk/src/org/apache/pivot/wtk/

Author: gbrown
Date: Fri Apr 23 13:09:26 2010
New Revision: 937280

URL: http://svn.apache.org/viewvc?rev=937280&view=rev
Log:
Initial work on PIVOT-415.

Modified:
    pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraAlertSkin.java
    pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraPromptSkin.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/Alert.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/AlertListener.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/Prompt.java
    pivot/trunk/wtk/src/org/apache/pivot/wtk/PromptListener.java

Modified: pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java Fri Apr 23 13:09:26 2010
@@ -504,7 +504,7 @@ public class BeanAdapter implements Map<
     }
 
     /**
-     * Tests the read-only state of a property. Note that is no such property
+     * Tests the read-only state of a property. Note that if no such property
      * exists, this method will return <tt>true</tt> (it will <u>not</u> throw
      * an exception).
      *

Modified: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraAlertSkin.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraAlertSkin.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraAlertSkin.java (original)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraAlertSkin.java Fri Apr 23 13:09:26 2010
@@ -22,6 +22,7 @@ import java.net.URL;
 
 import org.apache.pivot.collections.ArrayList;
 import org.apache.pivot.collections.Map;
+import org.apache.pivot.collections.Sequence;
 import org.apache.pivot.json.JSONSerializer;
 import org.apache.pivot.serialization.SerializationException;
 import org.apache.pivot.wtk.Alert;
@@ -32,6 +33,7 @@ import org.apache.pivot.wtk.Component;
 import org.apache.pivot.wtk.BoxPane;
 import org.apache.pivot.wtk.ImageView;
 import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.MessageType;
 import org.apache.pivot.wtk.PushButton;
 import org.apache.pivot.wtk.Theme;
 import org.apache.pivot.wtk.Window;
@@ -43,8 +45,29 @@ import org.apache.pivot.wtkx.WTKXSeriali
 @SuppressWarnings("unchecked")
 public class TerraAlertSkin extends TerraDialogSkin
     implements AlertListener {
+    private ImageView typeImageView = null;
+    private Label messageLabel = null;
+    private BoxPane messageBoxPane = null;
+
+    // TODO Rename to optionButtonBoxPane?
+    private BoxPane buttonBoxPane = null;
+
+    // TODO Do we need this?
     private ArrayList<Button> optionButtons = new ArrayList<Button>();
 
+    private ButtonPressListener optionButtonPressListener = new ButtonPressListener() {
+        @Override
+        public void buttonPressed(Button button) {
+            int optionIndex = optionButtons.indexOf(button);
+
+            if (optionIndex >= 0) {
+                Alert alert = (Alert)getComponent();
+                alert.setSelectedOption(optionIndex);
+                alert.close(true);
+            }
+        }
+    };
+
     private static Map<String, ?> commandButtonStyles;
 
     static {
@@ -82,8 +105,8 @@ public class TerraAlertSkin extends Terr
 
         // Load the alert content
         WTKXSerializer wtkxSerializer = new WTKXSerializer();
-        Component content = null;
 
+        Component content;
         try {
             content = (Component)wtkxSerializer.readObject(this, "terra_alert_skin.wtkx");
         } catch(Exception exception) {
@@ -92,49 +115,23 @@ public class TerraAlertSkin extends Terr
 
         alert.setContent(content);
 
-        // Set the type image
-        TerraTheme theme = (TerraTheme)Theme.getTheme();
-
-        ImageView typeImageView = (ImageView)wtkxSerializer.get("typeImageView");
-        typeImageView.setImage(theme.getMessageIcon(alert.getMessageType()));
-
-        // Set the message
-        Label messageLabel = (Label)wtkxSerializer.get("messageLabel");
-        String message = alert.getMessage();
-        messageLabel.setText(message);
-
-        // Set the body
-        BoxPane messageBoxPane = (BoxPane)wtkxSerializer.get("messageBoxPane");
-        Component body = alert.getBody();
-        if (body != null) {
-            messageBoxPane.add(body);
-        }
-
-        // Add the option buttons
-        BoxPane buttonBoxPane = (BoxPane)wtkxSerializer.get("buttonBoxPane");
-
-        for (int i = 0, n = alert.getOptionCount(); i < n; i++) {
-            Object option = alert.getOption(i);
+        typeImageView = (ImageView)wtkxSerializer.get("typeImageView");
+        messageLabel = (Label)wtkxSerializer.get("messageLabel");
+        messageBoxPane = (BoxPane)wtkxSerializer.get("messageBoxPane");
+        buttonBoxPane = (BoxPane)wtkxSerializer.get("buttonBoxPane");
 
+        for (Object option : alert.getOptions()) {
             PushButton optionButton = new PushButton(option);
             optionButton.setStyles(commandButtonStyles);
-
-            optionButton.getButtonPressListeners().add(new ButtonPressListener() {
-                @Override
-                public void buttonPressed(Button button) {
-                    int optionIndex = optionButtons.indexOf(button);
-
-                    if (optionIndex >= 0) {
-                        Alert alert = (Alert)getComponent();
-                        alert.setSelectedOption(optionIndex);
-                        alert.close(true);
-                    }
-                }
-            });
+            optionButton.getButtonPressListeners().add(optionButtonPressListener);
 
             buttonBoxPane.add(optionButton);
             optionButtons.add(optionButton);
         }
+
+        messageTypeChanged(alert, null);
+        messageChanged(alert, null);
+        bodyChanged(alert, null);
     }
 
     @Override
@@ -152,6 +149,47 @@ public class TerraAlertSkin extends Terr
     }
 
     @Override
+    public void messageTypeChanged(Alert alert, MessageType previousMessageType) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        typeImageView.setImage(theme.getMessageIcon(alert.getMessageType()));
+    }
+
+    @Override
+    public void messageChanged(Alert alert, String previousMessage) {
+        messageLabel.setText(alert.getMessage());
+    }
+
+    @Override
+    public void bodyChanged(Alert alert, Component previousBody) {
+        if (previousBody != null) {
+            messageBoxPane.remove(previousBody);
+        }
+
+        Component body = alert.getBody();
+        if (body != null) {
+            messageBoxPane.add(body);
+        }
+    }
+
+    @Override
+    public void optionInserted(Alert alert, int index) {
+        Object option = alert.getOptions().get(index);
+
+        PushButton optionButton = new PushButton(option);
+        optionButton.setStyles(commandButtonStyles);
+        optionButton.getButtonPressListeners().add(optionButtonPressListener);
+
+        buttonBoxPane.insert(optionButton, index);
+        optionButtons.insert(optionButton, index);
+    }
+
+    @Override
+    public void optionsRemoved(Alert alert, int index, Sequence<?> removed) {
+        buttonBoxPane.remove(index, removed.getLength());
+        optionButtons.remove(index, removed.getLength());
+    }
+
+    @Override
     public void selectedOptionChanged(Alert alert, int previousSelectedOption) {
         int index = alert.getSelectedOption();
 

Modified: pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraPromptSkin.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraPromptSkin.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraPromptSkin.java (original)
+++ pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraPromptSkin.java Fri Apr 23 13:09:26 2010
@@ -22,6 +22,7 @@ import java.net.URL;
 
 import org.apache.pivot.collections.ArrayList;
 import org.apache.pivot.collections.Map;
+import org.apache.pivot.collections.Sequence;
 import org.apache.pivot.json.JSONSerializer;
 import org.apache.pivot.serialization.SerializationException;
 import org.apache.pivot.wtk.Button;
@@ -30,6 +31,7 @@ import org.apache.pivot.wtk.Component;
 import org.apache.pivot.wtk.BoxPane;
 import org.apache.pivot.wtk.ImageView;
 import org.apache.pivot.wtk.Label;
+import org.apache.pivot.wtk.MessageType;
 import org.apache.pivot.wtk.Prompt;
 import org.apache.pivot.wtk.PromptListener;
 import org.apache.pivot.wtk.PushButton;
@@ -43,8 +45,29 @@ import org.apache.pivot.wtkx.WTKXSeriali
 @SuppressWarnings("unchecked")
 public class TerraPromptSkin extends TerraSheetSkin
     implements PromptListener {
+    private ImageView typeImageView = null;
+    private Label messageLabel = null;
+    private BoxPane messageBoxPane = null;
+
+    // TODO Rename to optionButtonBoxPane?
+    private BoxPane buttonBoxPane = null;
+
+    // TODO Do we need this?
     private ArrayList<Button> optionButtons = new ArrayList<Button>();
 
+    private ButtonPressListener optionButtonPressListener = new ButtonPressListener() {
+        @Override
+        public void buttonPressed(Button button) {
+            int optionIndex = optionButtons.indexOf(button);
+
+            if (optionIndex >= 0) {
+                Prompt prompt = (Prompt)getComponent();
+                prompt.setSelectedOption(optionIndex);
+                prompt.close(true);
+            }
+        }
+    };
+
     private static Map<String, ?> commandButtonStyles;
 
     static {
@@ -75,8 +98,8 @@ public class TerraPromptSkin extends Ter
 
         // Load the prompt content
         WTKXSerializer wtkxSerializer = new WTKXSerializer();
-        Component content = null;
 
+        Component content;
         try {
             content = (Component)wtkxSerializer.readObject(this, "terra_prompt_skin.wtkx");
         } catch(Exception exception) {
@@ -85,49 +108,23 @@ public class TerraPromptSkin extends Ter
 
         prompt.setContent(content);
 
-        // Set the type image
-        TerraTheme theme = (TerraTheme)Theme.getTheme();
-
-        ImageView typeImageView = (ImageView)wtkxSerializer.get("typeImageView");
-        typeImageView.setImage(theme.getMessageIcon(prompt.getMessageType()));
-
-        // Set the message
-        Label messageLabel = (Label)wtkxSerializer.get("messageLabel");
-        String message = prompt.getMessage();
-        messageLabel.setText(message);
-
-        // Set the body
-        BoxPane messageBoxPane = (BoxPane)wtkxSerializer.get("messageBoxPane");
-        Component body = prompt.getBody();
-        if (body != null) {
-            messageBoxPane.add(body);
-        }
-
-        // Add the option buttons
-        BoxPane buttonBoxPane = (BoxPane)wtkxSerializer.get("buttonBoxPane");
-
-        for (int i = 0, n = prompt.getOptionCount(); i < n; i++) {
-            Object option = prompt.getOption(i);
+        typeImageView = (ImageView)wtkxSerializer.get("typeImageView");
+        messageLabel = (Label)wtkxSerializer.get("messageLabel");
+        messageBoxPane = (BoxPane)wtkxSerializer.get("messageBoxPane");
+        buttonBoxPane = (BoxPane)wtkxSerializer.get("buttonBoxPane");
 
+        for (Object option : prompt.getOptions()) {
             PushButton optionButton = new PushButton(option);
             optionButton.setStyles(commandButtonStyles);
-
-            optionButton.getButtonPressListeners().add(new ButtonPressListener() {
-                @Override
-                public void buttonPressed(Button button) {
-                    int optionIndex = optionButtons.indexOf(button);
-
-                    if (optionIndex >= 0) {
-                        Prompt prompt = (Prompt)getComponent();
-                        prompt.setSelectedOption(optionIndex);
-                        prompt.close(true);
-                    }
-                }
-            });
+            optionButton.getButtonPressListeners().add(optionButtonPressListener);
 
             buttonBoxPane.add(optionButton);
             optionButtons.add(optionButton);
         }
+
+        messageTypeChanged(prompt, null);
+        messageChanged(prompt, null);
+        bodyChanged(prompt, null);
     }
 
     @Override
@@ -145,6 +142,47 @@ public class TerraPromptSkin extends Ter
     }
 
     @Override
+    public void messageTypeChanged(Prompt prompt, MessageType previousMessageType) {
+        TerraTheme theme = (TerraTheme)Theme.getTheme();
+        typeImageView.setImage(theme.getMessageIcon(prompt.getMessageType()));
+    }
+
+    @Override
+    public void messageChanged(Prompt prompt, String previousMessage) {
+        messageLabel.setText(prompt.getMessage());
+    }
+
+    @Override
+    public void bodyChanged(Prompt prompt, Component previousBody) {
+        if (previousBody != null) {
+            messageBoxPane.remove(previousBody);
+        }
+
+        Component body = prompt.getBody();
+        if (body != null) {
+            messageBoxPane.add(body);
+        }
+    }
+
+    @Override
+    public void optionInserted(Prompt prompt, int index) {
+        Object option = prompt.getOptions().get(index);
+
+        PushButton optionButton = new PushButton(option);
+        optionButton.setStyles(commandButtonStyles);
+        optionButton.getButtonPressListeners().add(optionButtonPressListener);
+
+        buttonBoxPane.insert(optionButton, index);
+        optionButtons.insert(optionButton, index);
+    }
+
+    @Override
+    public void optionsRemoved(Prompt prompt, int index, Sequence<?> removed) {
+        buttonBoxPane.remove(index, removed.getLength());
+        optionButtons.remove(index, removed.getLength());
+    }
+
+    @Override
     public void selectedOptionChanged(Prompt prompt, int previousSelectedOption) {
         int index = prompt.getSelectedOption();
 

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/Alert.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/Alert.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/Alert.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/Alert.java Fri Apr 23 13:09:26 2010
@@ -16,21 +16,144 @@
  */
 package org.apache.pivot.wtk;
 
+import java.util.Iterator;
+
 import org.apache.pivot.collections.ArrayList;
-import org.apache.pivot.collections.List;
 import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.json.JSONSerializer;
+import org.apache.pivot.serialization.SerializationException;
+import org.apache.pivot.util.ImmutableIterator;
 import org.apache.pivot.util.ListenerList;
 import org.apache.pivot.util.Resources;
 
-
 /**
- * Class representing an "alert", a dialog commonly used to perform simple
+ * Class representing an "alert", a dialog commonly used to facilitate simple
  * user interaction.
  */
 public class Alert extends Dialog {
+    /**
+     * Option sequence implementation.
+     */
+    public final class OptionSequence implements Sequence<Object>, Iterable<Object> {
+        private OptionSequence() {
+        }
+
+        @Override
+        public int add(Object option) {
+            int i = getLength();
+            insert(option, i);
+
+            return i;
+        }
+
+        @Override
+        public void insert(Object option, int index) {
+            if (option == null) {
+                throw new IllegalArgumentException("option is null.");
+            }
+
+            options.insert(option, index);
+
+            if (selectedOption >= index) {
+                selectedOption++;
+            }
+
+            alertListeners.optionInserted(Alert.this, index);
+        }
+
+        @Override
+        public Component update(int index, Object option) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int remove(Object option) {
+            int index = indexOf(option);
+            if (index != -1) {
+                remove(index, 1);
+            }
+
+            return index;
+        }
+
+        @Override
+        public Sequence<Object> remove(int index, int count) {
+            Sequence<Object> removed = options.remove(index, count);
+
+            if (removed.getLength() > 0) {
+                if (selectedOption >= index) {
+                    if (selectedOption < index + count) {
+                        selectedOption = -1;
+                    } else {
+                        selectedOption -= count;
+                    }
+                }
+
+                alertListeners.optionsRemoved(Alert.this, index, removed);
+            }
+
+            return removed;
+        }
+
+        @Override
+        public Object get(int index) {
+            return options.get(index);
+        }
+
+        @Override
+        public int indexOf(Object option) {
+            return options.indexOf(option);
+        }
+
+        @Override
+        public int getLength() {
+            return options.getLength();
+        }
+
+        @Override
+        public Iterator<Object> iterator() {
+            return new ImmutableIterator<Object>(options.iterator());
+        }
+    }
+
     private static class AlertListenerList extends ListenerList<AlertListener>
         implements AlertListener {
         @Override
+        public void messageTypeChanged(Alert alert, MessageType previousMessageType) {
+            for (AlertListener listener : this) {
+                listener.messageTypeChanged(alert, previousMessageType);
+            }
+        }
+
+        @Override
+        public void messageChanged(Alert alert, String previousMessage) {
+            for (AlertListener listener : this) {
+                listener.messageChanged(alert, previousMessage);
+            }
+        }
+
+        @Override
+        public void bodyChanged(Alert alert, Component previousBody) {
+            for (AlertListener listener : this) {
+                listener.bodyChanged(alert, previousBody);
+            }
+        }
+
+        @Override
+        public void optionInserted(Alert alert, int index) {
+            for (AlertListener listener : this) {
+                listener.optionInserted(alert, index);
+            }
+        }
+
+        @Override
+        public void optionsRemoved(Alert alert, int index, Sequence<?> removed) {
+            for (AlertListener listener : this) {
+                listener.optionsRemoved(alert, index, removed);
+            }
+        }
+
+        @Override
         public void selectedOptionChanged(Alert alert, int previousSelectedOption) {
             for (AlertListener listener : this) {
                 listener.selectedOptionChanged(alert, previousSelectedOption);
@@ -38,10 +161,12 @@ public class Alert extends Dialog {
         }
     }
 
-    private MessageType type = null;
+    private MessageType messageType = null;
     private String message = null;
     private Component body = null;
-    private ArrayList<Object> options = null;
+
+    private ArrayList<Object> options = new ArrayList<Object>();
+    private OptionSequence optionSequence = new OptionSequence();
     private int selectedOption = -1;
 
     private AlertListenerList alertListeners = new AlertListenerList();
@@ -56,6 +181,10 @@ public class Alert extends Dialog {
         }
     }
 
+    public Alert() {
+        this(null, null, null);
+    }
+
     public Alert(MessageType type, String message, Sequence<?> options) {
         this(type, message, options, true);
     }
@@ -68,46 +197,88 @@ public class Alert extends Dialog {
         this(type, message, options, body, true);
     }
 
-    @SuppressWarnings("unchecked")
-    public Alert(MessageType type, String message, Sequence<?> options, Component body, boolean modal) {
+    public Alert(MessageType messageType, String message, Sequence<?> options, Component body, boolean modal) {
         super(modal);
 
-        if (type == null) {
-            throw new IllegalArgumentException("type is null.");
+        if (messageType == null) {
+            messageType = MessageType.INFO;
         }
 
         if (options == null) {
-            throw new IllegalArgumentException("options is null.");
+            options = new ArrayList<Object>(resources.get("defaultOption"));
         }
 
-        this.type = type;
-        this.message = message;
-        this.options = new ArrayList<Object>((Sequence<Object>)options);
-        this.body = body;
+        setMessageType(messageType);
+        setMessage(message);
+        setBody(body);
+        setOptions(options);
+
+        setTitle((String)resources.get("defaultTitle"));
+        setSelectedOption(0);
 
         installThemeSkin(Alert.class);
     }
 
     public MessageType getMessageType() {
-        return type;
+        return messageType;
     }
 
-    public String getMessage() {
-        return message;
+    public void setMessageType(MessageType messageType) {
+        if (messageType == null) {
+            throw new IllegalArgumentException();
+        }
+
+        MessageType previousMessageType = this.messageType;
+        if (previousMessageType != messageType) {
+            this.messageType = messageType;
+            alertListeners.messageTypeChanged(this, previousMessageType);
+        }
     }
 
-    public Object getOption(int index) {
-        return options.get(index);
+    public String getMessage() {
+        return message;
     }
 
-    public int getOptionCount() {
-        return options.getLength();
+    public void setMessage(String message) {
+        String previousMessage = this.message;
+        if (previousMessage != message) {
+            this.message = message;
+            alertListeners.messageChanged(this, previousMessage);
+        }
     }
 
     public Component getBody() {
         return body;
     }
 
+    public void setBody(Component body) {
+        Component previousBody = this.body;
+        if (previousBody != body) {
+            this.body = body;
+            alertListeners.bodyChanged(this, previousBody);
+        }
+    }
+
+    public OptionSequence getOptions() {
+        return optionSequence;
+    }
+
+    public void setOptions(Sequence<?> options) {
+        optionSequence.remove(0, optionSequence.getLength());
+
+        for (int i = 0, n = options.getLength(); i < n; i++) {
+            optionSequence.add(options.get(i));
+        }
+    }
+
+    public void setOptions(String options) {
+        try {
+            setOptions(JSONSerializer.parseList(options));
+        } catch (SerializationException exception) {
+            throw new IllegalArgumentException(exception);
+        }
+    }
+
     public int getSelectedOption() {
         return selectedOption;
     }
@@ -144,7 +315,7 @@ public class Alert extends Dialog {
 
     public static void alert(MessageType messageType, String message, Component body, Display display,
         DialogCloseListener dialogCloseListener) {
-        Alert alert = createAlert(messageType, message, body);
+        Alert alert = new Alert(messageType, message, null, body);
         alert.setModal(false);
         alert.open(display, dialogCloseListener);
     }
@@ -168,19 +339,7 @@ public class Alert extends Dialog {
 
     public static void alert(MessageType messageType, String message, Component body, Window owner,
         DialogCloseListener dialogCloseListener) {
-        Alert alert = createAlert(messageType, message, body);
-        alert.setModal(true);
+        Alert alert = new Alert(messageType, message, null, body);
         alert.open(owner.getDisplay(), owner, dialogCloseListener);
     }
-
-    private static Alert createAlert(MessageType messageType, String message, Component body) {
-        List<Object> options = new ArrayList<Object>();
-        options.add(resources.get("defaultOption"));
-
-        Alert alert = new Alert(messageType, message, options, body);
-        alert.setTitle((String)resources.get("defaultTitle"));
-        alert.setSelectedOption(0);
-
-        return alert;
-    }
 }

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/AlertListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/AlertListener.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/AlertListener.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/AlertListener.java Fri Apr 23 13:09:26 2010
@@ -16,11 +16,83 @@
  */
 package org.apache.pivot.wtk;
 
+import org.apache.pivot.collections.Sequence;
+
 /**
  * Alert listener interface.
  */
 public interface AlertListener {
     /**
+     * Alert listener adapter.
+     */
+    public static class Adapter implements AlertListener {
+        @Override
+        public void messageTypeChanged(Alert alert, MessageType previousMessageType) {
+        }
+
+        @Override
+        public void messageChanged(Alert alert, String previousMessage) {
+        }
+
+        @Override
+        public void bodyChanged(Alert alert, Component previousBody) {
+        }
+
+        @Override
+        public void optionInserted(Alert alert, int index) {
+        }
+
+        @Override
+        public void optionsRemoved(Alert alert, int index, Sequence<?> removed) {
+        }
+
+        @Override
+        public void selectedOptionChanged(Alert alert, int previousSelectedOption) {
+        }
+    }
+
+    /**
+     * Called when an alert's message type has changed.
+     *
+     * @param alert
+     * @param previousMessageType
+     */
+    public void messageTypeChanged(Alert alert, MessageType previousMessageType);
+
+    /**
+     * Called when an alert's message has changed.
+     *
+     * @param alert
+     * @param previousMessage
+     */
+    public void messageChanged(Alert alert, String previousMessage);
+
+    /**
+     * Called when an alert's body has changed.
+     *
+     * @param alert
+     * @param previousBody
+     */
+    public void bodyChanged(Alert alert, Component previousBody);
+
+    /**
+     * Called when an option has been inserted into an alert's option sequence.
+     *
+     * @param alert
+     * @param index
+     */
+    public void optionInserted(Alert alert, int index);
+
+    /**
+     * Called when options have been removed from an alert's option sequence.
+     *
+     * @param alert
+     * @param index
+     * @param removed
+     */
+    public void optionsRemoved(Alert alert, int index, Sequence<?> removed);
+
+    /**
      * Called when an alert's selected option has changed.
      *
      * @param alert

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/Dialog.java Fri Apr 23 13:09:26 2010
@@ -62,7 +62,7 @@ public class Dialog extends Frame {
         }
     }
 
-    private boolean modal = false;
+    private boolean modal;
     private DialogCloseListener dialogCloseListener = null;
 
     private boolean result = false;

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/Prompt.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/Prompt.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/Prompt.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/Prompt.java Fri Apr 23 13:09:26 2010
@@ -16,26 +16,144 @@
  */
 package org.apache.pivot.wtk;
 
+import java.util.Iterator;
+
 import org.apache.pivot.collections.ArrayList;
-import org.apache.pivot.collections.List;
 import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.json.JSONSerializer;
+import org.apache.pivot.serialization.SerializationException;
+import org.apache.pivot.util.ImmutableIterator;
 import org.apache.pivot.util.ListenerList;
 import org.apache.pivot.util.Resources;
 
-
 /**
- * Class representing an "prompt", a sheet commonly used to perform simple
+ * Class representing a "prompt", a sheet commonly used to facilitate 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.
  */
 public class Prompt extends Sheet {
+    /**
+     * Option sequence implementation.
+     */
+    public final class OptionSequence implements Sequence<Object>, Iterable<Object> {
+        private OptionSequence() {
+        }
+
+        @Override
+        public int add(Object option) {
+            int i = getLength();
+            insert(option, i);
+
+            return i;
+        }
+
+        @Override
+        public void insert(Object option, int index) {
+            if (option == null) {
+                throw new IllegalArgumentException("option is null.");
+            }
+
+            options.insert(option, index);
+
+            if (selectedOption >= index) {
+                selectedOption++;
+            }
+
+            promptListeners.optionInserted(Prompt.this, index);
+        }
+
+        @Override
+        public Component update(int index, Object option) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int remove(Object option) {
+            int index = indexOf(option);
+            if (index != -1) {
+                remove(index, 1);
+            }
+
+            return index;
+        }
+
+        @Override
+        public Sequence<Object> remove(int index, int count) {
+            Sequence<Object> removed = options.remove(index, count);
+
+            if (removed.getLength() > 0) {
+                if (selectedOption >= index) {
+                    if (selectedOption < index + count) {
+                        selectedOption = -1;
+                    } else {
+                        selectedOption -= count;
+                    }
+                }
+
+                promptListeners.optionsRemoved(Prompt.this, index, removed);
+            }
+
+            return removed;
+        }
+
+        @Override
+        public Object get(int index) {
+            return options.get(index);
+        }
+
+        @Override
+        public int indexOf(Object option) {
+            return options.indexOf(option);
+        }
+
+        @Override
+        public int getLength() {
+            return options.getLength();
+        }
+
+        @Override
+        public Iterator<Object> iterator() {
+            return new ImmutableIterator<Object>(options.iterator());
+        }
+    }
+
     private static class PromptListenerList extends ListenerList<PromptListener>
         implements PromptListener {
         @Override
+        public void messageTypeChanged(Prompt prompt, MessageType previousMessageType) {
+            for (PromptListener listener : this) {
+                listener.messageTypeChanged(prompt, previousMessageType);
+            }
+        }
+
+        @Override
+        public void messageChanged(Prompt prompt, String previousMessage) {
+            for (PromptListener listener : this) {
+                listener.messageChanged(prompt, previousMessage);
+            }
+        }
+
+        @Override
+        public void bodyChanged(Prompt prompt, Component previousBody) {
+            for (PromptListener listener : this) {
+                listener.bodyChanged(prompt, previousBody);
+            }
+        }
+
+        @Override
+        public void optionInserted(Prompt prompt, int index) {
+            for (PromptListener listener : this) {
+                listener.optionInserted(prompt, index);
+            }
+        }
+
+        @Override
+        public void optionsRemoved(Prompt prompt, int index, Sequence<?> removed) {
+            for (PromptListener listener : this) {
+                listener.optionsRemoved(prompt, index, removed);
+            }
+        }
+
+        @Override
         public void selectedOptionChanged(Prompt prompt, int previousSelectedOption) {
             for (PromptListener listener : this) {
                 listener.selectedOptionChanged(prompt, previousSelectedOption);
@@ -43,10 +161,12 @@ public class Prompt extends Sheet {
         }
     }
 
-    private MessageType type = null;
+    private MessageType messageType = null;
     private String message = null;
     private Component body = null;
-    private ArrayList<Object> options = null;
+
+    private ArrayList<Object> options = new ArrayList<Object>();
+    private OptionSequence optionSequence = new OptionSequence();
     private int selectedOption = -1;
 
     private PromptListenerList promptListeners = new PromptListenerList();
@@ -61,55 +181,101 @@ public class Prompt extends Sheet {
         }
     }
 
+    public Prompt() {
+        this(null, null, null);
+    }
+
     public Prompt(MessageType type, String message, Sequence<?> options) {
         this(type, message, options, null);
     }
 
-    @SuppressWarnings("unchecked")
     public Prompt(MessageType type, String message, Sequence<?> options, Component body) {
-        if (type == null) {
-            throw new IllegalArgumentException("type is null.");
+        if (messageType == null) {
+            messageType = MessageType.INFO;
         }
 
         if (options == null) {
-            throw new IllegalArgumentException("options is null.");
+            options = new ArrayList<Object>(resources.get("defaultOption"));
         }
 
-        this.type = type;
-        this.message = message;
-        this.options = new ArrayList<Object>((Sequence<Object>)options);
-        this.body = body;
+        setMessageType(messageType);
+        setMessage(message);
+        setBody(body);
+        setOptions(options);
+
+        setTitle((String)resources.get("defaultTitle"));
+        setSelectedOption(0);
 
         installThemeSkin(Prompt.class);
     }
 
     public MessageType getMessageType() {
-        return type;
+        return messageType;
     }
 
-    public String getMessage() {
-        return message;
+    public void setMessageType(MessageType messageType) {
+        if (messageType == null) {
+            throw new IllegalArgumentException();
+        }
+
+        MessageType previousMessageType = this.messageType;
+        if (previousMessageType != messageType) {
+            this.messageType = messageType;
+            promptListeners.messageTypeChanged(this, previousMessageType);
+        }
     }
 
-    public Object getOption(int index) {
-        return options.get(index);
+    public String getMessage() {
+        return message;
     }
 
-    public int getOptionCount() {
-        return options.getLength();
+    public void setMessage(String message) {
+        String previousMessage = this.message;
+        if (previousMessage != message) {
+            this.message = message;
+            promptListeners.messageChanged(this, previousMessage);
+        }
     }
 
     public Component getBody() {
         return body;
     }
 
+    public void setBody(Component body) {
+        Component previousBody = this.body;
+        if (previousBody != body) {
+            this.body = body;
+            promptListeners.bodyChanged(this, previousBody);
+        }
+    }
+
+    public OptionSequence getOptions() {
+        return optionSequence;
+    }
+
+    public void setOptions(Sequence<?> options) {
+        optionSequence.remove(0, optionSequence.getLength());
+
+        for (int i = 0, n = options.getLength(); i < n; i++) {
+            optionSequence.add(options.get(i));
+        }
+    }
+
+    public void setOptions(String options) {
+        try {
+            setOptions(JSONSerializer.parseList(options));
+        } catch (SerializationException exception) {
+            throw new IllegalArgumentException(exception);
+        }
+    }
+
     public int getSelectedOption() {
         return selectedOption;
     }
 
     public void setSelectedOption(int selectedOption) {
         if (selectedOption < -1
-            || selectedOption >= options.getLength()) {
+            || selectedOption > options.getLength() - 1) {
             throw new IndexOutOfBoundsException();
         }
 
@@ -144,18 +310,7 @@ public class Prompt extends Sheet {
 
     public static void prompt(MessageType messageType, String message, Component body, Window owner,
         SheetCloseListener sheetCloseListener) {
-        Prompt prompt = createPrompt(messageType, message, body);
+        Prompt prompt = new Prompt(messageType, message, null, body);
         prompt.open(owner, sheetCloseListener);
     }
-
-    private static Prompt createPrompt(MessageType messageType, String message, Component body) {
-        List<Object> options = new ArrayList<Object>();
-        options.add(resources.get("defaultOption"));
-
-        Prompt prompt = new Prompt(messageType, message, options, body);
-        prompt.setTitle((String)resources.get("defaultTitle"));
-        prompt.setSelectedOption(0);
-
-        return prompt;
-    }
 }

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/PromptListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/PromptListener.java?rev=937280&r1=937279&r2=937280&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/PromptListener.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/PromptListener.java Fri Apr 23 13:09:26 2010
@@ -16,12 +16,84 @@
  */
 package org.apache.pivot.wtk;
 
+import org.apache.pivot.collections.Sequence;
+
 /**
  * Prompt listener interface.
  */
 public interface PromptListener {
     /**
-     * Called when an prompt's selected option has changed.
+     * Prompt listener adapter.
+     */
+    public static class Adapter implements PromptListener {
+        @Override
+        public void messageTypeChanged(Prompt prompt, MessageType previousMessageType) {
+        }
+
+        @Override
+        public void messageChanged(Prompt prompt, String previousMessage) {
+        }
+
+        @Override
+        public void bodyChanged(Prompt prompt, Component previousBody) {
+        }
+
+        @Override
+        public void optionInserted(Prompt prompt, int index) {
+        }
+
+        @Override
+        public void optionsRemoved(Prompt prompt, int index, Sequence<?> removed) {
+        }
+
+        @Override
+        public void selectedOptionChanged(Prompt prompt, int previousSelectedOption) {
+        }
+    }
+
+    /**
+     * Called when a prompt's message type has changed.
+     *
+     * @param prompt
+     * @param previousMessageType
+     */
+    public void messageTypeChanged(Prompt prompt, MessageType previousMessageType);
+
+    /**
+     * Called when a prompt's message has changed.
+     *
+     * @param prompt
+     * @param previousMessage
+     */
+    public void messageChanged(Prompt prompt, String previousMessage);
+
+    /**
+     * Called when a prompt's body has changed.
+     *
+     * @param prompt
+     * @param previousBody
+     */
+    public void bodyChanged(Prompt prompt, Component previousBody);
+
+    /**
+     * Called when an option has been inserted into a prompt's option sequence.
+     *
+     * @param prompt
+     * @param index
+     */
+    public void optionInserted(Prompt prompt, int index);
+
+    /**
+     * Called when options have been removed from a prompt's option sequence.
+     *
+     * @param prompt
+     * @param index
+     * @param removed
+     */
+    public void optionsRemoved(Prompt prompt, int index, Sequence<?> removed);
+
+    /**
+     * Called when a prompt's selected option has changed.
      *
      * @param prompt
      * @param previousSelectedOption