javaGUI学习23:AWT-Component类

1、构件

在AWT 1.1中,所有的标准AWT构件都是重量构件,即每个构件在本地不透明的窗口中显示。虽然AWT1.1为开发轻量自定义构件°提供框架,但是它不能提供任何特定的轻量构件。所有存在的重量构件的轻量版本将在以后的 AWT版本中提供。
所有的标准AWT构件都具有本地的、依赖于平台的同位体,做许多幕后的工作。实现基于同位体的设计,能使AWT的原来开发者迅速地开发用户界面工具,该用户界面工具跨平台保留本地外观。但是,即使大多数开发者都不直接处理同位体,当使用AWT开发用户界面时,同位体方法仍然引起许多困难。构件的Swing集提供重量AWT构件的无同位体的版本给开发者,这样可以开发者不采用基于同位体的方法。

构件 超类 描述
Button Component 触发行为的文本按钮
Canvas Component 绘制图形的画布
Checkbox Component 可检验的布尔构件
Choice Component 文本输入的弹出菜单
Dialog Window 可模式化窗口
Filedialog Dialog 选择文件的相关平台对话框
Frame Window 具有标题栏和可选菜单的顶层窗口
Label Component 显示字符串的构件
List Component 文本输入的可滚动列表
List Container 一般构件容器
Panel Component 滚动项目的adjustable构件
Scrollbar Container 可滚动容器
Scrollpane TextComponent 多行可滚动的文本框
Textarea Component TextArea和TextField的基本功能
TextComponent TextComponent 输入文本的单行构件
Window Container 没有标题的无边界窗口

2、java.awt.Component

每个AWT构件最终都是 java.awt.Component类的一个扩展。java.awt .Component是一个抽象类,它封装了AWT构件的通用功能。实际上,有很多的功能被嵌人到Component类中,以致于它可以至少提供120种公共方法。我们不逐个讨论每种方法,而是把焦点集中在常见的可能处理的构件基本特征上。

3、构件的属性

属性 方法
背景颜色 void setBackground ( Color)
Color getBackground
边界 void oetBounds ( Rectangle)
void setBounds ( int,int,int,int)
Rectangle getBounds ()
光标 void setCursor ( Cursor)
Cursor getCursor ()
拖放目标 void setDropTarget ( DropTarget )
DropTarget getDropTarget ()
使能 void setEnabled (boolean)
boolean isEnabled ()
字体 void setFont ()
Font getFont ()
前景颜色 void setForeground ( Color)
Color getForeground ()
地区 void setLocale ( Locale)
Locale getLocale ()
位置 void setLocation (Point)
void setLocation (int,int)
Point getLocation ()
Point getlocationOnScrcen ()
名称 void setName ()
String getNane ()
尺寸 void setSize ( Dimension)
Dimension getSize ( )
可见性 void setVisible ( boolean)
boolean isVisible ()

4、不赞成的方法

不支持的方法带有deprecation选项。详细查询javaAPI或者《java2图形设计卷1:AWT》

5、构件的位置,边界和坐标

构件的位置是相对于它的容器的,但是它的边界表示构件的真实像素宽度和高度。如果希望找出构件的实际屏幕坐标,使用AWT1.1版本中引人的新方法:

Point java . awt.Component . getLocationOnScreen ()

构件方法中使用的坐标是相对于构件的左上角的。例如,如果希望在画布上画-一-个矩形,并规定矩形的位置为(10,10),那么矩形左上角将定位在画布的左上角向下向右各10个像素的地方。

6、构件的首选、最小和最大尺寸

构件可以通过分别覆盖getPreferredSize ()、getMinimumSize ()和getMaximumSize ())规定它们的首选、最小和最大尺寸。
上面列出的覆盖方法不能保证构件的尺寸。这些方法只不过是指导方针,可能被设置构件尺寸的对象—布局管理器忽略。

7、构件的可见性和响应

除了框架、窗口和对话框以外的所有构件都是默认可见的。可以使用java. awt.Component的 setVisible方法设置单个构件的可见性。如果需要切换一组构件的可见性,应该考虑使用CardLayout布局管理器代替单独管理每个构件的可见性。
也可以通过调用setEnabled方法,分别传递true或false,以允许或禁止构件对用户的输入做出响应。当构件不允许进行响应时,应提供与平台相关的视觉反馈。

