GWT - GWT Designer开发Ajax应用 (03)

本文详细介绍如何使用GWT及GWT Designer创建一个简单的股票查看器应用,包括UI设计、代码实现、定时刷新股票价格等功能。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

前篇:http://blog.csdn.net/pathuang68/archive/2009/04/25/4117352.aspx

 

目标:利用GWT和GWT Designer创建一个股票查看器。

注意:如果看不到完整的图片,可以鼠标右键->“图片另存为”的方法,存到本地看即可。 


1. 新建一个GWT Java Project

 

1

 

2

点击Next按钮,如下图将项目名称设定为“StockWatcher”:

 

3

点击Next按钮。如下图,选择Create GWT Module复选框,并指定Module NameStockWatcherPackage Namecom.pnft.ajax

 

4

点击Finish按钮,

 

5

上图是GWT Designer自动为我们产生的一些代码,点击左下角Design tab并双击上边的Tab -  StockWatcher.java以放大,

 

6

删除Click me!按钮,以删除自动产生boilerplate code

 

7

点击Source tab,可以看到现在StockWatcher.java的代码变成了:

 

8

到此,项目建立完成。


2. UI设计

我们希望最终的参考界面如下图所示:

 

9

现在我们来设计图形界面:

a. rootPanel中放置一个VerticalPanel

 

10

 

11

将刚才添加的VerticalPanel放置到rootPanel的左上角,并拖动其Anchor使之放大到合适的大小,并将其variable属性改为mainPanel,如下图所示:

 

12

b. 如下图所示,在mainPanel中增加一个FlexTable,并将其variables户型改为stocksFlexTable

 

13

c. 如下图所示,在mainPanel中,stocksFlexTable之下,增加一个HorizontalPanel,并使其variable属性为“addPanel

 

14

d. addPanel中增加两个widget,如下图所示:

   - 一个文本框,使其variable属性为“newSymbolTextBox”;

   - 一个按钮,使其variable属性为“addButton”,其Text属性为“Add

 

15

e. addPanel下面增加一个Label,修改其属性,使其variable属性为“lastUpdatedLabel”:

 

16

f. Convert local to field。选中最上层的mainPanel,然后点击Covert local to field按钮:

 

17

对于其他widgetFlexTableTextBoxButton以及Label均使用同样方法进行Convert local to field

 

下图就是我们前面所做的工作的代码结果:

 

18

g. 将文本框newSymbolTextBoxfocus属性设定为true,这样当进入到该页面是,文本框newSymbolTextBox将自动获得输入焦点。


3. 代码设计

   - a. 切换到Source,并找到下面高亮的语句。

 

19

插入代码,使其如下:

 

20

到目前为止,我们前面所做的工作结果类似:

 

21

b. 给按钮增加onClick事件处理函数:

 

22

自动生成代码如下:

        addButton.addClickListener(new ClickListener()

        {

            public void onClick(final Widget sender)

            {

            }

        });

onClick函数中增加如下一行,使之如下(注意addStock()目前还不存在)

        addButton.addClickListener(new ClickListener()

        {

            public void onClick(final Widget sender)

            {

                addStock();

            }

        });

 

c. 给文本框增加一个keyDown处理函数:

 

23

自动生成的代码如下:

        newSymbolTextBox.addKeyboardListener(new KeyboardListenerAdapter()

        {

            public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

            {

            }

        });

onKeyDown函数中增加如下一行,使之如下(注意addStock()目前还不存在)

        newSymbolTextBox.addKeyboardListener(new KeyboardListenerAdapter()

        {

            public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

            {

                addStock();

            }

        });

 

d. 增加addStock方法:

 

24

选择Create method ‘addStock()’ in type ‘StockWatcher’(注意,此处所谓type即为class之别称),修改addStock的的代码如下:

    protected void addStock()

    {

        final String symbol = newSymbolTextBox.getText().toUpperCase().trim();

        newSymbolTextBox.setFocus(true);

        // validation

        // symbol must be between 1 and 10 chars that are numbers, letters, or dots

        // the matches method takes a parameter of regular expression like the following code

        if(!symbol.matches("^[0-9a-zA-Z//.]{1,10}$"))

        {

            Window.alert("'" + symbol + "' is not a valid symbol.");

            newSymbolTextBox.selectAll();

            return;

        }

        newSymbolTextBox.setText("");

        // here we need to add the stock to the list...

       

    }

 

e. 修改onKeyDown代码如下,判断是否有回车键按下,如果是,则调用addStock方法:

    public void onKeyDown(final Widget sender, final char keyCode, final int modifiers)

    {

        if(keyCode == KEY_ENTER)

        {

            addStock();

        }

    }

 

f. 增加一个ArrayList如下:

 

25

 

