Adds a PopupPanel.isShowing() method, implements PopupPanel.isVisible() to match PopupPanel.setVisible(), and fully defines the difference between setVisible()/show()/hide().  This patch also removes the ChangeHandler from TextBoxBase in favor of the ValueChangeHandler.

Patch by: jlabanca
Review by: ecc (desk)
Issue: 1665, 3233



git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4412 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForEventsFiring.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForEventsFiring.java
index c3720de..07efe27 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForEventsFiring.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForEventsFiring.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google 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
@@ -29,6 +29,7 @@
 import com.google.gwt.event.dom.client.ErrorHandler;
 import com.google.gwt.event.dom.client.FocusEvent;
 import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.HasChangeHandlers;
 import com.google.gwt.event.dom.client.HasContextMenuHandlers;
 import com.google.gwt.event.dom.client.HasDoubleClickHandlers;
 import com.google.gwt.event.dom.client.HasMouseWheelHandlers;
@@ -101,6 +102,13 @@
     }
   }
 
+  private static class CustomTextBox extends TextBox implements
+      HasChangeHandlers {
+    public HandlerRegistration addChangeHandler(ChangeHandler handler) {
+      return addDomHandler(handler, ChangeEvent.getType());
+    }
+  }
+
   private static final int WINDOW_EVENT_SCROLL = -1;
   private static final int WINDOW_EVENT_RESIZE = -2;
   private static final int WINDOW_EVENT_CLOSING = -3;
@@ -225,7 +233,7 @@
 
   private void prepKeyboardEvents() {
     // Setup a text box to trigger the events
-    TextBox textBox = new TextBox();
+    CustomTextBox textBox = new CustomTextBox();
 
     // Setup the tests
     textBox.setText("Type a letter");
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTextEvents.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTextEvents.java
index 5bff5ec..704f83a 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTextEvents.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTextEvents.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google 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
@@ -49,7 +49,6 @@
     }));
     b.addKeyboardListener(handler);
     handler.addKeyHandlersTo(b);
-    b.addChangeHandler(handler);
     b.addChangeListener(handler);
     b.addFocusHandler(handler);
     b.addBlurHandler(handler);
diff --git a/user/src/com/google/gwt/user/client/ui/CheckBox.java b/user/src/com/google/gwt/user/client/ui/CheckBox.java
index a40700b..e2f96cf 100644
--- a/user/src/com/google/gwt/user/client/ui/CheckBox.java
+++ b/user/src/com/google/gwt/user/client/ui/CheckBox.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google 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
@@ -34,10 +34,12 @@
  * </p>
  * 
  * <h3>CSS Style Rules</h3>
- * <ul class='css'>
- * <li>.gwt-CheckBox { }</li>
- * <li>.gwt-CheckBox-disabled { Applied when Checkbox is disabled }</li>
- * </ul>
+ * <dl>
+ * <dt>.gwt-CheckBox</dt>
+ * <dd>the outer element</dd>
+ * <dt>.gwt-CheckBox-disabled</dt>
+ * <dd>applied when Checkbox is disabled</dd>
+ * </dl>
  * 
  * <p>
  * <h3>Example</h3>
@@ -46,6 +48,7 @@
  */
 public class CheckBox extends ButtonBase implements HasName, HasValue<Boolean> {
   private Element inputElem, labelElem;
+  private boolean valueChangeHandlerInitialized;
 
   /**
    * Creates a check box with no label.
@@ -104,10 +107,11 @@
       ValueChangeHandler<Boolean> handler) {
     // Is this the first value change handler? If so, time to listen to clicks
     // on the checkbox
-    if (!isEventHandled(ValueChangeEvent.getType())) {
+    if (!valueChangeHandlerInitialized) {
+      valueChangeHandlerInitialized = true;
       this.addClickHandler(new ClickHandler() {
         public void onClick(ClickEvent event) {
-          // No need to compare old value and new value--click handler 
+          // No need to compare old value and new value--click handler
           // only fires on real click, and value always toggles
           ValueChangeEvent.fire(CheckBox.this, isChecked());
         }
@@ -166,7 +170,7 @@
 
   /**
    * Checks or unchecks this check box. Does not fire {@link ValueChangeEvent}.
-   * (If you want the event to fire, use {@link #setValue(boolean, boolean)})
+   * (If you want the event to fire, use {@link #setValue(Boolean, boolean)})
    * 
    * @param checked <code>true</code> to check the check box.
    */
@@ -220,7 +224,8 @@
   }
 
   /**
-   * Checks or unchecks the text box. 
+   * Checks or unchecks the text box.
+   * 
    * @param value true to check, false to uncheck. Must not be null.
    * @thows IllegalArgumentException if value is null
    */
