Java/GWT/Image

Материал из Java эксперт
Перейти к: навигация, поиск

Image widget that overcomes PNG browser incompatabilities

package com.jexp.gwt.client;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.core.client.*;
public class GWTClient implements EntryPoint{
  public void onModuleLoad() {
    RootPanel.get().add(new ToggleButton("images/close.png",16,16));
  }
}
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * 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.
 */

class ToggleButton extends ImageButton
{
    private int trueState;

    public ToggleButton (String url, int width, int height)
    {
        super(url, width, height);
    }
    protected void init ()
    {
        addMouseListener(new MouseListenerAdapter(){
            public void onMouseEnter (Widget sender)
            {
                trueState = getState();
                setState(ON_STATE);
                setColors();
            }
            public void onMouseLeave (Widget sender)
            {
                setState(trueState);
                setColors();
            }
        });
    }
    
    public void setOn (boolean on)
    {
        if (on) {
            setState(ON_STATE);
            trueState = ON_STATE;
        }
        else {
            setState(OFF_STATE);
            trueState = OFF_STATE;
        }
        setColors();
    }

    /**
     * Toggle button state
     * @param on
     */
    public void toggle ()
    {
        if (trueState == ON_STATE) {
            trueState = OFF_STATE;
        }
        else {
            trueState = ON_STATE;
        }
        setState(trueState);
        setColors();
    }
}
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * 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.
 */
/**
 * Use an image as a button.  Allows for setting of on/off 
 * background color, border color, border width, and border 
 * style.  The "on" colors are used on mouse over.
 * 
 * @author rhanson
 */
class ImageButton extends PNGImage
{
    protected final static int ON_STATE = 1;
    protected final static int OFF_STATE = -1;
    private int state = OFF_STATE;
    
    private String onStyle = "gwl-ImageButton-On";
    private String offStyle = "gwl-ImageButton-Off";
    private Color backgroundOnColor = Color.NONE;
    private Color backgroundOffColor = Color.NONE;
    private Color borderOnColor = Color.BLACK;
    private Color borderOffColor = Color.NONE;
    
    private int borderOnWidth = 1;
    private int borderOffWidth = 0;
    
    private int paddingLeft = 0;
    private int paddingRight = 0;
    private int paddingTop = 0;
    private int paddingBottom = 0;
    
    private BorderStyleConstant borderOnStyle = BorderStyle.BORDER_STYLE_SOLID;
    private BorderStyleConstant borderOffStyle = BorderStyle.BORDER_STYLE_NONE;

    public ImageButton (String url, int width, int height)
    {
        super(url, width, height);
        setStyleName("gwl-image-button");
        setColors();
        init();
    }
    
    protected void init ()
    {
        addMouseListener(new MouseListenerAdapter(){
            public void onMouseEnter (Widget sender)
            {
                state = ON_STATE;
                setColors();
            }
            public void onMouseLeave (Widget sender)
            {
                state = OFF_STATE;
                setColors();
            }
        });
    }
    
    
    public boolean isOn ()
    {
        return state == ON_STATE;
    }
    
    /**
     * Updates the colors of the widget based on the state
     * and color settings. This is usually only used after 
     * setting one or more of the colors.
     */
    public void setColors ()
    {
        DOM.setStyleAttribute(getElement(), "paddingTop", getPaddingTopWidth() + "px");
        DOM.setStyleAttribute(getElement(), "paddingRight", getPaddingRightWidth() + "px");
        DOM.setStyleAttribute(getElement(), "paddingBottom", getPaddingBottomWidth() + "px");
        DOM.setStyleAttribute(getElement(), "paddingLeft", getPaddingLeftWidth() + "px");
        DOM.setStyleAttribute(getElement(), "borderWidth", getBorderWidth() + "px");
        DOM.setStyleAttribute(getElement(), "borderColor", getBorderColor().getHexValue());
        DOM.setStyleAttribute(getElement(), "borderStyle", getBorderStyle().getBorderStyleName());
        DOM.setStyleAttribute(getElement(), "backgroundColor", getBackgroundColor().getHexValue());
        setStyleName(getCssStyleName());
    }
    private String getCssStyleName ()
    {
        if (state == ON_STATE)
            return onStyle;
        else
            return offStyle;
    }