8、构件和同位体

对于大部分开发者而言,不需要直接处理同位体。但是,如果在构件的同位体建立以前调用Component方法,那么一些Component方法的执行将不同。
同位体在构件的addNotify方法中建立。如果必须在构件的同位体建立以前调用下面的方法,那么基本上有两种选择。可以直接调用addNotify(),这样可能导致构件同位体的建立;或覆盖addNotify(),并且在调用super. addNotify ()以后调用依赖同位体的方法。

方法 在同位体建立以前的行为表现
Image createImage ( int,int) 返回null
ColorModel getColorModel ) 返回工具箱的颜色模式——不是构件的
Font getFont () 返回null
FontMetrics getFontMetrics () 返回工具箱的字体尺度-—不是构件的
Graphics getGraphics () 返回null
Insets getInsets () 返回空白区(0,0,0,0)
Dimension getPreferredSize ( ) 返回最小尺寸——不是首选尺寸
Dimension getMinimumSize ( ) 返回getSize ()的值
Dimension getSize ( ) 如果构件被明确规定尺寸,则返回它的大小;否贝个零宽度和高度的 Dimension
Toolkit getToolkit() 返回默认的工具箱—–不是构件的
boolean isFocusTraversable () 返回false
boolean isValid () 返回false
boolean icShowing () 返回false
Point getLocationOnScreen () 抛出IllegalComponentSateException异常
void requestFocus () 空操作

同位体的前景:
构件的Swing集为AWT重量构件提供无同位体的代替。虽然同位体方法可跨平台保留本地化外观,但是相对于所能解决的问题,同位体通常导致更多的问题。

9、显示构件

在paint (Craphics)方法中显示构件时,一般是在下面的两种环境中进行调用:

  • 产生一个系统绘制或更新事件。
  • 显式调用repaint ()。

只要构件所在窗口的处理结果需要重绘构件,那么就会产生系统绘制和更新事件。例如,如果一个applet窗口被另一个窗口覆盖,随后又被移到前面,那么产生一个PaintEvent事件并把它传给需要重绘的applet中的构件。
当更新构件的图形表示时,repaint ()经常被显式调用,有时是构件自己调用。
在构件的同位体中, repaint()的所有重载版本都调用paint 方法。如果重绘的构件是轻量构件,则沿着构件的容器层次调用直到发现重量容器为止,并且调用容器同位体的paint 方法。

void repaint() //尽可能快的调用update()
void repaint(int x, int y, int width, int height) //尽可能快的调用update(),只重绘指定矩形的构件
void repaint() //尽可能快的调用update()
void repaint() //尽可能快的调用update(),只重绘指定矩形内的构件

调用同位体的repaint方法最终导致对构件的update方法的访问。那么对repaint () 的访问将引起下面一系列访问:

repaint() -> peer. repaint() -> update ()-> paint()

Component . update清除重量构件的背景,随后调用构件的paint方法。如果重量构件需要连续地更新——例如,一个可滚动的窗口或动画画布——那么应该覆盖update ()以简单地调用paint ( )。取消构件的清除可以减少闪烁。
一个应该提及的警告是关于覆盖update ()以调用paint ()的。如果一个本地窗口系统的绘制事件调用update (),那么很可能不管如何实现update (),窗口系统都将清除构件的背景。例如,如果构件为避免清除背景而覆盖它的 update方法,那么显式调用repaint () (和由此导致的最终调用update ())将重绘构件而不用清除背景。但是,如果构件所在的窗口1被覆盖,然后再次出现在前面,那么本地窗口系统可能在调用update ()以前清除窗口的背景。

ps:

覆盖update()以避免闪烁
Component . update ()首先清除构件的背景(如果它是重量构件),然后调用paint()方法。如果重量构件被repaint ()更新并将最终导致对update ()的访问,则可能引起闪烁。为减少和清除背景有关的闪烁,覆盖update ()以调用paint () 可以不用清除构件的背景。

10、构件和zorder

