试用Google Web Toolkit(2)

原创 2006年05月20日 14:18:00
把GWT中sample目录中的KitchenSink按(1)中的步骤建立一个eclipse工程


projectCreator -eclipse KitchenSink
applicationCreator -eclipse KitchenSink com.google.gwt.sample.kitchensink.client. KitchenSink

在把sample/KitchenSink/com/.../kitchensink目录下的client和public拷贝过来,这个工程实际上演示GWT中的主要UI组件。

在GWT中如果想要创造一个复杂组件,你需要从Composite类派生一个子类,在这个子类中,你可以封装一系列其他从Widget派生的组件,对外提供一致的抽象接口。

比如,我想写一个类似于一般IDE中都提供的属性编辑器,很显然,这个东西由多个属性编辑项(Item)构成,而每个属性项目包括属性的名字以及他对应的值,这个值可以由Text, Combox, List, Dialog等等你能想到的一切能输入值的组件构成。

首先来看看我们的基本单位PropertyItem(属性项)应该是个什么样子。

package com.google.gwt.sample.kitchensink.client.custom;
// 从Composite 继承,组合两个组件属性名字和属性值
public class PropertyItem extends Composite {
    // 用id来唯一标识每个item
    private String id;  
    // 属性的名字,选择用Label或是HTML控件
    private HTML nameView;
    // 属性值的编辑器
    private BaseEditor valueView;
    // panel,放置属性名字和属性值的容器组件,这是一个横向排列的panel
    private HorizontalPanel container = new HorizontalPanel();
}

最大的麻烦恐怕就是属性值的编辑器了,因为它可以是一个任何可能的编辑器,考虑把它抽象为一个接口;

package com.google.gwt.sample.kitchensink.client.custom;

import com.google.gwt.user.client.ui.Widget;

public interface Editable {
    // 一个属性值编辑器必须能取值和设置值,当然这个值对象可能更复杂一些,不过先用一个String类就够了
    public String getValue();
    public void setValue(String value);
    // 这个编辑器需要暴露它的最高层的UI组件,以便显示在PropertyItem中。
    public Widget getWidget();
}


接下来要考虑的事情是:在属性值的编辑器的值发生变化时,外部可以接收到值变化的事件。
package com.google.gwt.sample.kitchensink.client.custom;
public interface ChangeListener {
    public void onChange(Editable sender);
}

每个属性值编辑器都是一个事件源,需要提供注册事件捕捉器的能力。
package com.google.gwt.sample.kitchensink.client.custom;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public abstract class BaseEditor implements Editable {

    private List listeners = new ArrayList();
   
    public BaseEditor() {
    }
   
    public boolean addChangeListener(ChangeListener listener) {
        return listeners.add(listener);
    }
   
    public boolean removeChangeListener(ChangeListener listener) {
        return listeners.remove(listener);
    }
   
    public ChangeListener removeChangeListener(int index) {
        return (ChangeListener)listeners.remove(index);
    }
   
    public void notifyAllChangeListeners() {
        for (Iterator iter= listeners.iterator(); iter.hasNext();) {
            ((ChangeListener)iter.next()).onChange(this);
        }
    }
       
}


看看如何实现一个基本的属性编辑器,比如一个最普通的文本输入框,它只是对TextBox组件一个adaptor。
package com.google.gwt.sample.kitchensink.client.custom;

import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class TextEditor extends BaseEditor implements com.google.gwt.user.client.ui.ChangeListener  {

    private TextBox editor = new TextBox();
   
    public TextEditor() {
        super();
        editor.addChangeListener(this);
    }

    public String getValue() {
        return editor.getText();
    }

    public void setValue(String value) {
        editor.setText(value);
    }

    public void onChange(Widget sender) {
        if (sender == editor) {
            notifyAllChangeListeners();
        }
    }

    public Widget getWidget() {
        return editor;
    }


}

然后把它填充到PropertyItem中去:
package com.google.gwt.sample.kitchensink.client.custom;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;

public class PropertyItem extends Composite {
    private String id;
    private HTML nameView;
    private BaseEditor valueView;
    private HorizontalPanel container = new HorizontalPanel();
/*    VerticalPanel left = new VerticalPanel();
    VerticalPanel right = new VerticalPanel();*/

    public PropertyItem(String id) {
        this(id, "label", EditorType.Text, "");
    }
   
    public PropertyItem(String id, String name, int editorType, String value) {
        this.id = id;
        setNameView(new HTML(name));
        setValueView(EditorFactory.create(editorType));
        setValue(value);
        adjustPosition();
        setWidget(container);
    }
   
    public void setNameView(HTML view) {   
        refresh(nameView, view, 0);
        nameView = view;
    }
   
    public void setValueView(BaseEditor view) {
        Widget widget = null;
        if (null != valueView) widget = valueView.getWidget();
        refresh(widget, view.getWidget(), 1);
        valueView = view;
    }
   
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
   
   
    public void setName(String name) {
        nameView.setHTML(name);
    }
   
    public void setValue(String value) {
        valueView.setValue(value);
    }
   
    public String getValue() {
        return valueView.getValue();
    }
   
    public String getName() {
        return nameView.getHTML();
    }
   
    public void addChangeListener(ChangeListener listener) {
        valueView.addChangeListener(listener);
    }

    public HTML getNameView() {
        return nameView;
    }

    public BaseEditor getValueView() {
        return valueView;
    }
   
    public void refresh(Widget oldView, Widget newView, int index) {
        int oldIndex = -1;
        if (oldView != null) oldIndex = container.getWidgetIndex(oldView);
        if (oldIndex != -1) container.remove(oldView);
        int setIndex = (oldIndex == -1) ? index : oldIndex;
        container.insert(newView, setIndex);
    }
   