    private Color getBackgroundColor ()
    {
        if (state == ON_STATE)
            return backgroundOnColor;
        else
            return backgroundOffColor;
    }
    private BorderStyleConstant getBorderStyle ()
    {
        if (state == ON_STATE)
            return borderOnStyle;
        else
            return borderOffStyle;
    }
    private Color getBorderColor ()
    {
        if (state == ON_STATE)
            return borderOnColor;
        else
            return borderOffColor;
    }
    private int getBorderWidth ()
    {
        if (state == ON_STATE)
            return borderOnWidth;
        else
            return borderOffWidth;
    }
    private int getPaddingLeftWidth ()
    {
        int max = (borderOnWidth > borderOffWidth) ? borderOnWidth : borderOffWidth;
        
        if (state == ON_STATE) {
            return (max - borderOnWidth + paddingLeft);
        }
        else {
            return (max - borderOffWidth + paddingLeft);
        }
    }
    private int getPaddingRightWidth ()
    {
        int max = (borderOnWidth > borderOffWidth) ? borderOnWidth : borderOffWidth;
        
        if (state == ON_STATE) {
            return (max - borderOnWidth + paddingRight);
        }
        else {
            return (max - borderOffWidth + paddingRight);
        }
    }
    private int getPaddingTopWidth ()
    {
        int max = (borderOnWidth > borderOffWidth) ? borderOnWidth : borderOffWidth;
        
        if (state == ON_STATE) {
            return (max - borderOnWidth + paddingTop);
        }
        else {
            return (max - borderOffWidth + paddingTop);
        }
    }
    