在初始版本的AWT中,没有构件深度或zorder(三维坐标系,z轴代表第三维)的概念。在AWT 1.1中,zorder的定义是构件从前向后加入到容器中的顺序。第一个加人到容器中的构件是最前面的构件,而最后一个加入到容器中的构件将显示在容器中的所有其他构件的后面。

11、构件和光标

在AWT中,支持设置构件光标的能力。为了设置构件的光标,传递Cursor 的实例给构件的 selCoursor方法。Cursor类具有一组预先定义的光标,可以通过调用Cursor .getPredefinedCursor(讲行访问。下面列出的整数常数代表这些预定义光标。

Cursor类字段:

static int CROSSHAIR_CURSOR //十字光标类型。  
static int CUSTOM_CURSOR //与所有自定义游标关联的类型。  
static int DEFAULT_CURSOR //默认光标类型(如果未定义光标,则设置)。  
static int E_RESIZE_CURSOR //东调整大小的游标类型。  
static int HAND_CURSOR //手形光标类型。  
static int MOVE_CURSOR //移动光标类型。  
static int N_RESIZE_CURSOR //北调整大小的游标类型。  
protected String name //用户可见的光标名称。  
static int NE_RESIZE_CURSOR //东北调整大小的游标类型。  
static int NW_RESIZE_CURSOR //西北调整大小的游标类型。  
protected static Cursor[] predefined //已过时。 从JDK 1.7版开始,应该使用getPredefinedCursor(int)方法。  
static int S_RESIZE_CURSOR //南调整大小的游标类型。  
static int SE_RESIZE_CURSOR //东南调整大小的游标类型。  
static int SW_RESIZE_CURSOR //西南调整大小的游标类型。  
static int TEXT_CURSOR //文本光标类型。  
static int W_RESIZE_CURSOR //西方调整大小的游标类型。  
static int WAIT_CURSOR //等待光标类型。 

方法:

static Cursor getDefaultCursor() //返回系统默认光标。  
String getName() //返回此游标的名称。  
static Cursor getPredefinedCursor(int type) //返回具有指定预定义类型的游标对象。  
static Cursor getSystemCustomCursor(String name) 返回与指定名称匹配的特定于系统的自定义游标对象。  
int getType() //返回此游标的类型。  
String toString() //返回此游标的字符串表示形式。  

12、构件和串行化

AWT构件为串行化提供内部支持。实际上,很多语句都是Java语言为支持串行化而提供的,AWT构件可以利用这种支持的。AWT为串行化和构件有关的事件监听者提供额外的支持。

例如:开始时包含一个按钮。当激活该按钮时,按钮的监听者串行化按钮并写入一个文件中。接着,监听者从文件中读出串行化按钮,并产生一-个新按钮添加到框架中。

ps:

如果希望监听者和它们的构件一起被串行化,让监听者实现 java. io.Se-rializable
如果希望串行化和构件相关联的监听者,那么必须确保监听者实现 java. io. Seri-alizable。所有的AWT构件自身都实现串行化接口,因此扩展AWT构件的自定义构件不需要显式实现串行化接口。但是,既然监听者默认的是不需要执行串行化,那么如果希望构件的监听者和构件一起被串行化,就必须人为地进行处理。

13、构件和国际化

13.1 Locale

Locale是表示指定地理、政治或文化区域的标志。java. util . Locale类提供许多公共Locale实例。

它们仅仅是一个标志符——没有其他任何意义。例如,可以设置文本框的Locale为Locale . French。

ToxtField . field = new TextField ( );
field . setLocale (Locale . FRENCH);

但是,这并不意味着文本框将用法文显示它的文本。而是我们已经将文本框标识为一个应该用法文显示其文本的构件。确保它的文本用法文显示不是文本框的职责——-这个职责留给了其他人,即需要你去管理。国际化讨论的其余部分将集中在这个职责上。

13.2 资源包

资源包(resource bundie〉含有可以在运行时加载的特定地区数据。例如,在资源包中,包含一对关键字/值。

所有的资源包(最终来自java. util . ResourceBundle的类)都包含关键字/值对,关键字标志特定地区对象。

13.3 资源包属性

为替代实现资源包类,资源可以在一个属性文件中被规定。属性文件具有. properties扩展名并包含关键字/值对。例如,下面的属性文件LabelsBundle _ en . properties可以替代 IabelsBun-dle __ en类:

Simplel8N English Property Bundle
ldentifier = English Gul

属性文件中以#开始的行被认为是注释行,可以被忽略。同样,IabelsBundle _ fr. properties文件可以替代IabelsBundle _ fr类:

#Simplel18N French Property Bundle
Identifier = Gul en Francais

当查找资源包时,如果没有在当前CLASSPATH 找到.class 文件,那么查找带有.properties扩展名的同名属性文件。如果找到属性文件,则实例化PropertyresourceBundle并且从Resource-Bundle.getBundle ()的调用中返回。PropertyresourceBundle是 ResourceBundle 的扩展,这意味着可以调用它的getObject方法获得一个和标志符相关的对象。
因此,可以不实现资源包类,而使用属性文件规定相关地区字符串。

13.4 从国际化代码中分离出GUI

如果希望提供一个意大利版本的GUI,只需要实现返回意大利版本标志符的IabelsBundle _ it类,并确保LabelsBundle _ it所位于的.class 文件在当前CLASSPATH中。

13.5 可用地区和两个字符的编码

Locale .

CANADA 适用于国家的常数。  //CA
CANADA_FRENCH 适用于国家的常数。  
CHINA 适用于国家的常数。  //CN
CHINESE 有用的语言常量。  //zh
ENGLISH 有用的语言常量。  //en
FRANCE 适用于国家的常数。  //FR
FRENCH 有用的语言常量。  //fr
GERMAN 有用的语言常量。  //de
GERMANY 适用于国家的常数。  //DE
ITALIAN 有用的语言常量。  //it
ITALY 适用于国家的常数。  //IT
JAPAN 适用于国家的常数。  //JP
JAPANESE 有用的语言常量。  //jp
KOREA 适用于国家的常数。  //KP
KOREAN 有用的语言常量。  //ko
PRC 适用于国家的常数。  
SIMPLIFIED_CHINESE 有用的语言常量。  
* 适用于国家的常数。  //TW
TRADITIONAL_CHINESE 有用的语言常量。  
UK 适用于国家的常数。   //UK
US 适用于国家的常数。  //US

14、约束属性

约束属性(bound property)是当它们的值改变时会引起通知的属性。通知采用PropertyChangeEvent格式,把 PropertyChangeEvent传送给已经注册对这种属性变化感兴趣的 PropertyChangeListener的一个列表处理,使用术语“约束属性”是因为一个约束属性的改变,和一组被通知属性改变的 PropertyChangeListener相关。

public void addPropertyChangeListener( PropertyChangeListener )//向构件维护的监听者列表注册指定的 PropertyChangeListener
public void rernovePropertyChangeListener ( PropertyChangeListener)//从构件维护的监听者列表中删去指定的PropertyChange-L.istener

public void assPropertyChangeListener ( String,PropertyCahngeListener)//为命名属性注册指定的PropertyChangeListener

public void removePropertyChangelistener ( String,PropertyChangeListener)//从和命名属性有关的监听者列表中删去指定的PropertyChangelistener
protected void firePropertyChange ( String,Object oldValue,Object newValue)//为具有指定旧值和新值的命名属性,激发一个属性改变到适当的 PropertyChangelistener

java. beans.PropertyChangeListener是一个简单的接口,只定义了一个方法:

propertyChange ( PropertyChangeEvent e)

PropertyChangeListener可以向整个构件注册。当改变构件的任何约束属性值时,调用监听者的 propertyChange方法。
另外,可以向某个属性注册 PropertyChangeListener,只有当具有适当名称的属性改变时,才通知 PropertyChangeListener。
除了为实现约束属性提供基本结构以外,也约束下列和java.awt.Component有关的属性:

  • 字体。
  • 前景颜色。
  • 背景颜色。

自定义构件属性约束,查阅《java2图形卷1:AWT》

15、构件和树锁定

Component类实例化一个static final Object。这个对象称为树锁定( tree lock),可以用来同步访问构件的容器层次结构和布局方法。阻止两个线程同时访问一个构件的容器层次结构(和布局方法)的思想可能会引起没有同步的访问方法处于不相容状态。

上一篇:javaGUI学习26:AWT-文本构件


下一篇:JavaGUI练习 - 正交测试用例生成小工具