Popup

Popup继承自LayoutContainer,可以使其弹出的窗口,始终至于其他的components之上。现在,我想要在用户点击Link feed按钮的时候可以显示一个Popup表单窗口,可以让用户输入一个URL。

  • 创建新package:com.danielvaughan.rssreader.client.components。在此包下创建LinkFeedPopup类,继承自Popup。
  • 然后在构造函数里,加入相关设置,代码如下:
public LinkFeedPopup() {
setSize(300, 55);
setBorders(true);
setShadow(true);
setAutoHide(false);
}
  • 我们设置了其大小,是否有边框,和阴影效果。


SelectionListener

现在我们有button和popup。如果想通过点击button可以控制popup,那么就需要Listener(正如先前提到的,GXT对事件的处理是使用的Listener),首先要把一个Listener注册到某一个component上,当有对应的事件发生的时候,就会通知Listener。因此要在Listener里编写相关的代码,以作为此次事件的响应时来执行。在我们的RSSReader项目里,Link feed button的点击Listener,应该是SelectionListener(而不是click之类的)。具体操作步骤如下:

  • 因为Link feed button被添加到RssNavigationPanel里,自然的我们要在RssNavigationPanel类,新建一个LinkFeedPopup。
final LinkFeedPopup linkFeedPopup = new LinkFeedPopup();


  • 要保证popup的弹出始终在整个面板Viewport内:
linkFeedPopup.setConstrainViewport(true);


  • 注册SelectionListener
package com.danielvaughan.rssreader.client.components;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.button.ToggleButton;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;

public class RssNavigationPanel extends ContentPanel
{
public RssNavigationPanel()
{
setHeading("Navigation");
final ToggleButton btnLinkFeed = new ToggleButton("Link feed");
btnLinkFeed.setIconStyle("link-feed");
setButtonAlign(HorizontalAlignment.LEFT);

ToolTipConfig linkFeedToolTipConfig = new ToolTipConfig();
linkFeedToolTipConfig.setTitle("Link to existing RSS feed");
linkFeedToolTipConfig
.setText("Allows you to enter the URL of an existing RSS feed you would like to link to");
btnLinkFeed.setToolTip(linkFeedToolTipConfig);

final LinkFeedPopup linkFeedPopup = new LinkFeedPopup();
linkFeedPopup.setConstrainViewport(true);
btnLinkFeed.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
if (btnLinkFeed.isPressed()) {
linkFeedPopup.show();
} else {
linkFeedPopup.hide();
}
}
});


addButton(btnLinkFeed);
}
}


  • 给btnLinkFeed注册了一个SelectionListener, 当btnLinkFeed被按下的时候,显示linkFeedPopup;当btnLinkFeed被按起的时候,隐藏linkFeedPopup



TextField

TestField继承自Field,Field继承自BoxComponent。Field作为表单数据项的基类。这些具体的Field,例如textboxes,checkboxes,listboxes等,都会被渲染成标准的HTML标签。TextField则是他们其中之一。一个GXT的TextField的定义代码如下:

TextField<String> text = new TextField<String>();


其中泛型String类型,表示其保存的值的类型。GXT的Field同样具有内建的功能来设置验证条件。对于我们RSSReader项目目前的需求来说,我们需要使用TextField来限制用户只可以输入URL的字符串。

  • 因为要在弹出的popup窗口构建一个表单,自然我们要在LinkFeedPopup类里面编辑。创建一个TextField的属性
private final TextField<String> tfUrl = new TextField<String>();
  • Override LinkFeedPopup类的onRender()方法,一个重新的,空的onRender()方法如下:
@Override
protected void onRender(Element parent, int pos) {
super.onRender(parent, pos);
}
  • 在onRender()方法里加入一个Text component,来告诉用户应该录入URL:
final Text txtExplaination = new Text("Enter a feed url");
  • 创建一个button,当用户录入URL后,可以点击他来提交。
final Button btnAdd = new Button("add");
btnAdd.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
addFeed(tfUrl.getValue());
}
});
  • 在响应点击事件处理的过程里,我们调用的addFeed方法,其用来处理具体的提交之后的操作。目前呢,只是先把用户录入的URL弹出一个Alert而已。
public void addFeed(String url) {
Window.alert("We would now attempt to add " + url + " at this point");
}


  • 之前的操作,大家会发现创建了两个对象,并注册了Listener。但是并没有添加到LinkFeedPopup类里面设置具体的显示效果。因此我们要对popup设置其布局显示效果。
final BorderLayout layout = new BorderLayout();
setLayout(layout);
  • 让txtExplaination 放在north区
final BorderLayoutData northData = new
BorderLayoutData(LayoutRegion.NORTH, 20);
northData.setMargins(new Margins(2));
add(txtExplaination, northData);


  • 让textbox放在center区
final BorderLayoutData centerData = new
BorderLayoutData(LayoutRegion.CENTER);
centerData.setMargins(new Margins(2));
add(tfUrl, centerData);
  • 让提交button放在east区
final BorderLayoutData eastData = new
BorderLayoutData(LayoutRegion.EAST, 50);
eastData.setMargins(new Margins(2));
add(btnAdd, eastData);
  • 最后运行一下程序,当点击Link feed button



  • 录入一个URL之后,点击add button



  • 完整的LinkFeedPopup类代码如下 :
package com.danielvaughan.rssreader.client.components;

import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Popup;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;

public class LinkFeedPopup extends Popup
{
private final TextField<String> tfUrl = new TextField<String>();

public LinkFeedPopup() {
setSize(300, 55);
setBorders(true);
setShadow(true);
setAutoHide(false);
}

@Override
protected void onRender(Element parent, int pos) {
super.onRender(parent, pos);
final Text txtExplaination = new Text("Enter a feed url");
final Button btnAdd = new Button("add");
btnAdd.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
addFeed(tfUrl.getValue());
}
});


final BorderLayout layout = new BorderLayout();
setLayout(layout);

final BorderLayoutData northData = new BorderLayoutData(LayoutRegion.NORTH, 20);
northData.setMargins(new Margins(2));
add(txtExplaination, northData);

final BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
centerData.setMargins(new Margins(2));
add(tfUrl, centerData);

final BorderLayoutData eastData = new BorderLayoutData(LayoutRegion.EAST, 50);
eastData.setMargins(new Margins(2));
add(btnAdd, eastData);
}

public void addFeed(String url) {
Window.alert("We would now attempt to add " + url + " at this point");
}

}