java基础技术提升篇:java AWT

新闻资讯 阅读(1742)

AWT

Java 1.1的一个显着变化是新AWT的创新。大多数更改都围绕着Java 1.1中使用的新事件模型:旧的事件模型是坏的,笨拙的,非面向对象的,并且新的事件模型可能是我见过的最好的。很难理解这样一个糟糕的(旧的AWT)和一个好的(新的事件模型)编程语言实际上来自同一个组。考虑事件的新方法似乎已经中止,因此争议不再成为障碍,因而很容易进入我们的意识;相反,它是一个帮助我们设计系统的工具。它也是Java Beans的精髓,我们将在本章后面介绍。

新方法设计对象用作“事件源”和“事件接收器”来替换旧的AWT的非面向对象的连接条件语句。正如我们将看到的,内部类的目的是将新事件集成到对象的原始状态中。此外,事件现在被描述为在类层次结构中替换单个类,我们可以创建自己的事件类型。

新事件模型

新事件模型中的组件可以启动事件。每种类型的事件都由一个单独的类描述。当事件开始时,它接受一个或多个指示“接收者”的事件。因此,事件源和处理事件的地址可以分开。

每个“接收器”是执行特定接收器类型接口的类对象。因此,作为程序开发人员,我们所要做的就是创建一个“接收器对象”并将其注册到被激活事件的组件中。事件触发组件调用addXXXListener()方法来完成注册以描述XXX事件类型接受。我们可以很容易地理解addListened名称的方法告诉我们可以处理任何事件类型。如果我们尝试接收事件,我们将在编译时发现错误。 Java Bean还使用addListener名称的这种方法来确定可以运行的程序。

我们所有的事件逻辑都将加载到接收器类中。创建接收器类时唯一的限制是我们必须实现专用接口。我们可以创建一个全局接收器类,这有助于在内部类中很好地使用,不仅因为它们为UI提供了理论上的接收器类集或它们所服务的业务逻辑类。但是因为事实是内部类维护了它的父句柄,所以它提供了一种通过类和子系统边界调用的好方法。

一个简单的例子可以清楚明确地说明这一点。还要考虑本章前面的Button2.java示例与此示例之间的区别。

//: Button2New.java

//按下捕获按钮

导入java.awt。*;

导入java.awt.event。*; //必须添加此

导入java.applet。*;

公共类Button2New扩展了Applet {

按钮

B1=新按钮('按钮1'),

B2=新按钮('按钮2');

Public void init(){

b1.addActionListener(new B1()); //b1是事件源新B1是接收器对象

b2.addActionListener(new B2()); //addXXXListener已注册到“事件组件”

添加(B1);

加入(B2);

}

B1类实现ActionListener {//接收器类

公共void actionPerformed(ActionEvent e){

getAppletContext()。showStatus('Button 1');

}

}

B2类实现了ActionListener {

公共void actionPerformed(ActionEvent e){

getAppletContext()。showStatus('Button 2');

}

}

/*旧AWT模式:

公共布尔动作(Event evt,Object arg){

如果(evt.target.equals(b1))//集中处理所有事件源

getAppletContext()。showStatus('Button 1');

否则if(evt.target.equals(b2))//发生了什么

getAppletContext()。showStatus('Button 2'); //如何处理

//让基类处理它:

其他

返回super.action(evt,arg);

回归真实; //我们在这里处理了

}

*/

} ///:~

我们可以比较两种方法,旧代码在左侧注释。在init()方法中,只有一个更改是添加以下两行:

b1.addActionListener(new B1());

b2.addActionListener(new B2());

按下该按钮时,将激活addActionListener()通知按钮对象。 B1和B2都是实现ActionListener接口的内部类。此接口包含单个方法actionPerformed()(这意味着将在激活事件时执行此操作)。请注意,actionPreformed()方法不是正常事件。更合适的是一种特殊类型的事件,ActionEvent。如果我们想要提取有关特定ActionEvent的信息,我们不需要刻意测试和深入查看建模参数。

重写事件actionPerformed()对于程序员来说非常简单。这是一种可以调用的方法。与旧的action()方法相比,旧的方法我们必须指出发生了什么和适当的行动。类似地,我们将担心调用基类action()的版本并返回一个值,指示它是否被处理。在新的事件模型中,我们知道所有事件测试推断都是自动发生的,因此我们不必弄清楚发生了什么;我们只是说发生了什么,它是自动完成的。如果我们没有提议用新方法来覆盖旧方法,我们会尽快提出。

在这里介绍程序和窗口应用程序。

程序:

程序的局限性,出于安全原因,程序非常有限,而且有很多我们做不到的事情。您通常会问:程序是什么样的,以及传闻要做的事情:在浏览器中扩展WEB页面的功能。自从我们成为网络冲浪者以来,我们从未真正想知道网页是否来自友好或不友好的网站,我们想要一些可以安全行动的代码。所以我们可能会注意到很多限制:

(1)程序片不能触及本地磁盘。这意味着您无法在本地磁盘上进行写入和读取。我们不希望程序通过WEB页面读取和传输重要信息。当然,写作是被禁止的,因为这会导致病毒入侵。当数字签名生效时,这些限制被取消。

(2)程序没有菜单。 (注意:这在Swing中指定)这可以减少安全性和简化程序的麻烦。作为WEB页面的一部分,我们可能会收到有关该计划协调利益的通知;我们通常不注意该计划的范围。菜单中没有弹出框架和标题栏,结果框架和标题栏属于WEB浏览器。也许将来可以更改设计,以便我们将浏览器菜单与程序切片菜单相结合。程序会影响其环境,这将危及整个系统的安全性并使程序过于复杂。

(3)对话框不受信任。在Java中,有一些难以理解的对话框。首先,他们无法正确拒绝该计划,这实在令人沮丧。如果我们从程序中弹出一个对话框,我们将在对话框中看到一个附加的消息框“Untrusted Programs”。这是因为,理论上,有可能诱使用户认为他们通过WEB与同一旧客户的本地应用程序进行交易并要求他们输入他们的信用卡号。在看到AWT开发的GUI之后,我们可能会相信任何人都会被这种方法所迷惑。但是程序总是附加到Web页面,并且可以在浏览器中看到,并且对话框没有这种依赖性,因此理论上是可行的。因此,我们很少看到使用对话框的程序。

在较新的浏览器中,对受信任的程序放宽了许多限制(受信任的程序由受信任的源进行身份验证)。

当涉及到程序的开发时,还有其他问题需要考虑:

■程序不断从不同类别的单独服务器下载。我们的浏览器能够缓存程序,但这并不能保证。Java版本1.1的一个改进是JAR(Java存档)文件,它允许所有的程序组件(包括其他类文件、图像、声音)打包成一个可以由单个服务器下载和处理的单个压缩文件。数字签名(验证类创建者的能力)可以有效地添加到每个单独的JAR文件中。

由于安全原因,我们更难完成某些任务,例如访问数据库和发送电子邮件。此外,安全限制规则使得访问多个主机非常困难,因为所有内容都必须通过Web服务器路由,从而造成性能瓶颈,并且单个链接错误将导致整个进程停止。

■浏览器中的程序与本机应用程序运行的控件类型不同。例如,由于用户可以切换页面,所以程序中没有正式的对话框。当用户更改网页或退出浏览器时,对我们的程序来说是一场灾难。无法保存状态,因此如果我们正在处理和操作,信息将丢失。此外,当我们离开一个网页时,不同的浏览器会对我们的程序执行不同的操作,因此结果本身是不确定的。

项目的优势

如果您能够容忍这些限制,那么这个程序的一些优势也非常突出,特别是当我们构建客户机/服务器应用程序或其他Web应用程序时:

■安装没有争议。该程序具有真正的平台独立性(包括轻松播放声音文件的能力),因此我们不需要修改不同平台的代码,也不需要任何人根据安装运行任何“调整”。实际上,安装每次都会自动将WEB页面与程序块一起发布,因此可以安静地自动更新。在传统的客户端/服务器系统中,构建和安装新版本的客户端软件是一场噩梦。

■出于安全原因,在核心Java语言和程序片结构中创建,我们不必担心错误的代码并导致某人破坏系统。通过这种方式,与以前的优点一起,您可以使用Java(可以从JavaScript和VBScript中选择客户端WEB编程工具)来开发所谓的Intrant的应用程序(内部网,供公司内部使用而无需转移到互联网)客户/服务器。

■由于程序自动与HTML集成,因此我们有一个内置的独立平台文件系统来支持该程序。这是一种非常有趣的方法,因为我们习惯于拥有程序文件的一部分而不是相反的文件系统。

窗口应用程序

出于安全原因,我们将看到我们的行为在程序中非常有限。我们真的觉得这个程序是临时添加到Web浏览器中的,所以它的功能以及相关知识必须受到限制。然而,我们希望Java可以创建一个窗口程序来运行某些东西,否则它将被放置在一个网页上,也许我们希望它运行一些可靠的应用程序,以及夸大的实时可移植性。在本书的前几章中,我们创建了一些命令行应用程序,但在某些操作环境(例如Macintosh)中,没有命令行。因此,我们有很多理由使用Java来创建一个安装窗口,而不是一个程序。这当然是一个非常合理的要求。

Java设置窗口应用程序可以有菜单和对话框(对于单个程序来说这是不可能的和困难的),但是如果我们使用旧版本的Java,我们将牺牲本地操作系统环境的外观。还有感觉。JFC/Swing库允许我们创建一个保持原始操作系统环境外观的应用程序。如果我们想构建一个安装窗口应用程序,它是合理的。同样,如果我们可以使用最新版本的Java并收集所有的工具,我们可以发布不迷惑用户的应用程序。如果由于某种原因,我们不得不使用旧版本的Java,请在销毁应用程序之前仔细考虑,以创建一个重要的安装窗口。

用Java 1.1 AWT

制作Windows和程序

