Fixed issue 3248 by adding Focusable interface
Review by:jlabanca

git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4413 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/Focusable.java b/user/src/com/google/gwt/user/client/ui/Focusable.java
new file mode 100644
index 0000000..a7828eb
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/Focusable.java
@@ -0,0 +1,55 @@
+/*

+ * Copyright 2008 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;

+

+/**

+ * A widget that implements this interface can receive keyboard focus.

+ */

+public interface Focusable {

+

+  /**

+   * Gets the widget's position in the tab index.

+   * 

+   * @return the widget's tab index

+   */

+  int getTabIndex();

+

+  /**

+   * Sets the widget's 'access key'. This key is used (in conjunction with a

+   * browser-specific modifier key) to automatically focus the widget.

+   * 

+   * @param key the widget's access key

+   */

+  void setAccessKey(char key);

+

+  /**

+   * Explicitly focus/unfocus this widget. Only one widget can have focus at a

+   * time, and the widget that does will receive all keyboard events.

+   * 

+   * @param focused whether this widget should take focus or release it

+   */

+  void setFocus(boolean focused);

+

+  /**

+   * Sets the widget's position in the tab index. If more than one widget has

+   * the same tab index, each such widget will receive focus in an arbitrary

+   * order. Setting the tab index to <code>-1</code> will cause this widget to

+   * be removed from the tab order.

+   * 

+   * @param index the widget's tab index

+   */

+  void setTabIndex(int index);

+}

diff --git a/user/src/com/google/gwt/user/client/ui/HasFocus.java b/user/src/com/google/gwt/user/client/ui/HasFocus.java
index c869bd4..e0e999e 100644
--- a/user/src/com/google/gwt/user/client/ui/HasFocus.java
+++ b/user/src/com/google/gwt/user/client/ui/HasFocus.java
@@ -17,40 +17,11 @@
 
 /**
  * A widget that implements this interface can receive keyboard focus.
+ * 
+ * @deprecated use {@link Focusable} instead
  */
-@SuppressWarnings("deprecation")
-public interface HasFocus extends SourcesFocusEvents, SourcesKeyboardEvents {
+@Deprecated
+public interface HasFocus extends Focusable, SourcesFocusEvents,
+    SourcesKeyboardEvents {
 
-  /**
-   * Gets the widget's position in the tab index.
-   * 
-   * @return the widget's tab index
-   */
-  int getTabIndex();
-
-  /**
-   * Sets the widget's 'access key'. This key is used (in conjunction with a
-   * browser-specific modifier key) to automatically focus the widget.
-   * 
-   * @param key the widget's access key
-   */
-  void setAccessKey(char key);
-
-  /**
-   * Explicitly focus/unfocus this widget. Only one widget can have focus at a
-   * time, and the widget that does will receive all keyboard events.
-   * 
-   * @param focused whether this widget should take focus or release it
-   */
-  void setFocus(boolean focused);
-
-  /**
-   * Sets the widget's position in the tab index. If more than one widget has
-   * the same tab index, each such widget will receive focus in an arbitrary
-   * order. Setting the tab index to <code>-1</code> will cause this widget to
-   * be removed from the tab order.
-   * 
-   * @param index the widget's tab index
-   */
-  void setTabIndex(int index);
 }
diff --git a/user/src/com/google/gwt/user/client/ui/Tree.java b/user/src/com/google/gwt/user/client/ui/Tree.java
index 3f794ba..f27b247 100644
--- a/user/src/com/google/gwt/user/client/ui/Tree.java
+++ b/user/src/com/google/gwt/user/client/ui/Tree.java
@@ -72,11 +72,14 @@
  * <img class='gallery' src='Tree.png'/>
  * </p>
  * <h3>CSS Style Rules</h3>
- * <ul class='css'>
- * <li>.gwt-Tree { the tree itself }</li>
- * <li>.gwt-Tree .gwt-TreeItem { a tree item }</li>
- * <li>.gwt-Tree .gwt-TreeItem-selected { a selected tree item }</li>
- * </ul>
+ * <dl>
+ * <dt>.gwt-Tree</dt>
+ * <dd>the tree itself</dd>
+ * <dt>.gwt-Tree .gwt-TreeItem</dt>
+ * <dd>a tree item</dd>
+ * <dt>.gwt-Tree .gwt-TreeItem-selected</dt>
+ * <dd>a selected tree item</dd>
+ * </dl>
  * <p>
  * <h3>Example</h3>
  * {@example com.google.gwt.examples.TreeExample}
@@ -353,7 +356,7 @@
   }
 
   public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
-    return addHandler(handler,MouseDownEvent.getType());
+    return addHandler(handler, MouseDownEvent.getType());
   }
 
   @Deprecated
@@ -362,23 +365,23 @@
   }
 
   public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
-    return addDomHandler(handler,MouseMoveEvent.getType());
+    return addDomHandler(handler, MouseMoveEvent.getType());
   }
 
   public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
-    return addDomHandler(handler,MouseOutEvent.getType());
+    return addDomHandler(handler, MouseOutEvent.getType());
   }
 
   public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
-    return addDomHandler(handler,MouseOverEvent.getType());
+    return addDomHandler(handler, MouseOverEvent.getType());
   }
 
   public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
-    return addDomHandler(handler,MouseUpEvent.getType());
+    return addDomHandler(handler, MouseUpEvent.getType());
   }
 
   public HandlerRegistration addMouseWheelHandler(MouseWheelHandler handler) {
-    return addDomHandler(handler,MouseWheelEvent.getType());
+    return addDomHandler(handler, MouseWheelEvent.getType());
   }
 
   public final HandlerRegistration addOpenHandler(OpenHandler<TreeItem> handler) {
@@ -1039,7 +1042,7 @@
    * Move the tree focus to the specified selected item.
    */
   private void moveFocus() {
-    HasFocus focusableWidget = curSelection.getFocusableWidget();
+    Focusable focusableWidget = curSelection.getFocusable();
     if (focusableWidget != null) {
       focusableWidget.setFocus(true);
       DOM.scrollIntoView(((Widget) focusableWidget).getElement());
diff --git a/user/src/com/google/gwt/user/client/ui/TreeItem.java b/user/src/com/google/gwt/user/client/ui/TreeItem.java
index c3c808f..38c5756 100644
--- a/user/src/com/google/gwt/user/client/ui/TreeItem.java
+++ b/user/src/com/google/gwt/user/client/ui/TreeItem.java
@@ -619,11 +619,35 @@
   }
 
   /**
+   * Returns a suggested {@link Focusable} instance to use when this tree item
+   * is selected. The tree maintains focus if this method returns null. By
+   * default, if the tree item contains a focusable widget, that widget is
+   * returned.
+   * 
+   * Note, the {@link Tree} will ignore this value if the user clicked on an
+   * input element such as a button or text area when selecting this item.
+   * 
+   * @return the focusable item
+   */
+  protected Focusable getFocusable() {
+    Focusable focus = getFocusableWidget();
+    if (focus == null) {
+      Widget w = getWidget();
+      if (w instanceof Focusable) {
+        focus = (Focusable) w;
+      }
+    }
+    return focus;
+  }
+
+  /**
    * Returns the widget, if any, that should be focused on if this TreeItem is
    * selected.
    * 
+   * @deprecated use {@link #getFocusable()} instead
    * @return widget to be focused.
    */
+  @Deprecated
   protected HasFocus getFocusableWidget() {
     Widget w = getWidget();
     if (w instanceof HasFocus) {