48.java编程思想——创建窗口和程序片 按钮及事件

48.java编程思想——创建窗口和程序片 按钮及事件

制作一个按钮非常简单:只需要调用Button 构建器,并指定想在按钮上出现的标签就行了(如果不想要标签,亦可使用默认构建器,但那种情况极少出现)。可参照后面的程序为按钮创建一个句柄,以便以后能够引用它。

Button 是一个组件,象它自己的小窗口一样,会在更新时得以重绘。这意味着我们不必明确描绘一个按钮或者其他任意种类的控件;只需将它们纳入窗体,以后的描绘工作会由它们自行负责。所以为了将一个按钮置入窗体,需要过载init()方法,而不是过载paint():

1     代码1

import java.awt.*;

import java.applet.*;

public class Button1 extends Applet {

    Button b1 = new Button("Button 1"), b2 = new Button("Button 2");

    public voidinit() {

        add(b1);

        add(b2);

    }

} /// :~

如下图1


必须同时调用Applet add()方法,令按钮放置在程序片的窗体中。这看起来似乎比实际简单得多,因为对add()的调用实际会(间接地)决定将控件放在窗体的什么地方。

2     捕获事件

大家可注意到假如编译和运行上面的程序片,按下按钮后不会发生任何事情。必须进入程序片内部,编写用于决定要发生什么事情的代码。对于由事件驱动的程序设计,它的基本目标就是用代码捕获发生的事件,并由代码对那些事件作出响应。事实上,GUI 的大部分内容都是围绕这种事件驱动的程序设计展开的。大家应该有了面向对象程序设计的一些基础,此时可能会想到应当有一些面向对象的方法来专门控制事件。例如,也许不得不继承每个按钮,并过载一些“按钮按下”方法(尽管这显得非常麻烦有有限)。大家也可能认为存在一些主控“事件”类,其中为希望响应的每个事件都包含了一个方法。

在对象以前,事件控制的典型方式是switch 语句。每个事件都对应一个独一无二的整数编号;而且在主事件控制方法中,需要专门为那个值写一个switch。

Java 1.0 的AWT 没有采用任何面向对象的手段。此外,它也没有使用switch 语句,没有打算依靠那些分配给事件的数字。相反,我们必须创建if 语句的一个嵌套系列。通过if 语句,我们需要尝试做的事情是侦测到作为事件“目标”的对象。换言之,那是我们关心的全部内容——假如某个按钮是一个事件的目标,那么它肯定是一次鼠标点击,并要基于那个假设继续下去。但是,事件里也可能包含了其他信息。例如,假如想调查一次鼠标点击的像素位置,以便画一条引向那个位置的线,那么Event 对象里就会包含那个位置的信息(也要注意Java 1.0 的组件只能产生有限种类的事件,而Java 1.1 和Swing/JFC 组件则可产生完整的一系列事件)。

Java 1.0 版的AWT 方法串联的条件语句中存在action() 方法的调用。虽然整个Java 1.0 版的事件模型不兼容Java 1.1 版,但它在还不支持Java1.1 版的机器和运行简单的程序片的系统中更广泛地使用,忠告您使用它会变得非常的舒适,包括对下面使用的action() 程序方法而言。action()拥有两个自变量:第一个是事件的类型,包括所有的触发调用action()的事件的有关信息。例如鼠标单击、普通按键按下或释放、特殊按键按下或释放、鼠标移动或者拖动、事件组件得到或丢失焦点,等等。第二个自变量通常是我们忽略的事件目标。第二个自变量封装在事件目标中,所以它像一个自变量一样的冗长。

需调用action() 时情况非常有限:将控件置入窗体时,一些类型的控件(按钮、复选框、下拉列表单、菜单)会发生一种“标准行动”,从而随相应的Event 对象发起对action()的调用。比如对按钮来说,一旦按钮被按下,而且没有再多按一次,就会调用它的action()方法。这种行为通常正是我们所希望的,因为这正是我们对一个按钮正常观感。还可通过handleEvent()方法来处理其他许多类型的事件。

3     代码2

import java.awt.*;

import java.applet.*;

public class Button2 extends Applet {

    Button b1 = new Button("Button 1"), b2 = new Button("Button 2");

    public voidinit() {

        add(b1);

        add(b2);

    }

    public booleanaction(Event evt, Object arg){

        if (evt.target.equals(b1))

            getAppletContext().showStatus("Button 1");

        else if (evt.target.equals(b2))

            getAppletContext().showStatus("Button 2");

        // Let the base class handle it:

        else

            return super.action(evt, arg);

        return true; // We'vehandled it here

    }

} /// :~

为了解目标是什么,需要向Event 对象询问它的target(目标)成员是什么,然后用equals() 方法检查它是否与自己感兴趣的目标对象句柄相符。为所有感兴趣的对象写好句柄后,必须在末尾的else 语句中调用super.action(evt, arg)方法。此时调用的是我们过载过的方法,而非它的基础类版本。然而,基础类版本也针对我们不感兴趣的所有情况提供了相应的控制代码。

除非明确进行,否则它们是不会得到调用的。返回值指出我们是否已经处理了它,所以假如确实与一个事件相符,就应返回true;否则就返回由基础类event()返回的东西。

对这个例子来说,最简单的行动就是打印出到底是什么按钮被按下。一些系统允许你弹出一个小消息窗口,但Java 程序片却防碍窗口的弹出。不过我们可以用调用Applet 方法的getAppletContext()来访问浏览器,然后用showStatus()在浏览器窗口底部的状态栏上显示一条信息。还可用同样的方法打印出对事件的一段完整说明文字,方法是调用getAppletConext().showStatus(evt + "")。空字串会强制编译器将evt 转换成一个字符串。这些报告对于测试和调试特别有用,因为浏览器可能会覆盖我们的消息。

ShowStatus()也属于Applet 的一个方法,所以可直接调用它,不必调用getAppletContext()。尽管看起来似乎很奇怪,但我们确实也能通过event()中的第二个参数将一个事件与按钮上的文字相配。

4     代码3

import java.awt.*;

import java.applet.*;

public class Button3 extends Applet {

    Button b1 = new Button("Button 1"), b2 = new Button("Button 2");

    public voidinit() {

        add(b1);

        add(b2);

    }

    public booleanaction(Event evt,Object arg){

        if (arg.equals("Button 1"))

            getAppletContext().showStatus("Button 1");

        else if (arg.equals("Button 2"))

            getAppletContext().showStatus("Button 2");

        // Let the base class handle it:

        else

            return super.action(evt, arg);

        return true; // We'vehandled it here

    }

} /// :~

很难确切知道equals()方法在这儿要做什么。这种方法有一个很大的问题,就是开始使用这个新技术的Java程序员至少需要花费一个受挫折的时期来在比较按钮上的文字时发现他们要么大写了要么写错了(我就有这种经验)。同样,如果我们改变了按钮上的文字,程序代码将不再工作(但我们不会得到任何编译时和运行时的信息)。所以如果可能,我们就得避免使用这种方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值