我们经常需要创建一个可以作为窗口或程序片调用的类。要做到这一点,只需在程序中添加一个main()即可在Frame中构建程序实例。作为一个简单的例子,让我们看一下如何对Button2New.java进行更改,以便它既可以用作应用程序,也可以用作程序:

//: Button2NewB.java

//应用程序和小程序

导入java.awt。*;

导入java.awt.event。*; //必须添加此

导入java.applet。*;

公共类Button2NewB扩展了Applet {//程序

按钮

B1=新按钮('按钮1'),

B2=新按钮('按钮2');

TextField t=new TextField(20);

Public void init(){

b1.addActionListener(new B1());

b2.addActionListener(new B2());

添加(B1);

加入(B2);

添加(T);

}

B1类实现了ActionListener {

公共void actionPerformed(ActionEvent e){

t.setText('Button 1');

}

}

B2类实现了ActionListener {

公共void actionPerformed(ActionEvent e){

t.setText('Button 2');

}

}

//关闭应用程序:

静态类WL扩展WindowAdapter {

公共void windowClosing(WindowEvent e){

System.exit(0);

}

}

//应用程序:的main()

Public static void main(String [] args){//Windows Application

Button2NewB applet=new Button2NewB();

帧aFrame=新帧('Button2NewB');

aFrame.addWindowListener(new WL());

aFrame.add(applet,BorderLayout.CENTER);

aFrame.setSize();

Applet.init();

Applet.start();

aFrame.setVisible(真);

}

} ///:~

内部类WL和main()方法是添加到程序切片的唯一两个元素,而程序切片的其余部分保持不变。实际上,我们通常将WL类和main()方法复制并粘贴到我们自己的程序中(请记住,在创建内部类时,通常需要一个外部类来处理它,静态地形成它消除这种需要)。我们可以看到在main()方法中,程序被显式初始化并启动,因为在这个例子中,浏览器无法为我们有效地运行它。当然,这不会为stop()和destroy()提供完整的浏览器调用,但在大多数情况下都可以接受。如果它变得很麻烦,我们可以:

(1)使程序处理一个静态类(而不是局部变量main()),然后:

(2)在调用System.exit()之前,在WindowAdapter.windowClosing()中调用applet.stop()和applet.destroy()。

注意最后一行:

aFrame.setVisible(真);

这是Java 1.1 AWT的变化。不再支持show()方法,setVisible(true)替换show()方法。当我们在本章后面学习Java Bean时,这些看似易于改变的方法将变得更加合理。

此示例也使用TextField进行修改,而不是显示到控制台或浏览器状态行。开发程序时的一个限制是程序和应用程序都必须根据其操作选择输入和输出结构。

以下是Java 1.1 AWT的其他小功能。我们不再需要使用错误的方法来使用字符串指定BorderLayout的布局。当我们将一个元素添加到BorderLayout的Java 1.1版本时,我们可以写:

aFrame.add(applet,BorderLayout.CENTER);

我们为该位置指定一个BorderLayout常量,以便可以在编译时验证它(而不是静静地为旧结构做不适当的事情)。这是一项重大改进,将在本书的其余部分广泛使用。

将窗口接收器变为匿名类

任何接收器类都可以作为匿名类执行,但这一直是一个意外,也就是说,我们可能需要在其他情况下使用它们的功能。但是,窗口接收器仅在此处用作关闭应用程序窗口,因此我们可以安全地创建匿名类。然后,main()中的以下代码行:

aFrame.addWindowListener(new WL());

将成为:

aFrame.addWindowListener(new WindowAdapter(){//创建一个匿名类接收器对象,aFrame是事件源

公共void windowClosing(WindowEvent e){

System.exit(0);

}

});

这样做的一个优点是它不需要其他类名。我们必须判断自己是否使代码更容易理解或更难。但是,对于本书的其余部分,匿名内部类通常用于窗口接收器。

将程序封装到JAR文件中

一个重要的JAR应用程序是完成程序的加载。在Java 1.0中,人们倾向于尝试将他们的代码填充到单个程序类中,因此客户只需要一台服务器来下载程序代码。但这不仅使得结果凌乱,而且很难读取(当然也是维护)程序,但是类文件还没有被压缩,所以下载速度从未如此之快。

JAR文件将所有压缩类文件打包到一个文件中,并由浏览器下载。现在我们不需要创建一个糟糕的设计来最小化我们创建的类,并且用户将获得更快的下载。

想想上面的例子。这个例子看起来像Button2NewB,它是一个单独的类,但实际上它包含三个内部类,所以有四个。每当我们编译程序时,我都会使用这行代码将它打包成一个JAR文件:

Jar CF Button2NewB.jar * .class

这假定当前目录中只有一个类文件,其中一个来自Button2NewB。 Java(否则我们将得到一个特殊的包)。

现在我们可以使用新的文件标签创建一个指定JAR文件的HTML页面,如下所示:

按钮2 NewB示例小程序

Archive='Button2NewB.jar'

宽度=200高度=150>

与HTML文件中的切片标签相关的任何其他内容保持不变。