g. 修改addStock方法,使之如下:

    protected void addStock()

    {

        final String symbol = newSymbolTextBox.getText().toUpperCase().trim();

        newSymbolTextBox.setFocus(true);

        // validation

        // symbol must be between 1 and 10 chars that are numbers, letters, or dots

        // matches method takes a parameter of regular expression like the following code

        if(!symbol.matches("^[0-9a-zA-Z//.]{1,10}$"))

        {

            Window.alert("'" + symbol + "' is not a valid symbol.");

            newSymbolTextBox.selectAll();

            return;

        }

        newSymbolTextBox.setText("");

        // here we need to add the stock to the list...

        if(stocks.contains(symbol)) return;

       

        // add the stock to the list

        int row = stocksFlexTable.getRowCount();

        stocks.add(symbol);

        stocksFlexTable.setText(row, 0, symbol);

       

        // add button to remove this stock from the list

        Button removeStock = new Button("x");

        removeStock.addClickListener(new ClickListener()

        {

            public void onClick(Widget sender)

            {

                int removedIndex = stocks.indexOf(symbol);

                stocks.remove(removedIndex);

                stocksFlexTable.removeRow(removedIndex + 1);

            }

        });

        stocksFlexTable.setWidget(row, 3, removeStock);

    }

注意:

// here we need to add the stock to the list...后面的代码是新加的。

 

h. 阶段性结果:

 

26

i. 增加一个计时器,用来模拟股票价格在一天中的变化。为此,我们必须

import com.google.gwt.user.client.Timer;

  在类StockWatcher最开始处增加以下代码,用来确定多长时间间隔可进行一次刷新:

    private static final int REFRESH_INTERVAL = 5000;

 

并在onModuleLoad()方法的最后处,增加以下代码:

    Timer refreshTimer = new Timer()

    {

        public void run()       // 注意:以内部类的形式出现

        {

            refreshWatchList(); // 注意:此时refreshWatchList方法尚不存在

        }

    };

    refreshTimer.scheduleRepeating(REFRESH_INTERVAL);

 

j. 增加refreshWatchList方法,和增加addStock方法的过程类似。

 

k. 新增一个类StockPrice

 

27

 

28

点击Finish按钮。

 

修改类StockPrice的代码,使之如下:

package com.pnft.ajax.client;

 

public class StockPrice

{

    private String symbol;

    private double price;

    private double change;

   

    public StockPrice()

    {      

    }

   

    public StockPrice(String symbol, double price, double change)

    {

        this.symbol = symbol;

        this.price = price;

        this.change = change;

    }

 

    public String getSymbol() {

        return symbol;

    }

 

    public void setSymbol(String symbol) {

        this.symbol = symbol;

    }

   

    public double getChangePercent()

    {

        return 100.0 * this.change / this.price;

    }

 

    public double getPrice() {

        return price;

    }

 

    public void setPrice(double price) {

        this.price = price;

    }

 

    public double getChange() {

        return change;

    }

 

    public void setChange(double change) {

        this.change = change;

    }

}

 

l. 回到StockWatcher源代码,修改在步骤j中增加的方法refreshWatchList,并引入相关的包,使得方法refreshWatchList的代码如下:

    protected void refreshWatchList()

    {

        final double MAX_PRICE = 100.0;

        final double MAX_PRICE_CHANGE = 0.02;   // +/- 2%

       

        StockPrice[] prices = new StockPrice[stocks.size()];

        for(int i = 0; i < stocks.size(); i++)

        {

            double price = Random.nextDouble() * MAX_PRICE;

            double change = price * MAX_PRICE_CHANGE * (Random.nextDouble() * 2.0 - 1.0);

            prices[i] = new StockPrice((String)stocks.get(i), price, change);

        }

        updateTable(prices);    // 注意此时updateTable方法尚不存在

    }

m. 增加updateTable方法,过程与步骤d(增加addStock方法)类似。修改updateTable方法的代码,使之如下:

    private void updateTable(StockPrice[] prices)

    {

       for(int i = 0; i < prices.length; i++)

       {

           updateTable(prices[i]);

       }

      

       // change the last update timestamp

       lastUpdatedLabel.setText("Last update : " + DateTimeFormat.

getMediumDateFormat().format(new Date()));

    }

   

    private void updateTable(StockPrice price)

    {

        // make sure the stock is still in our watch list

        if (!stocks.contains(price.getSymbol()))

        {

            return;

        }

 

        int row = stocks.indexOf(price.getSymbol()) + 1;

 

        // apply nice formatting to price and change

        String priceText = NumberFormat.getFormat("#,##0.00").format(

                price.getPrice());

        NumberFormat changeFormat = NumberFormat

                .getFormat("+#,##0.00;-#,##0.00");

        String changeText = changeFormat.format(price.getChange());

        String changePercentText = changeFormat

                .format(price.getChangePercent());

 

        // update the watch list with the new values

        stocksFlexTable.setText(row, 1, priceText);

        stocksFlexTable.setText(row, 2, changeText + " (" + changePercentText + "%)");

    }

 

n. 如以下图形所表明的步骤,增加Googlelogo

 

29

 

30

点击Next按钮,

 

31

点击Finish按钮。图片已经被import进来:

32

回到StockWatcher.javaDesign状态,在FlexTable之上,增加一个Image widget,然后将该Image widgetURL属性设置为图片所在的位置。

 

33

 

34

指定ImageURL属性为googlecode.png,得到:

 

35