@@ -229,12 +234,12 @@
   }
 
   /**
-   * Checks or unchecks the text box, firing {@link ValueChangeEvent}
-   * if appropriate.
-   *
+   * Checks or unchecks the text box, firing {@link ValueChangeEvent} if
+   * appropriate.
+   * 
    * @param value true to check, false to uncheck. Must not be null.
    * @param fireEvents If true, and value has changed, fire a
-   * {@link ValueChangeEvent}
+   *          {@link ValueChangeEvent}
    * @thows IllegalArgumentException if value is null
    */
   public void setValue(Boolean value, boolean fireEvents) {
diff --git a/user/src/com/google/gwt/user/client/ui/PopupPanel.java b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
index 6ed6891..bbf4de4 100644
--- a/user/src/com/google/gwt/user/client/ui/PopupPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
@@ -439,14 +439,16 @@
   }
 
   /**
-   * Hides the popup. This has no effect if it is not currently visible.
+   * Hides the popup and detaches it from the page. This has no effect if it is
+   * not currently showing.
    */
   public void hide() {
     hide(false);
   }
 
   /**
-   * Hides the popup. This has no effect if it is not currently visible.
+   * Hides the popup and detaches it from the page. This has no effect if it is
+   * not currently showing.
    * 
    * @param autoClosed the value that will be passed to
    *          {@link CloseHandler#onClose(CloseEvent)} when the popup is closed
@@ -501,6 +503,31 @@
   }
 
   /**
+   * Determines whether or not this popup is showing.
+   * 
+   * @return <code>true</code> if the popup is showing
+   * @see #show()
+   * @see #hide()
+   */
+  public boolean isShowing() {
+    return showing;
+  }
+
+  /**
+   * Determines whether or not this popup is visible. Note that this just checks
+   * the <code>visibility</code> style attribute, which is set in the
+   * {@link #setVisible(boolean)} method. If you want to know if the popup is
+   * attached to the page, use {@link #isShowing()} instead.
+   * 
+   * @return <code>true</code> if the object is visible
+   * @see #setVisible(boolean)
+   */
+  @Override
+  public boolean isVisible() {
+    return !"hidden".equals(getElement().getStyle().getProperty("visibility"));
+  }
+
+  /**
    * @deprecated use {@link #onPreviewNativeEvent(NativePreviewEvent)} instead
    */
   @Deprecated