    public void adjustPosition() {
        nameView.setStyleName("inspector-item-name");
        container.setCellWidth(nameView, "50%");
        container.setCellWidth(valueView.getWidget(), "50%");
        container.setCellVerticalAlignment(nameView, HasVerticalAlignment.ALIGN_MIDDLE);
        container.setCellVerticalAlignment(valueView.getWidget(), HasVerticalAlignment.ALIGN_MIDDLE);
        container.setCellHorizontalAlignment(nameView, HasHorizontalAlignment.ALIGN_LEFT);
        container.setCellHorizontalAlignment(valueView.getWidget(), HasHorizontalAlignment.ALIGN_LEFT);
    }
}



有了PropertyItem,把他们组合在一个垂直排列的panel内,就可以组成一个简单的PropertyEditor.

package com.google.gwt.sample.kitchensink.client.custom;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.VerticalPanel;

public class Inspector extends Composite {

   
    VerticalPanel container = new VerticalPanel();
    private List itemList = new ArrayList();
   
    public Inspector() {
        super();
       
        container.setStyleName("inspector");       
        setWidget(container);
       
    }
   
    public void addItemView(PropertyItem item) {
        container.add(item);
    }
   
    public void removeItemView(PropertyItem item) {
        container.remove(item);
    }
   
    public void addItem(PropertyItem item) {
        itemList.add(item);
        addItemView(item);
    }
   
    public void removeItem(PropertyItem item) {
        itemList.remove(item);
        removeItemView(item);
    }
  
    public void addItem(String id, String name, int editorType, String value) {
        addItem(new PropertyItem(id, name, editorType, value));
    }
   
    public PropertyItem getItem(String id) throws ItemNotFoundException {
        for (Iterator iter = itemList.iterator(); iter.hasNext();) {
            PropertyItem item = (PropertyItem)iter.next();
            if (item.getId().equalsIgnoreCase(id)) {
                return item;
            }
        }
        throw new ItemNotFoundException("item " + id + "not found");
    }
   
    public void removeItem(String id) throws ItemNotFoundException  {
        PropertyItem item = getItem(id);
        removeItem(item);
    }
   
    private void addChangeListenerInternal(String id, ChangeListener listener) throws ItemNotFoundException {
        getItem(id).addChangeListener(listener);
    }
   
    public boolean addChangeListener(String id, ChangeListener listener) {
        try {
            addChangeListenerInternal("t1", listener);
            return true;
        } catch (ItemNotFoundException e) {
            return false;
        }
    }
}



要在kitchensink项目中测试这个组件,可以仿造其中的Buttons类:

package com.google.gwt.sample.kitchensink.client;

import com.google.gwt.sample.kitchensink.client.custom.Editable;
import com.google.gwt.sample.kitchensink.client.custom.EditorType;
import com.google.gwt.sample.kitchensink.client.custom.Inspector;
import com.google.gwt.user.client.ui.*;

public class PropertyEditor extends Sink implements com.google.gwt.sample.kitchensink.client.custom.ChangeListener {

    public static SinkInfo init()  {
        return new SinkInfo("PropertyEditor",
            "Composite class build <code>PropertyEditor</code>") {
            public Sink createInstance() {
                return new PropertyEditor();
            }
        };
    }
   
   
    private void setInspector() {

          Inspector inspector = new Inspector();
          inspector.addItem("t1", "key", EditorType.Text, "dddd");
          inspector.addItem("t2", "cdasfas", EditorType.Text, "asdfsaf");

         
//        All composites must call setWidget() in their constructors.
          setWidget(inspector);
        
    }
   


    /**
     * Constructs an OptionalTextBox with the given caption on the check.
     *
     * @param caption the caption to be displayed with the check box
     */
    public PropertyEditor() {
      // Place the check above the text box using a vertical panel.

        setInspector();
       

      // Give the overall composite a style name.
      setStyleName("example-OptionalCheckBox");
    }


    public void onChange(Editable sender) {
        System.out.println(sender.getValue());
    }

   

}

当然,这很丑陋,可以利用css调整,不过我早告诉你,我对那些玩意不感兴趣。

面向 Java 开发人员的 Ajax: 探索 Google Web Toolkit

介: 最近发布的 Google Web Toolkit (GWT) 是一组全面的 API 和工具,它支持用户几乎完全使用 Java™ 代码来创建动态 Web 应用程序。Philip McCarthy ...

面向 Java 开发人员的 Ajax: Google Web Toolkit 入门

Ajax简介 Ajax是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写,由XHTML、CSS、JavaScript、XMLHttpRequest、XM...

Google Web Toolkit Solutions

  • 2008年02月19日 16:15
  • 9.94MB
  • 下载

GWT开发 - Eclipse, Google Plugin and Google Web Toolkit SDK

Google Web Toolkit 官方地址 1 在eclipse上安装Google plugin 针对不同版本eclipse的插件下载地...

Google.Web.Toolkit.Solutions

  • 2008年02月26日 07:50
  • 10.8MB
  • 下载

google web toolkit

  • 2010年01月21日 15:50
  • 19KB
  • 下载

Google OAuth2 for Android(type of web OAuth)

Google OAuth2 for Android(type of web OAuth)一、应用创建和注册1.登录google登录Google 应用 2.创建项目3.创建OAuth同意屏幕4.创建O...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:试用Google Web Toolkit(2)
举报原因:
原因补充:

(最多只允许输入30个字)