o. 在图片下面增加一个Label,使其Text属性为“Stock Watcher”,并做相应的微调,得到结果如下:

 

36

p. 试运行

 

37

q. 增加一些颜色

 

38

r. 部署

 

39

 

40

选择Tomcat6的路径,点击OK按钮。

 

41

部署成功。在Tomcat6/webapps目录下多出了一个StockWatcher.war文件:

 

42

s. 启动Tomcat6

t. 最后结果:

 

43

 

 

后篇: http://blog.csdn.net/pathuang68/archive/2009/04/27/4130429.aspx

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

内容概要:本文介绍了一种用于电磁暂态(EMT)研究的第四类全变流器型风力发电系统的通用Simulink仿真模型,旨在构建一个能够准确反映实际风电系统动态特性的简化通用模型。该模型涵盖了风力机、传动链、发电机、全功率变流器及其控制策略等关键组成部分,重点突出系统在电网故障、风速波动等复杂工况下的动态响应能力,适用于风电并网电磁暂态分析、新型电力系统稳定性评估及高比例可再生能源接入场景的研究。模型设计兼顾准确性与仿真效率,便于研究人员快速搭建和调试,推动风电系统建模与控制技术的发展; 适合人群:具备一定电力系统理论基础和MATLAB/Simulink仿真能力,从事新能源发电、电力电子变换、风电并网控制及相关方向的研究生、科研人员及工程技术人员; 使用场景及目标:①开展风电系统在电网扰动下的电磁暂态仿真分析;②研究全功率变流器风电机组的动态行为与控制特性;③支撑新型电力系统中高渗透率风电接入的稳定性与电能质量评估,服务于学术研究、课程教学与工程项目前期仿真验证; 阅读建议:建议读者结合文中提供的模型结构与参数设置,在Simulink环境中动手复现并调试仿真模型,通过设置不同运行工况(如三相短路、低电压穿越、风速突变等)观察系统响应,深入理解全变流器风电机组的建模方法、控制逻辑与动态特性,进而拓展应用于更复杂的多机并网或综合能源系统仿真场景。
内容概要:本文探讨了Hash算法在芯片行业,特别是网络处理器(NPU)中的性能优化实践,聚焦于如何通过硬件流水线设计实现纳秒级高速哈希查找。文章分析了传统软件哈希方案在高带宽场景下的局限性,提出基于硬件描述语言或高层次综合(HLS)的设计方法,采用CRC32等硬件友好型哈希函数、并行多路哈希、流水线化解耦以及双端口存储结构等核心技术,实现低延迟、无阻塞的数据包处理。通过C++风格的HLS代码示例,展示了从算法选择到资源优化的完整硬件加速逻辑,并深入剖析了循环展开、位宽控制、内存映射和流水线调度等关键实现细节。最后展望了可编程交换机、P4语言支持及TCAM与哈希混合架构等未来发展方向。; 适合人群:具备数字电路基础、熟悉Verilog/SystemVerilog或HLS的芯片设计工程师,以及从事网络芯片、FPGA加速、高性能路由设备研发的技术人员(工作年限1-5年为宜);也适合对硬件加速算法感兴趣的研究人员。; 使用场景及目标:①掌握如何将哈希算法高效映射到硬件逻辑中以满足线速转发需求;②理解流水线设计、资源约束优化、读写冲突规避等在实际芯片项目中的应用;③为开发高性能网络处理器中的流表/路由表查找单元提供技术参考与实现范例。; 阅读建议:学习时应结合HLS工具(如Xilinx Vitis HLS)进行代码仿真与综合,重点关注#pragma指令对硬件结构的影响,并对比不同哈希算法在资源占用与时序表现上的差异,深入理解“空间换时间”的硬件优化本质。
内容概要:本文系统研究了基于粒子群优化(PSO)、灰狼优化(GWO)、鲸鱼优化(WOA)、哈里斯鹰优化(HHO)、蜣螂优化(DBO)和麻雀搜索算法(SSA)六种智能优化算法在无人机三维路径规划中的应用,并在Matlab平台上实现了相应的仿真代码。研究构建了复杂的三维地形与障碍物环境模型,设计了包含路径长度、飞行时间、能耗及安全性等多维度的成本函数,通过定义合理的适应度函数与飞行约束条件,对各类算法的路径搜索能力、收敛速度与规划质量进行了全面对比分析。通过仿真实验验证了各算法在静态复杂环境下的性能表现,旨在为实际无人机任务中优化算法的选择提供科学依据和技术支持。; 适合人群:具备一定Matlab编程基础,从事智能优化算法、无人机路径规划、自动化控制及相关领域研究的研究生、科研人员或工程技术人员。; 使用场景及目标:① 掌握主流群智能优化算法在无人机三维路径规划中的建模与实现方法;② 对比分析不同算法在相同复杂环境下的性能差异,为算法选型提供量化依据;③ 为后续研究动态环境路径规划、多无人机协同任务分配等问题奠定理论与技术基础; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点关注适应度函数的设计、障碍物规避策略的实现以及多目标成本函数的权衡机制,同时可通过调整参数设置或引入新型优化算法进行扩展实验,以深化对算法性能的理解与实际应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值