001    /*
002     * Copyright 2006 Google Inc.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package com.google.gwt.user.client.ui;
017    
018    import com.google.gwt.user.client.DOM;
019    import com.google.gwt.user.client.Element;
020    import com.google.gwt.user.client.Event;
021    import com.google.gwt.user.client.ui.impl.FocusImpl;
022    
023    /**
024     * Abstract base class for most widgets that can receive keyboard focus.
025     */
026    public abstract class FocusWidget extends Widget implements SourcesClickEvents,
027        SourcesFocusEvents, HasFocus {
028    
029      // This FocusImpl instance is intentionally _not_ rebound, as the base
030      // implementation works on all browsers for truly focusable widgets.  The
031      // special cases are only needed for things that aren't naturally focusable
032      // on some browsers, such as DIVs.
033      private static FocusImpl impl = new FocusImpl();
034    
035      private ClickListenerCollection clickListeners;
036      private FocusListenerCollection focusListeners;
037      private KeyboardListenerCollection keyboardListeners;
038    
039      /**
040       * Creates a new focus component that wraps the specified browser element.
041       * 
042       * @param handle a handle to the element to be wrapped
043       */
044      protected FocusWidget(Element elem) {
045        setElement(elem);
046        sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS);
047      }
048    
049      public void addClickListener(ClickListener listener) {
050        if (clickListeners == null)
051          clickListeners = new ClickListenerCollection();
052        clickListeners.add(listener);
053      }
054    
055      public void addFocusListener(FocusListener listener) {
056        if (focusListeners == null)
057          focusListeners = new FocusListenerCollection();
058        focusListeners.add(listener);
059      }
060    
061      public void addKeyboardListener(KeyboardListener listener) {
062        if (keyboardListeners == null)
063          keyboardListeners = new KeyboardListenerCollection();
064        keyboardListeners.add(listener);
065      }
066    
067      public int getTabIndex() {
068        return impl.getTabIndex(getElement());
069      }
070    
071      /**
072       * Gets whether this widget is enabled.
073       * 
074       * @return <code>true</code> if the widget is enabled
075       */
076      public boolean isEnabled() {
077        return !DOM.getAttribute(getElement(), "disabled").equals("true");
078      }
079    
080      public void onBrowserEvent(Event event) {
081        switch (DOM.eventGetType(event)) {
082          case Event.ONCLICK:
083            if (clickListeners != null)
084              clickListeners.fireClick(this);
085            break;
086    
087          case Event.ONBLUR:
088          case Event.ONFOCUS:
089            if (focusListeners != null)
090              focusListeners.fireFocusEvent(this, event);
091            break;
092    
093          case Event.ONKEYDOWN:
094          case Event.ONKEYUP:
095          case Event.ONKEYPRESS:
096            if (keyboardListeners != null)
097              keyboardListeners.fireKeyboardEvent(this, event);
098            break;
099        }
100      }
101    
102      public void removeClickListener(ClickListener listener) {
103        if (clickListeners != null)
104          clickListeners.remove(listener);
105      }
106    
107      public void removeFocusListener(FocusListener listener) {
108        if (focusListeners != null)
109          focusListeners.remove(listener);
110      }
111    
112      public void removeKeyboardListener(KeyboardListener listener) {
113        if (keyboardListeners != null)
114          keyboardListeners.remove(listener);
115      }
116    
117      public void setAccessKey(char key) {
118        DOM.setAttribute(getElement(), "accessKey", "" + key);
119      }
120    
121      /**
122       * Sets whether this widget is enabled.
123       * 
124       * @param enabled <code>true</code> to enable the widget, <code>false</code>
125       *          to disable it
126       */
127      public void setEnabled(boolean enabled) {
128        DOM.setAttribute(getElement(), "disabled", enabled ? "" : "true");
129      }
130    
131      public void setFocus(boolean focused) {
132        if (focused)
133          impl.focus(getElement());
134        else
135          impl.blur(getElement());
136      }
137    
138      public void setTabIndex(int index) {
139        impl.setTabIndex(getElement(), index);
140      }
141    }