友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第75部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
aFrame。add(applet; BorderLayout。CENTER);
aFrame。setSize(300;200);
applet。init();
applet。start();
aFrame。setVisible(true);
}
} ///:~
ILCheck拥有当我们增加或者减少复选框时自动调整的优点。当然,我们对单选钮使用这种方法也同样的
好。但是,它仅当我们的逻辑足以普遍的支持这种方法时才会被使用。如果声明一个确定的信号——我们将
重复利用独立的接收器类,否则我们将结束一串条件语句。
4。 下拉列表
下拉列表在 Java 1。1 版中当一个选择被改变时同样使用 ItemListener去告知我们:
//: ChoiceNew。java
// Drop…down lists with Java 1。1
import java。awt。*;
import java。awt。event。*;
import java。applet。*;
public class ChoiceNew extends Applet {
String'' description = { 〃Ebullient〃; 〃Obtuse〃;
〃Recalcitrant〃; 〃Brilliant〃; 〃Somnescent〃;
〃Timorous〃; 〃Florid〃; 〃Putrescent〃 };
421
…………………………………………………………Page 423……………………………………………………………
TextField t = new TextField(100);
Choice c = new Choice();
Button b = new Button(〃Add items〃);
int count = 0;
public void init() {
t。setEditable(false);
for(int i = 0; i 《 4; i++)
c。addItem(description'count++');
add(t);
add(c);
add(b);
c。addItemListener(new CL());
b。addActionListener(new BL());
}
class CL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
t。setText(〃index: 〃 + c。getSelectedIndex()
+ 〃 〃 + e。toString());
}
}
class BL implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(count 《 description。length)
c。addItem(description'count++');
}
}
public static void main(String'' args) {
ChoiceNew applet = new ChoiceNew();
Frame aFrame = new Frame(〃ChoiceNew〃);
aFrame。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
aFrame。add(applet; BorderLayout。CENTER);
aFrame。setSize(750;100);
applet。init();
applet。start();
aFrame。setVisible(true);
}
} ///:~
这个程序中没什么特别新颖的东西(除了 Java 1。1 版的UI 类里少数几个值得关注的缺陷)。
5。 列表
我们消除了 Java 1。0 中List 设计的一个缺陷,就是 List 不能像我们希望的那样工作:它会与单击在一个列
表元素上发生冲突。
//: ListNew。java
// Java 1。1 Lists are easier to use
import java。awt。*;
422
…………………………………………………………Page 424……………………………………………………………
import java。awt。event。*;
import java。applet。*;
public class ListNew extends Applet {
String'' flavors = { 〃Chocolate〃; 〃Strawberry〃;
〃Vanilla Fudge Swirl〃; 〃Mint Chip〃;
〃Mocha Almond Fudge〃; 〃Rum Raisin〃;
〃Praline Cream〃; 〃Mud Pie〃 };
// Show 6 items; allow multiple selection:
List lst = new List(6; true);
TextArea t = new TextArea(flavors。length; 30);
Button b = new Button(〃test〃);
int count = 0;
public void init() {
t。setEditable(false);
for(int i = 0; i 《 4; i++)
lst。addItem(flavors'count++');
add(t);
add(lst);
add(b);
lst。addItemListener(new LL());
b。addActionListener(new BL());
}
class LL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
t。setText(〃〃);
String'' items = lst。getSelectedItems();
for(int i = 0; i 《 items。length; i++)
t。append(items'i' + 〃n〃);
}
}
class BL implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(count 《 flavors。length)
lst。addItem(flavors'count++'; 0);
}
}
public static void main(String'' args) {
ListNew applet = new ListNew();
Frame aFrame = new Frame(〃ListNew〃);
aFrame。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
aFrame。add(applet; BorderLayout。CENTER);
aFrame。setSize(300;200);
applet。init();
applet。start();
aFrame。setVisible(true);
}
423
…………………………………………………………Page 425……………………………………………………………
} ///:~
我们可以注意到在列表项中无需特别的逻辑需要去支持一个单击动作。我们正好像我们在其它地方所做的那
样附加上一个接收器。
6。 菜单
为菜单处理事件看起来受益于 Java 1。1 版的事件模型,但 Java 生成菜单的方法常常麻烦并且需要一些手工
编写代码。生成菜单的正确方法看起来像资源而不是一些代码。请牢牢记住编程工具会广泛地为我们处理创
建的菜单,因此这可以减少我们的痛苦(只要它们会同样处理维护任务!)。另外,我们将发现菜单不支持
并且将导致混乱的事件:菜单项使用ActionListeners (动作接收器),但复选框菜单项使用 ItemListeners
(项目接收器)。菜单对象同样能支持ActionListeners (动作接收器),但通常不那么有用。一般来说,
我们会附加接收器到每个菜单项或复选框菜单项,但下面的例子(对先前例子的修改)演示了一个联合捕捉
多个菜单组件到一个单独的接收器类的方法。正像我们将看到的,它或许不值得为这而激烈地争论。
//: MenuNew。java
// Menus in Java 1。1
import java。awt。*;
import java。awt。event。*;
public class MenuNew extends Frame {
String'' flavors = { 〃Chocolate〃; 〃Strawberry〃;
〃Vanilla Fudge Swirl〃; 〃Mint Chip〃;
〃Mocha Almond Fudge〃; 〃Rum Raisin〃;
〃Praline Cream〃; 〃Mud Pie〃 };
TextField t = new TextField(〃No flavor〃; 30);
MenuBar mb1 = new MenuBar();
Menu f = new Menu(〃File〃);
Menu m = new Menu(〃Flavors〃);
Menu s = new Menu(〃Safety〃);
// Alternative approach:
CheckboxMenuItem'' safety = {
new CheckboxMenuItem(〃Guard〃);
new CheckboxMenuItem(〃Hide〃)
};
MenuItem'' file = {
// No menu shortcut:
new MenuItem(〃Open〃);
// Adding a menu shortcut is very simple:
new MenuItem(〃Exit〃;
new MenuShortcut(KeyEvent。VK_E))
};
// A second menu bar to swap to:
MenuBar mb2 = new MenuBar();
Menu fooBar = new Menu(〃fooBar〃);
MenuItem'' other = {
new MenuItem(〃Foo〃);
new MenuItem(〃Bar〃);
new MenuItem(〃Baz〃);
};
// Initialization code:
{
ML ml = new ML();
424
…………………………………………………………Page 426……………………………………………………………
CMIL cmil = new CMIL();
safety'0'。setActionmand(〃Guard〃);
safety'0'。addItemListener(cmil);
safety'1'。setActionmand(〃Hide〃);
safety'1'。addItemListener(cmil);
file'0'。setActionmand(〃Open〃);
file'0'。addActionListener(ml);
file'1'。setActionmand(〃Exit〃);
file'1'。addActionListener(ml);
other'0'。addActionListener(new FooL());
other'1'。addActionListener(new BarL());
other'2'。addActionListener(new BazL());
}
Button b = new Button(〃Swap Menus〃);
public MenuNew() {
FL fl = new FL();
for(int i = 0; i 《 flavors。length; i++) {
MenuItem mi = new MenuItem(flavors'i');
mi。addActionListener(fl);
m。add(mi);
// Add separators at intervals:
if((i+1) % 3 == 0)
m。addSeparator();
}
for(int i = 0; i 《 safety。length; i++)
s。add(safety'i');
f。add(s);
for(int i = 0; i 《 file。length; i++)
f。add(file'i');
mb1。add(f);
mb1。add(m);
setMenuBar(mb1);
t。setEditable(false);
add(t; BorderLayout。CENTER);
// Set up the system for swapping menus:
b。addActionListener(new BL());
add(b; BorderLayout。NORTH);
for(int i = 0; i 《 other。length; i++)
fooBar。add(other'i');
mb2。add(fooBar);
}
class BL implements ActionListener {
public void actionPerformed(ActionEvent e) {
MenuBar m = getMenuBar();
if(m == mb1) setMenuBar(mb2);
else if (m == mb2) setMenuBar(mb1);
}
}
class ML implements ActionListener {
public void actionPerformed(ActionEvent e) {
MenuItem target = (MenuItem)e。getSource();
String actionmand =
425
…………………………………………………………Page 427……………………………………………………………
target。getActionmand();
if(actionmand。equals(〃Open〃)) {
String s = t。getText();
boolean chosen = false;
for(int i = 0; i 《 flavors。length; i++)
if(s。equals(flavors'i')) chosen = true;
if(!chosen)
t。setText(〃Choose a flavor first!〃);
else
t。setText(〃Opening 〃+ s +〃。 Mmm; mm!〃);
} else if(actionmand。equals(〃Exit〃)) {
dispatchEvent(
new WindowEvent(MenuNew。this;
WindowEvent。WINDOW_CLOSING));
}
}
}
class FL implements ActionListener {
public void actionPerformed(ActionEvent e) {
MenuItem target = (MenuItem)e。getSource();
t。setText(target。getLabel());
}
}
// Alternatively; you can create a different
// class for each different MenuItem。 Then you
// Don't have to figure out which one it is:
class FooL implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Foo selected〃);
}
}
class BarL implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Bar selected〃);
}
}
class BazL implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Baz selected〃);
}
}
class CMIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
CheckboxMenuItem target =
(CheckboxMenuItem)e。getSource();
String actionmand =
target。getActionmand();
if(actionmand。equals(〃Guard〃))
t。setText(〃Guard the Ice Cream! 〃 +
〃Guarding is 〃 + target。getState());
else if(actionmand。equals(〃Hide〃))
t。setText(〃Hide the Ice Cream! 〃 +
426
…………………………………………………………Page 428……………………………………………………………
〃Is it cold? 〃 + target。getState());
}
}
public static void main(String'' args) {
MenuNew f = new MenuNew();
f。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
f。setSize(300;200);
f。setVisible(true);
}
} ///:~
在我们开始初始化节(由注解“Initialization code:”后的右大括号指明)的前面部分的代码同先前
(Java 1。0 版)版本相同。这里我们可以注意到项目接收器和动作接收器被附加在不同的菜单组件上。
Java 1。1 支持“菜单快捷键”,因此我们可以选择一个菜单项目利用键盘替代鼠标。这十分的简单;我们只
要使用过载菜单项构建器设置第二个自变量为一个 MenuShortcut (菜单快捷键事件)对象即可。菜单快捷键
构建器设置重要的方法,当它按下时不可思议地显示在菜单项上。上面的例子增加了 Control…E 到“Exit ”
菜单项中。
我们同样会注意 setActionmand()的使用。这看似一点陌生因为在各种情况下“action mand”完全同
菜单组件上的标签一样。为什么不正好使用标签代替可选择的字符串呢?这个难题是国际化的。如果我们重
新用其它语言写这个程序,我们只需要改变菜单中的标签,并不审查代码中可能包含新错误的所有逻辑。因
此使这对检查文字字符串联合菜单组件的代码而言变得简单容易,当菜单标签能改变时“动作指令”可以不
作任何的改变。所有这些代码同“动作指令”一同工作,因此它不会受改变菜单标签的影响。注意在这个程
序中,不是所有的菜单组件都被它们的动作指令所审查,因此这些组件都没有它们的动作指令集。
大多数的构建器同前面的一样,将几个调用的异常增加到接收器中。大量的工作发生在接收器里。在前面例
子的BL 中,菜单交替发生。在ML 中,“寻找ring ”方法被作为动作事件(ActionEvent)的资源并对它进
行造型送入菜单项,然后得到动作指令字符串,再通过它去贯穿串联组,当然条件是对它进行声明。这些大
多数同前面的一样,但请注意如果“Exit ”被选中,通过进入封装类对象的句柄(MenuNew。this)并创建一
个WINDOW_CLOSING 事件,一个新的窗口事件就被创建了。新的事件被分配到封装类对象的dispatchEvent()
方法,然后结束调用windowsClosing() 内部帧的窗口接收器(这个接收器作为一个内部类被创建在main()
里),似乎这是“正常”产生消息的方法。通过这种机制,我们可以在任何情况下迅速处理任何的信息,因
此,它非常的强大。
FL 接收器是很简单尽管它能处理特殊菜单的所有不同的特色。如果我们的逻辑十分的简单明了,这种方法对
我们就很有用处,但通常,我们使用这种方法时需要与FooL,BarL 和BazL 一道使用,它们每个都附加到一
个单独的菜单组件上,因此必然无需测试逻辑,并且使我们正确地辨识出谁调用了接收器。这种方法产生了
大量的类,内部代码趋向于变得小巧和处理起来简单、安全。
7。 对话框
在这个例子里直接重写了早期的ToeTest。java 程序。在这个新的版本里,任何事件都被安放进一个内部类
中。虽然这完全消除了需要记录产生的任何类的麻烦,作为ToeTest。java 的一个例子,它能使内部类的概念
变得不那遥远。在这点,内嵌类被嵌套达四层之深!我们需要的这种设计决定了内部类的优点是否值得增加
更加复杂的事物。另外,当我们创建一个非静态的内部类时,我们将捆绑非静态类到它周围的类上。有时,
单独的类可以更容易地被复用。
//: ToeTestNew。java
// Demonstration of dialog boxes
// and creating your own ponents
import java。awt。*;
427
…………………………………………………………Page 429……………………………………………………………
import java。awt。event。*;
public class ToeTestNew extends Frame {
TextField rows = new TextField(〃3〃);
TextField cols = new TextField(〃3〃);
public ToeTestNew() {
setTitle(〃Toe Test〃);
Panel p = new Panel();
p。setLayout(new GridLayout(2;2));
p。add(new Label(〃Rows〃; Label。CENTER));
p。add(rows);
p。add(new Label(〃Columns〃; Label。CENTER));
p。add(cols);
add(p; BorderLayout。NORTH);
Button b = new Button(〃go〃);
b。addActionListener(new BL());
add(b; BorderLayout。SOUTH);
}
static final int BLANK = 0;
static final int XX = 1;
static fina l int OO = 2;
class ToeDialog extends Dialog {
// w = number of cells wide
// h = number of cells hig
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!