@@ -689,10 +716,14 @@
   }
 
   /**
-   * Sets whether this object is visible.
+   * Sets whether this object is visible. This method just sets the
+   * <code>visibility</code> style attribute. You need to call {@link #show()}
+   * to actually attached/detach the {@link PopupPanel} to the page.
    * 
    * @param visible <code>true</code> to show the object, <code>false</code> to
    *          hide it
+   * @see #show()
+   * @see #hide()
    */
   @Override
   public void setVisible(boolean visible) {
@@ -739,7 +770,8 @@
   }
 
   /**
-   * Shows the popup. It must have a child widget before this method is called.
+   * Shows the popup and attach it to the page. It must have a child widget
+   * before this method is called.
    */
   public void show() {
     if (showing) {
diff --git a/user/src/com/google/gwt/user/client/ui/SuggestBox.java b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
index eacf785..3ab2a0e 100644
--- a/user/src/com/google/gwt/user/client/ui/SuggestBox.java
+++ b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
@@ -20,6 +20,7 @@
 import static com.google.gwt.event.dom.client.KeyCodes.KEY_TAB;
 import static com.google.gwt.event.dom.client.KeyCodes.KEY_UP;
 
+import com.google.gwt.event.dom.client.ChangeEvent;
 import com.google.gwt.event.dom.client.HandlesAllKeyEvents;
 import com.google.gwt.event.dom.client.HasAllKeyHandlers;
 import com.google.gwt.event.dom.client.KeyDownEvent;
@@ -46,6 +47,7 @@
 
 import java.util.Collection;
 import java.util.List;
+
 /**
  * A {@link SuggestBox} is a text box or text area which displays a
  * pre-configured set of selections that match the user's input.
@@ -91,31 +93,53 @@
  * <img class='gallery' src='SuggestBox.png'/>
  * </p>
  * 
- * <h3>CSS Style Rules</h3> 
- * <ul class='css'> 
- * <li>.gwt-SuggestBox { the suggest
- * box itself }</li> 
- * <li>.gwt-SuggestBoxPopup { the suggestion popup }</li> 
- * <li>.gwt-SuggestBoxPopup .item { an unselected suggestion }</li> 
- * <li>.gwt-SuggestBoxPopup .item-selected { a selected suggestion }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopLeft { the top left cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopLeftInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopCenter { the top center cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopCenterInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopRight { the top right cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupTopRightInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleLeft { the middle left cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleLeftInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleCenter { the middle center cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleCenterInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleRight { the middle right cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupMiddleRightInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomLeft { the bottom left cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomLeftInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomCenter { the bottom center cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomCenterInner { the inner element of the cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomRight { the bottom right cell }</li> 
- * <li>.gwt-SuggestBoxPopup .suggestPopupBottomRightInner { the inner element of the cell }</li> </ul>
+ * <h3>CSS Style Rules</h3>
+ * <dl>
+ * <dt>.gwt-SuggestBox</dt>
+ * <dd>the suggest box itself</dd>
+ * <dt>.gwt-SuggestBoxPopup</dt>
+ * <dd>the suggestion popup</dd>
+ * <dt>.gwt-SuggestBoxPopup .item</dt>
+ * <dd>an unselected suggestion</dd>
+ * <dt>.gwt-SuggestBoxPopup .item-selected</dt>
+ * <dd>a selected suggestion</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopLeft</dt>
+ * <dd>the top left cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopLeftInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopCenter</dt>
+ * <dd>the top center cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopCenterInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopRight</dt>
+ * <dd>the top right cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupTopRightInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleLeft</dt>
+ * <dd>the middle left cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleLeftInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleCenter</dt>
+ * <dd>the middle center cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleCenterInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleRight</dt>
+ * <dd>the middle right cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupMiddleRightInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomLeft</dt>
+ * <dd>the bottom left cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomLeftInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomCenter</dt>
+ * <dd>the bottom center cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomCenterInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomRight</dt>
+ * <dd>the bottom right cell</dd>
+ * <dt>.gwt-SuggestBoxPopup .suggestPopupBottomRightInner</dt>
+ * <dd>the inner element of the cell</dd>
+ * </dl>
  * 
  * @see SuggestOracle
  * @see MultiWordSuggestOracle
@@ -455,7 +479,7 @@
   public void addChangeListener(final ChangeListener listener) {
     ListenerWrapper.Change legacy = new ListenerWrapper.Change(listener);
     legacy.setSource(this);
-    box.addChangeHandler(legacy);
+    box.addDomHandler(legacy, ChangeEvent.getType());
   }
 
   /**
@@ -533,9 +557,9 @@
   }
 
   /**
-   * Returns whether or not the first suggestion will be automatically
-   * selected. This behavior is off by default.
-   *
+   * Returns whether or not the first suggestion will be automatically selected.
+   * This behavior is off by default.
+   * 
    * @return true if the first suggestion will be automatically selected
    */
   public boolean getSelectsFirstItem() {
@@ -576,6 +600,13 @@
     return suggestionPopup.isAnimationEnabled();
   }
 
+  /**
+   * @return true if the list of suggestions is currently showing, false if not
+   */
+  public boolean isSuggestionListShowing() {
+    return suggestionPopup.isShowing();
+  }
+
   @Deprecated
   public void removeChangeListener(ChangeListener listener) {
     ListenerWrapper.Change.remove(box, listener);
@@ -636,7 +667,7 @@
   /**
    * Turns on or off the behavior that automatically selects the first suggested
    * item. It defaults to off.
-   *
+   * 
    * @param selectsFirstItem Whether or not to automatically select the first
    *          suggested
    */
@@ -676,6 +707,10 @@
     suggestionMenu.setMenuItemDebugIds(baseID);
   }
 
+  void showSuggestions(String query) {
+    oracle.requestSuggestions(new Request(query, limit), callBack);
+  }
+
   private void addEventsToTextBox() {
     class TextBoxEvents extends HandlesAllKeyEvents implements
         ValueChangeHandler<String> {
@@ -715,7 +750,7 @@
       }
 
       public void onValueChange(ValueChangeEvent<String> event) {
-         fireEvent(event);
+        fireEvent(event);
       }
 
       private void refreshSuggestions() {
@@ -806,8 +841,4 @@
       suggestionPopup.hide();
     }
   }
-
-  private void showSuggestions(String query) {
-    oracle.requestSuggestions(new Request(query, limit), callBack);
-  }
 }
diff --git a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
index 62a6d9a..ed5c4ff 100644
--- a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
+++ b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2009 Google 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
@@ -19,7 +19,6 @@
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.event.dom.client.ChangeEvent;
 import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.HasChangeHandlers;
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
 import com.google.gwt.event.shared.HandlerRegistration;
@@ -32,7 +31,7 @@
  */
 @SuppressWarnings("deprecation")
 public class TextBoxBase extends FocusWidget implements SourcesChangeEvents,
-    HasChangeHandlers, HasText, HasName, HasValue<String> {
+    HasText, HasName, HasValue<String> {
 
   /**
    * Text alignment constant, used in
@@ -77,6 +76,7 @@
   private static TextBoxImpl impl = GWT.create(TextBoxImpl.class);
 
   private Event currentEvent;
+  private boolean valueChangeHandlerInitialized;
 
   /**
    * Creates a text box that wraps the given browser element handle. This is
@@ -88,24 +88,21 @@
     super(elem);
   }
 
-  public HandlerRegistration addChangeHandler(ChangeHandler handler) {
-    return addDomHandler(handler, ChangeEvent.getType());
-  }
-
   @Deprecated
   public void addChangeListener(ChangeListener listener) {
-    addChangeHandler(new ListenerWrapper.Change(listener));
+    addDomHandler(new ListenerWrapper.Change(listener), ChangeEvent.getType());
   }
 
   public HandlerRegistration addValueChangeHandler(
       ValueChangeHandler<String> handler) {
     // Initialization code
-    if (!isEventHandled(ValueChangeEvent.getType())) {
-      addChangeHandler(new ChangeHandler() {
+    if (!valueChangeHandlerInitialized) {
+      valueChangeHandlerInitialized = true;
+      addDomHandler(new ChangeHandler() {
         public void onChange(ChangeEvent event) {
-          setValue(getText());
+          ValueChangeEvent.fire(TextBoxBase.this, getText());
         }
-      });
+      }, ChangeEvent.getType());
     }
     return addHandler(handler, ValueChangeEvent.getType());
   }
diff --git a/user/src/com/google/gwt/user/datepicker/client/DateBox.java b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
index 4e5a6a4..1332561 100644
--- a/user/src/com/google/gwt/user/datepicker/client/DateBox.java
+++ b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google 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
@@ -70,9 +70,9 @@
    * If that fails, we then try to parse again using the default browser date
    * parsing.
    * </p>
-   * If that fails, the <code>dateBoxFormatError</code> css style is
-   * applied to the {@link DateBox}. The style will be removed when either a
-   * successful {@link #parse(DateBox,String, boolean)} is called or
+   * If that fails, the <code>dateBoxFormatError</code> css style is applied to
+   * the {@link DateBox}. The style will be removed when either a successful
+   * {@link #parse(DateBox,String, boolean)} is called or
    * {@link #format(DateBox,Date)} is called.
    * <p>
    * Use a different {@link DateBox.Format} instance to change that behavior.
@@ -183,7 +183,7 @@
       CloseHandler<PopupPanel> {
 
     public void onBlur(BlurEvent event) {
-      if (isDatePickerVisible() == false) {
+      if (isDatePickerShowing() == false) {
         updateDateFromTextBox();
       }
     }
@@ -201,7 +201,7 @@
     }
 
     public void onFocus(FocusEvent event) {
-      if (allowDPShow && isDatePickerVisible() == false) {
+      if (allowDPShow && isDatePickerShowing() == false) {
         showDatePicker();
       }
     }
@@ -354,10 +354,10 @@
   }
 
   /**
-   * @return true if date picker is currently visible, false if not
+   * @return true if date picker is currently showing, false if not
    */
-  public boolean isDatePickerVisible() {
-    return popup.isVisible();
+  public boolean isDatePickerShowing() {
+    return popup.isShowing();
   }
 
   /**
diff --git a/user/test/com/google/gwt/user/UISuite.java b/user/test/com/google/gwt/user/UISuite.java
index b9c3d79..363fb65 100644
--- a/user/test/com/google/gwt/user/UISuite.java
+++ b/user/test/com/google/gwt/user/UISuite.java
@@ -66,6 +66,7 @@
 import com.google.gwt.user.client.ui.SimpleRadioButtonTest;
 import com.google.gwt.user.client.ui.SplitPanelTest;
 import com.google.gwt.user.client.ui.StackPanelTest;
+import com.google.gwt.user.client.ui.SuggestBoxTest;
 import com.google.gwt.user.client.ui.TabBarTest;
 import com.google.gwt.user.client.ui.TabPanelTest;
 import com.google.gwt.user.client.ui.TextAreaTest;
@@ -142,6 +143,7 @@
     suite.addTestSuite(SimpleRadioButtonTest.class);
     suite.addTestSuite(SplitPanelTest.class);
     suite.addTestSuite(StackPanelTest.class);
+    suite.addTestSuite(SuggestBoxTest.class);
     suite.addTestSuite(TabBarTest.class);
     suite.addTestSuite(TabPanelTest.class);
     suite.addTestSuite(TextAreaTest.class);
diff --git a/user/test/com/google/gwt/user/client/ui/DateBoxTest.java b/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
index 624359a..f8ee4a7 100644
--- a/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DateBoxTest.java
@@ -22,13 +22,23 @@
  * Tests DateBox.
  */
 public class DateBoxTest extends GWTTestCase {
+  @Override
   public String getModuleName() {
     return "com.google.gwt.user.User";
   }
-  
+
+  public void testAccessors() {
+    DateBox db = new DateBox();
+    assertFalse(db.isDatePickerShowing());
+    db.showDatePicker();
+    assertTrue(db.isDatePickerShowing());
+    db.hideDatePicker();
+    assertFalse(db.isDatePickerShowing());
+  }
+
   public void testValueChangeEvent() {
     DateBox db = new DateBox();
     RootPanel.get().add(db);
-    new DateValueChangeTester(db).run();    
+    new DateValueChangeTester(db).run();
   }
 }
diff --git a/user/test/com/google/gwt/user/client/ui/PopupTest.java b/user/test/com/google/gwt/user/client/ui/PopupTest.java
index 4285ea6..a8611bd 100644
--- a/user/test/com/google/gwt/user/client/ui/PopupTest.java
+++ b/user/test/com/google/gwt/user/client/ui/PopupTest.java
@@ -23,7 +23,7 @@
 import com.google.gwt.user.client.Window;
 
 /**
- * TODO: document me.
+ * Tests for {@link PopupPanel}.
  */
 public class PopupTest extends GWTTestCase {
 
@@ -82,6 +82,20 @@
     assertTrue(popup.isPreviewingAllNativeEvents());
     popup.setPreviewingAllNativeEvents(false);
     assertFalse(popup.isPreviewingAllNativeEvents());
+
+    // setVisible
+    assertTrue(popup.isVisible());
+    popup.setVisible(false);
+    assertFalse(popup.isVisible());
+    popup.setVisible(true);
+    assertTrue(popup.isVisible());
+
+    // isShowing
+    assertFalse(popup.isShowing());
+    popup.show();
+    assertTrue(popup.isShowing());
+    popup.hide();
+    assertFalse(popup.isShowing());
   }
 
   public void testAutoHidePartner() {
diff --git a/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java b/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
new file mode 100644
index 0000000..df82e39
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009 Google 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 com.google.gwt.user.client.ui;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests for {@link SuggestBoxTest}.
+ */
+public class SuggestBoxTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.user.User";
+  }
+
+  /**
+   * Test the basic accessors.
+   */
+  public void testAccessors() {
+    SuggestBox box = createSuggestBox();
+
+    // setLimit
+    box.setLimit(5);
+    assertEquals(5, box.getLimit());
+
+    // setSelectsFirstItem
+    box.setSelectsFirstItem(true);
+    assertTrue(box.getSelectsFirstItem());
+    box.setSelectsFirstItem(false);
+    assertFalse(box.getSelectsFirstItem());
+
+    // isSuggestionListShowing
+    assertFalse(box.isSuggestionListShowing());
+    box.showSuggestions("test");
+    assertTrue(box.isSuggestionListShowing());
+  }
+
+  protected SuggestBox createSuggestBox() {
+    MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
+    oracle.add("test");
+    oracle.add("test1");
+    oracle.add("test2");
+    oracle.add("test3");
+    oracle.add("test4");
+    oracle.add("john");
+    return new SuggestBox(oracle);
+  }
+}