    private int getPaddingBottomWidth ()
    {
        int max = (borderOnWidth > borderOffWidth) ? borderOnWidth : borderOffWidth;
        
        if (state == ON_STATE) {
            return (max - borderOnWidth + paddingBottom);
        }
        else {
            return (max - borderOffWidth + paddingBottom);
        }
    }
    
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setMargin (int px)
    {
        DOM.setStyleAttribute(getElement(), "margin", px + "px");
    }
    
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setHorizontalMargin (int px)
    {
        DOM.setStyleAttribute(getElement(), "marginLeft", px + "px");
        DOM.setStyleAttribute(getElement(), "marginRight", px + "px");
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setVerticleMargin (int px)
    {
        DOM.setStyleAttribute(getElement(), "marginTop", px + "px");
        DOM.setStyleAttribute(getElement(), "marginBotom", px + "px");
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public Color getBackgroundOffColor ()
    {
        return backgroundOffColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBackgroundOffColor (Color backgroundOffColor)
    {
        this.backgroundOffColor = backgroundOffColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public Color getBackgroundOnColor ()
    {
        return backgroundOnColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBackgroundOnColor (Color backgroundOnColor)
    {
        this.backgroundOnColor = backgroundOnColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public Color getBorderOffColor ()
    {
        return borderOffColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOffColor (Color borderOffColor)
    {
        this.borderOffColor = borderOffColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public BorderStyleConstant getBorderOffStyle ()
    {
        return borderOffStyle;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOffStyle (BorderStyleConstant borderOffStyle)
    {
        this.borderOffStyle = borderOffStyle;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public int getBorderOffWidth ()
    {
        return borderOffWidth;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOffWidth (int borderOffWidth)
    {
        this.borderOffWidth = borderOffWidth;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public Color getBorderOnColor ()
    {
        return borderOnColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOnColor (Color borderOnColor)
    {
        this.borderOnColor = borderOnColor;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public BorderStyleConstant getBorderOnStyle ()
    {
        return borderOnStyle;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOnStyle (BorderStyleConstant borderOnStyle)
    {
        this.borderOnStyle = borderOnStyle;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public int getBorderOnWidth ()
    {
        return borderOnWidth;
    }
    /**
     * This method is under consideration for removal,
     * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
     */
    public void setBorderOnWidth (int borderOnWidth)
    {
        this.borderOnWidth = borderOnWidth;
    }
    protected int getState ()
    {
        return state;
    }
    protected void setState (int state)
    {
        this.state = state;
    }

    public String getOffStyle ()
    {
        return offStyle;
    }

    public void setOffStyle (String offStyle)
    {
        this.offStyle = offStyle;
    }

    public String getOnStyle ()
    {
        return onStyle;
    }

    public void setOnStyle (String onStyle)
    {
        this.onStyle = onStyle;
    }

}
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * 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.
 */

/**
 * Image widget that overcomes PNG browser incompatabilities.
 * Although meant for PNG images, it will work with any image
 * format supported by the browser.  If the image file ends
 * with ".png" or ".PNG" it will use the PNG specific routines,
 * otherwise will use generic non-PNG specific routines.
 * 
 * The URL, width, and height are required at the creation of the
 * widget, and may not be updated via the widget methogs.  Calling
 * setUrl() will throw a RuntimeException.  This is in part due to
 * the workarounds required for IE 5.5 and IE6.
 * 
 * @author rhanson
 */
 class PNGImage extends Image
{
    private PNGImageImpl impl;

    public PNGImage (String url, int width, int height)
    {
        impl = (PNGImageImpl) GWT.create(PNGImageImpl.class);
        
        setElement(impl.createElement(url, width, height));
        sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.ONLOAD | Event.ONERROR);
    }
    
    public String getUrl ()
    {
        return impl.getUrl(this);
    }
   
    /**
     * Should not be used. Throws RuntimeException
     */
    public void setUrl (String url)
    {
        throw new RuntimeException("Not allowed to set url for a PNG image");
    }
}
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * 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.
 */
 class PNGImageImpl
{
    
    public Element createElement (String url, int width, int height)
    {
        Element result = DOM.createImg();
        DOM.setAttribute(result, "src", url);
        DOM.setIntAttribute(result, "width", width);
        DOM.setIntAttribute(result, "height", height);
        return result;
    }
    public String getUrl (PNGImage image)
    {
        return DOM.getAttribute(image.getElement(), "src");
    }
}
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * 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.
 */
class PNGImageImplIE6 extends PNGImageImpl
{
    private String url;
    private boolean isPng;
    
    public Element createElement (String url, int width, int height)
    {
        this.url = url;
    
        if (url.endsWith(".png") || url.endsWith(".PNG")) {
            isPng = true;
        }
        else {
            isPng = false;
        }
        
        if (isPng) {
            Element div = DOM.createDiv();
            DOM.setInnerHTML(div, "<span style=\"display:inline-block;width:" + width + "px;height:" + height + "px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="" + url + "", sizingMethod="scale")\"></span>");
            return DOM.getFirstChild(div);
        }
        else {
            return super.createElement(url, width, height);
        }
    }
    public String getUrl (PNGImage image)
    {
        if (isPng) {
            return url;
        }
        else {
            return super.getUrl(image);
        }
    }
    
}
public class BorderStyleConstant
{
        private String styleName;
        
        public BorderStyleConstant (String styleName)
        {
            this.styleName = styleName;
        }
        public String getBorderStyleName() {
            return styleName;
        }
        
}

 class BorderStyle
{
   
    
    final public static BorderStyleConstant BORDER_STYLE_NONE = new BorderStyleConstant("none");
    final public static BorderStyleConstant BORDER_STYLE_DOTTED = new BorderStyleConstant("dotted");
    final public static BorderStyleConstant BORDER_STYLE_DASHED = new BorderStyleConstant("dashed");
    final public static BorderStyleConstant BORDER_STYLE_SOLID = new BorderStyleConstant("solid");
    final public static BorderStyleConstant BORDER_STYLE_DOUBLE = new BorderStyleConstant("double");
    final public static BorderStyleConstant BORDER_STYLE_GROOVE = new BorderStyleConstant("groove");
    final public static BorderStyleConstant BORDER_STYLE_RIDGE = new BorderStyleConstant("ridge");
    final public static BorderStyleConstant BORDER_STYLE_INSET = new BorderStyleConstant("inset");
    final public static BorderStyleConstant BORDER_STYLE_OUTSET = new BorderStyleConstant("outset");
}
class Color
{
    public final static Color WHITE = new Color(255, 255, 255);
    public final static Color LIGHT_GRAY = new Color(192, 192, 192);
    public final static Color GRAY = new Color(128, 128, 128);
    public final static Color DARK_GRAY = new Color(64, 64, 64);
    public final static Color BLACK = new Color(0, 0, 0);
    public final static Color RED = new Color(255, 0, 0);
    public final static Color PINK = new Color(255, 175, 175);
    public final static Color ORANGE = new Color(255, 200, 0);
    public final static Color YELLOW = new Color(255, 255, 0);
    public final static Color GREEN = new Color(0, 255, 0);
    public final static Color MAGENTA = new Color(255, 0, 255);
    public final static Color CYAN = new Color(0, 255, 255);
    public final static Color BLUE = new Color(0, 0, 255);
    public static final Color NONE = new Color("");
    
    private int r, g, b;
    
    // only for special cases, like no color, or maybe named colors
    private String colorText = null;
    private Color (String colorText) {
        this.colorText = colorText;
    }
    public Color (int r, int g, int b)
    {
        this.r = r;
        this.g = g;
        this.b = b;
    }
    public int getRed ()
    {
        return r;
    }
    public int getGreen ()
    {
        return g;
    }
    public int getBlue ()
    {
        return b;
    }
    public String getHexValue ()
    {
        if (colorText != null) {
            return colorText;
        }
        return "#"
            + pad(Integer.toHexString(r))
            + pad(Integer.toHexString(g))
            + pad(Integer.toHexString(b));
    }
    private String pad (String in)
    {
        if (in.length() == 0) {
            return "00";
        }
        if (in.length() == 1) {
            return "0" + in;
        }
        return in;
    }
    public String toString ()
    {
        if (colorText != null) {
            return colorText;
        }
        return "red=" + r + ", green=" + g + ", blue=" + b;
    }
}





Load image

package com.jexp.gwt.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
public class GWTClient implements EntryPoint {
  public void onModuleLoad() {
    Button b = new Button("Click me", new ClickListener() {
      public void onClick(Widget sender) {
         DialogBox dlg = new MyDialog();
         dlg.center();
      }
    });
    RootPanel.get().add(b);
  }
}
class MyDialog extends DialogBox implements ClickListener {
  public MyDialog() {
    setText("Sample DialogBox");
    Button closeButton = new Button("Close", this);
    HTML msg = new HTML("<center>A standard dialog box component.</center>",true);
    DockPanel dock = new DockPanel();
    dock.setSpacing(4);
    dock.add(closeButton, DockPanel.SOUTH);
    dock.add(msg, DockPanel.NORTH);
    dock.add(new Image("images/yourImage.jpg"), DockPanel.CENTER);
    dock.setCellHorizontalAlignment(closeButton, DockPanel.ALIGN_RIGHT);
    dock.setWidth("100%");
    setWidget(dock);
  }
  public void onClick(Widget sender) {
    hide();
  }
}





Use GWT Resource To Load Images

package com.jexp.gwt.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.DOM;
public class GWTClient implements EntryPoint {
  public void onModuleLoad() {
    RichTextArea area = new RichTextArea();
    RichTextToolbar tb = new RichTextToolbar(area);
    VerticalPanel p = new VerticalPanel();
    p.add(tb);
    p.add(area);
    area.setHeight("14em");
    area.setWidth("100%");
    tb.setWidth("100%");
    p.setWidth("100%");
    DOM.setStyleAttribute(p.getElement(), "margin-right", "4px");
    p.setWidth("32em");
    RootPanel.get().add(p);
  }
}
//////////////////
/*
 * Copyright 2007 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.sample.kitchensink.client;
package com.jexp.gwt.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ruposite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ImageBundle;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
 * A sample toolbar for use with {@link RichTextArea}. It provides a simple UI
 * for all rich text formatting, dynamically displayed only for the available
 * functionality.
 */
public class RichTextToolbar extends Composite {
  /**
   * This {@link ImageBundle} is used for all the button icons. Using an image
   * bundle allows all of these images to be packed into a single image, which
   * saves a lot of HTTP requests, drastically improving startup time.
   */
  public interface Images extends ImageBundle {
    /**
     * @gwt.resource bold.gif
     */
    AbstractImagePrototype bold();
    /**
     * @gwt.resource createLink.gif
     */
    AbstractImagePrototype createLink();
    /**
     * @gwt.resource hr.gif
     */
    AbstractImagePrototype hr();
    /**
     * @gwt.resource indent.gif
     */
    AbstractImagePrototype indent();
    /**
     * @gwt.resource insertImage.gif
     */
    AbstractImagePrototype insertImage();
    /**
     * @gwt.resource italic.gif
     */
    AbstractImagePrototype italic();
    /**
     * @gwt.resource justifyCenter.gif
     */
    AbstractImagePrototype justifyCenter();
    /**
     * @gwt.resource justifyLeft.gif
     */
    AbstractImagePrototype justifyLeft();
    /**
     * @gwt.resource justifyRight.gif
     */
    AbstractImagePrototype justifyRight();
    /**
     * @gwt.resource ol.gif
     */
    AbstractImagePrototype ol();
    /**
     * @gwt.resource outdent.gif
     */
    AbstractImagePrototype outdent();
    /**
     * @gwt.resource removeFormat.gif
     */
    AbstractImagePrototype removeFormat();
    /**
     * @gwt.resource removeLink.gif
     */
    AbstractImagePrototype removeLink();
    /**
     * @gwt.resource strikeThrough.gif
     */
    AbstractImagePrototype strikeThrough();
    /**
     * @gwt.resource subscript.gif
     */
    AbstractImagePrototype subscript();
    /**
     * @gwt.resource superscript.gif
     */
    AbstractImagePrototype superscript();
    /**
     * @gwt.resource ul.gif
     */
    AbstractImagePrototype ul();
    /**
     * @gwt.resource underline.gif
     */
    AbstractImagePrototype underline();
  }
  /**
   * This {@link Constants} interface is used to make the toolbar"s strings
   * internationalizable.
   */
  public interface Strings extends Constants {
    String black();
    String blue();
    String bold();
    String color();
    String createLink();
    String font();
    String green();
    String hr();
    String indent();
    String insertImage();
    String italic();
    String justifyCenter();
    String justifyLeft();
    String justifyRight();
    String large();
    String medium();
    String normal();
    String ol();
    String outdent();
    String red();
    String removeFormat();
    String removeLink();
    String size();
    String small();
    String strikeThrough();
    String subscript();
    String superscript();
    String ul();
    String underline();
    String white();
    String xlarge();
    String xsmall();
    String xxlarge();
    String xxsmall();
    String yellow();
  }
  /**
   * We use an inner EventListener class to avoid exposing event methods on the
   * RichTextToolbar itself.
   */
  private class EventListener implements ClickListener, ChangeListener,
      KeyboardListener {
    public void onChange(Widget sender) {
      if (sender == backColors) {
        basic.setBackColor(backColors.getValue(backColors.getSelectedIndex()));
        backColors.setSelectedIndex(0);
      } else if (sender == foreColors) {
        basic.setForeColor(foreColors.getValue(foreColors.getSelectedIndex()));
        foreColors.setSelectedIndex(0);
      } else if (sender == fonts) {
        basic.setFontName(fonts.getValue(fonts.getSelectedIndex()));
        fonts.setSelectedIndex(0);
      } else if (sender == fontSizes) {
        basic.setFontSize(fontSizesConstants[fontSizes.getSelectedIndex() - 1]);
        fontSizes.setSelectedIndex(0);
      }
    }
    public void onClick(Widget sender) {
      if (sender == bold) {
        basic.toggleBold();
      } else if (sender == italic) {
        basic.toggleItalic();
      } else if (sender == underline) {
        basic.toggleUnderline();
      } else if (sender == subscript) {
        basic.toggleSubscript();
      } else if (sender == superscript) {
        basic.toggleSuperscript();
      } else if (sender == strikethrough) {
        extended.toggleStrikethrough();
      } else if (sender == indent) {
        extended.rightIndent();
      } else if (sender == outdent) {
        extended.leftIndent();
      } else if (sender == justifyLeft) {
        basic.setJustification(RichTextArea.Justification.LEFT);
      } else if (sender == justifyCenter) {
        basic.setJustification(RichTextArea.Justification.CENTER);
      } else if (sender == justifyRight) {
        basic.setJustification(RichTextArea.Justification.RIGHT);
      } else if (sender == insertImage) {
        String url = Window.prompt("Enter an image URL:", "http://");
        if (url != null) {
          extended.insertImage(url);
        }
      } else if (sender == createLink) {
        String url = Window.prompt("Enter a link URL:", "http://");
        if (url != null) {
          extended.createLink(url);
        }
      } else if (sender == removeLink) {
        extended.removeLink();
      } else if (sender == hr) {
        extended.insertHorizontalRule();
      } else if (sender == ol) {
        extended.insertOrderedList();
      } else if (sender == ul) {
        extended.insertUnorderedList();
      } else if (sender == removeFormat) {
        extended.removeFormat();
      } else if (sender == richText) {
        // We use the RichTextArea"s onKeyUp event to update the toolbar status.
        // This will catch any cases where the user moves the cursur using the
        // keyboard, or uses one of the browser"s built-in keyboard shortcuts.
        updateStatus();
      }
    }
    public void onKeyDown(Widget sender, char keyCode, int modifiers) {
    }
    public void onKeyPress(Widget sender, char keyCode, int modifiers) {
    }
    public void onKeyUp(Widget sender, char keyCode, int modifiers) {
      if (sender == richText) {
        // We use the RichTextArea"s onKeyUp event to update the toolbar status.
        // This will catch any cases where the user moves the cursur using the
        // keyboard, or uses one of the browser"s built-in keyboard shortcuts.
        updateStatus();
      }
    }
  }
  private static final RichTextArea.FontSize[] fontSizesConstants = new RichTextArea.FontSize[] {
      RichTextArea.FontSize.XX_SMALL, RichTextArea.FontSize.X_SMALL,
      RichTextArea.FontSize.SMALL, RichTextArea.FontSize.MEDIUM,
      RichTextArea.FontSize.LARGE, RichTextArea.FontSize.X_LARGE,
      RichTextArea.FontSize.XX_LARGE};
  private Images images = (Images) GWT.create(Images.class);
  private Strings strings = (Strings) GWT.create(Strings.class);
  private EventListener listener = new EventListener();
  private RichTextArea richText;
  private RichTextArea.BasicFormatter basic;
  private RichTextArea.ExtendedFormatter extended;
  private VerticalPanel outer = new VerticalPanel();
  private HorizontalPanel topPanel = new HorizontalPanel();
  private HorizontalPanel bottomPanel = new HorizontalPanel();
  private ToggleButton bold;
  private ToggleButton italic;
  private ToggleButton underline;
  private ToggleButton subscript;
  private ToggleButton superscript;
  private ToggleButton strikethrough;
  private PushButton indent;
  private PushButton outdent;
  private PushButton justifyLeft;
  private PushButton justifyCenter;
  private PushButton justifyRight;
  private PushButton hr;
  private PushButton ol;
  private PushButton ul;
  private PushButton insertImage;
  private PushButton createLink;
  private PushButton removeLink;
  private PushButton removeFormat;
  private ListBox backColors;
  private ListBox foreColors;
  private ListBox fonts;
  private ListBox fontSizes;
  /**
   * Creates a new toolbar that drives the given rich text area.
   * 
   * @param richText the rich text area to be controlled
   */
  public RichTextToolbar(RichTextArea richText) {
    this.richText = richText;
    this.basic = richText.getBasicFormatter();
    this.extended = richText.getExtendedFormatter();
    outer.add(topPanel);
    outer.add(bottomPanel);
    topPanel.setWidth("100%");
    bottomPanel.setWidth("100%");
    initWidget(outer);
    setStyleName("gwt-RichTextToolbar");
    if (basic != null) {
      topPanel.add(bold = createToggleButton(images.bold(), strings.bold()));
      topPanel.add(italic = createToggleButton(images.italic(), strings.italic()));
      topPanel.add(underline = createToggleButton(images.underline(),
          strings.underline()));
      topPanel.add(subscript = createToggleButton(images.subscript(),
          strings.subscript()));
      topPanel.add(superscript = createToggleButton(images.superscript(),
          strings.superscript()));
      topPanel.add(justifyLeft = createPushButton(images.justifyLeft(),
          strings.justifyLeft()));
      topPanel.add(justifyCenter = createPushButton(images.justifyCenter(),
          strings.justifyCenter()));
      topPanel.add(justifyRight = createPushButton(images.justifyRight(),
          strings.justifyRight()));
    }
    if (extended != null) {
      topPanel.add(strikethrough = createToggleButton(images.strikeThrough(),
          strings.strikeThrough()));
      topPanel.add(indent = createPushButton(images.indent(), strings.indent()));
      topPanel.add(outdent = createPushButton(images.outdent(), strings.outdent()));
      topPanel.add(hr = createPushButton(images.hr(), strings.hr()));
      topPanel.add(ol = createPushButton(images.ol(), strings.ol()));
      topPanel.add(ul = createPushButton(images.ul(), strings.ul()));
      topPanel.add(insertImage = createPushButton(images.insertImage(),
          strings.insertImage()));
      topPanel.add(createLink = createPushButton(images.createLink(),
          strings.createLink()));
      topPanel.add(removeLink = createPushButton(images.removeLink(),
          strings.removeLink()));
      topPanel.add(removeFormat = createPushButton(images.removeFormat(),
          strings.removeFormat()));
    }
    if (basic != null) {
      bottomPanel.add(backColors = createColorList("Background"));
      bottomPanel.add(foreColors = createColorList("Foreground"));
      bottomPanel.add(fonts = createFontList());
      bottomPanel.add(fontSizes = createFontSizes());
      // We only use these listeners for updating status, so don"t hook them up
      // unless at least basic editing is supported.
      richText.addKeyboardListener(listener);
      richText.addClickListener(listener);
    }
  }
  private ListBox createColorList(String caption) {
    ListBox lb = new ListBox();
    lb.addChangeListener(listener);
    lb.setVisibleItemCount(1);
    lb.addItem(caption);
    lb.addItem(strings.white(), "white");
    lb.addItem(strings.black(), "black");
    lb.addItem(strings.red(), "red");
    lb.addItem(strings.green(), "green");
    lb.addItem(strings.yellow(), "yellow");
    lb.addItem(strings.blue(), "blue");
    return lb;
  }
  private ListBox createFontList() {
    ListBox lb = new ListBox();
    lb.addChangeListener(listener);
    lb.setVisibleItemCount(1);
    lb.addItem(strings.font(), "");
    lb.addItem(strings.normal(), "");
    lb.addItem("Times New Roman", "Times New Roman");
    lb.addItem("Arial", "Arial");
    lb.addItem("Courier New", "Courier New");
    lb.addItem("Georgia", "Georgia");
    lb.addItem("Trebuchet", "Trebuchet");
    lb.addItem("Verdana", "Verdana");
    return lb;
  }
  private ListBox createFontSizes() {
    ListBox lb = new ListBox();
    lb.addChangeListener(listener);
    lb.setVisibleItemCount(1);
    lb.addItem(strings.size());
    lb.addItem(strings.xxsmall());
    lb.addItem(strings.xsmall());
    lb.addItem(strings.small());
    lb.addItem(strings.medium());
    lb.addItem(strings.large());
    lb.addItem(strings.xlarge());
    lb.addItem(strings.xxlarge());
    return lb;
  }
  private PushButton createPushButton(AbstractImagePrototype img, String tip) {
    PushButton pb = new PushButton(img.createImage());
    pb.addClickListener(listener);
    pb.setTitle(tip);
    return pb;
  }
  private ToggleButton createToggleButton(AbstractImagePrototype img, String tip) {
    ToggleButton tb = new ToggleButton(img.createImage());
    tb.addClickListener(listener);
    tb.setTitle(tip);
    return tb;
  }
  /**
   * Updates the status of all the stateful buttons.
   */
  private void updateStatus() {
    if (basic != null) {
      bold.setDown(basic.isBold());
      italic.setDown(basic.isItalic());
      underline.setDown(basic.isUnderlined());
      subscript.setDown(basic.isSubscript());
      superscript.setDown(basic.isSuperscript());
    }
    if (extended != null) {
      strikethrough.setDown(extended.isStrikethrough());
    }
  }
}