Java编程思想第4版[中文版](PDF格式)-第123部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
…………………………………………………………Page 472……………………………………………………………
down = new BasicArrowButton(
BasicArrowButton。SOUTH);
right = new BasicArrowButton(
BasicArrowButton。EAST);
left = new BasicArrowButton(
BasicArrowButton。WEST);
public Buttons() {
add(jb);
add(new JToggleButton(〃JToggleButton〃));
add(new JCheckBox(〃JCheckBox〃));
add(new JRadioButton(〃JRadioButton〃));
JPanel jp = new JPanel();
jp。setBorder(new TitledBorder(〃Directions〃));
jp。add(up);
jp。add(down);
jp。add(left);
jp。add(right);
add(jp);
}
public static void main(String args'') {
Show。inFrame(new Buttons(); 300; 200);
}
} ///:~
JButton 看起来像AWT 按钮,但它没有更多可运行的功能(像我们后面将看到的如加入图像等)。在
。sun。java。swing。basic 里,有一个更合适的 BasicArrowButton 按钮,但怎样测试它呢?有两种类型的
“指针”恰好请求箭头按钮使用:Spinner 修改一个中断值,并且 StringSpinner 通过一个字符串数组来移
动(当它到达数组底部时,甚至会自动地封装)。ActionListeners 附着在箭头按钮上展示它使用的这些相
关指针:因为它们是Bean ,我们将期待利用方法名,正好捕捉并设置它们的值。
当我们运行这个程序例子时,我们会发现触发按钮保持它最新状态,开或时关。但复选框和单选钮每一个动
作都相同,选中或没选中(它们从 JToggleButton 处继承)。
13。19。7 按钮组
如果我们想单选钮保持“异或”状态,我们必须增加它们到一个按钮组中,这几乎同老AWT 中的方法相同但
更加的灵活。在下面将要证明的程序例子是,一些 AbstruactButton 能被增加到一个ButtonGroup 中。
为避免重复一些代码,这个程序利用映射来生不同类型的按钮组。这会在 makeBPanel 中看到,makeBPanel
创建了一个按钮组和一个JPanel,并且为数组中的每个 String 就是makeBPanel 的第二个自变量增加一个类
对象,由它的第一个自变量进行声明:
//: ButtonGroups。java
// Uses reflection to create groups of different
// types of AbstractButton。
package c13。swing;
import java。awt。*;
import java。awt。event。*;
import javax。swing。*;
import javax。swing。border。*;
import java。lang。reflect。*;
public class ButtonGroups extends JPanel {
static String'' ids = {
〃June〃; 〃Ward〃; 〃Beaver〃;
471
…………………………………………………………Page 473……………………………………………………………
〃Wally〃; 〃Eddie〃; 〃Lumpy〃;
};
static JPanel
makeBPanel(Class bClass; String'' ids) {
ButtonGroup bg = new ButtonGroup();
JPanel jp = new JPanel();
String title = bClass。getName();
title = title。substring(
title。lastIndexOf('。') + 1);
jp。setBorder(new TitledBorder(title));
for(int i = 0; i 《 ids。length; i++) {
AbstractButton ab = new JButton(〃failed〃);
try {
// Get the dynamic constructor method
// that takes a String argument:
Constructor ctor = bClass。getConstructor(
new Class'' { String。class });
// Create a new object:
ab = (AbstractButton)ctor。newInstance(
new Object''{ids'i'});
} catch(Exception ex) {
System。out。println(〃can't create 〃 +
bClass);
}
bg。add(ab);
jp。add(ab);
}
return jp;
}
public ButtonGroups() {
add(makeBPanel(JButton。class; ids));
add(makeBPanel(JToggleButton。class; ids));
add(makeBPanel(JCheckBox。class; ids));
add(makeBPanel(JRadioButton。class; ids));
}
public static void main(String args'') {
Show。inFrame(new ButtonGroups(); 500; 300);
}
} ///:~
边框标题由类名剔除了所有的路径信息而来。AbstractButton 初始化为一个 JButton,JButtonr 的标签发生
“失效”,因此如果我们忽略这个异常信息,我们会在屏幕上一直看到这个问题。getConstructor()方法产
生了一个通过getConstructor()方法安放自变量数组类型到类数组的构建器对象,然后所有我们要做的就是
调用newInstance() ,通过它一个数组对象包含我们当前的自变量——在这种例子中,就是 ids 数组中的字
符串。
这样增加了一些更复杂的内容到这个简单的程序中。为了使“异或”行为拥有按钮,我们创建一个按钮组并
增加每个按钮到我们所需的组中。当我们运行这个程序时,我们会注意到所有的按钮除了JButton 都会向我
们展示“异或”行为。
13。19。8 图标
我们可在一个JLable 或从AbstractButton 处继承的任何事物中使用一个图标(包括 JButton,JCheckbox ,
JradioButton 及不同类型的 JMenuItem)。利用JLables 的图标十分的简单容易(我们会在随后的一个程序例
472
…………………………………………………………Page 474……………………………………………………………
子中看到)。下面的程序例子探索了我们可以利用按钮的图标和它们的衍生物的其它所有方法。
我们可以使用任何我们需要的 GIF 文件,但在这个例子中使用的这个 GIF 文件是这本书编码发行的一部分,
可以在BruceEckel。 处下载来使用。为了打开一个文件和随之带来的图像,简单地创建一个图标并分
配它文件名。从那时起,我们可以在程序中使用这个产生的图标。
//: Faces。java
// Icon behavior in JButtons
package c13。swing;
import java。awt。*;
import java。awt。event。*;
import javax。swing。*;
public class Faces extends JPanel {
static Icon'' faces = {
new ImageIcon(〃face0。gif〃);
new ImageIcon(〃face1。gif〃);
new ImageIcon(〃face2。gif〃);
new ImageIcon(〃face3。gif〃);
new ImageIcon(〃face4。gif〃);
};
JButton
jb = new JButton(〃JButton〃; faces'3');
jb2 = new JButton(〃Disable〃);
boolean mad = false;
public Faces() {
jb。addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
if(mad) {
jb。setIcon(faces'3');
mad = false;
} else {
jb。setIcon(faces'0');
mad = true;
}
jb。setVerticalAlignment(JButton。TOP);
jb。setHorizontalAlignment(JButton。LEFT);
}
});
jb。setRolloverEnabled(true);
jb。setRolloverIcon(faces'1');
jb。setPressedIcon(faces'2');
jb。setDisabledIcon(faces'4');
jb。setToolTipText(〃Yow!〃);
add(jb);
jb2。addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
if(jb。isEnabled()) {
jb。setEnabled(false);
jb2。setText(〃Enable〃);
} else {
jb。setEnabled(true);
jb2。setText(〃Disable〃);
473
…………………………………………………………Page 475……………………………………………………………
}
}
});
add(jb2);
}
public static void main(String args'') {
Show。inFrame(new Faces(); 300; 200);
}
} ///:~
一个图标可以在许多的构建器中使用,但我们可以使用setIcon()方法增加或更换图标。这个例子同样展示
了当事件发生在JButton (或者一些AbstractButton)上时,为什么它可以设置各种各样的显示图标:当
JButton 被按下时,当它被失效时,或者“滚过”时(鼠标从它上面移动过但并不击它)。我们会注意到那
给了按钮一种动画的感觉。
注意工具提示条也同样增加到按钮中。
13。19。9 菜单
菜单在 Swing 中做了重要的改进并且更加的灵活——例如,我们可以在几乎程序中任何地方使用他们,包括
在面板和程序片中。语法同它们在老的AWT 中是一样的,并且这样使出现在老AWT 的在新的Swing 也出现
了:我们必须为我们的菜单艰难地编写代码,并且有一些不再作为资源支持菜单(其它事件中的一些将使它
们更易转换成其它的编程语言)。另外,菜单代码相当的冗长,有时还有一些混乱。下面的方法是放置所有
的关于每个菜单的信息到对象的二维数组里(这种方法可以放置我们想处理的任何事物到数组里),这种方
法在解决这个问题方面领先了一步。这个二维数组被菜单所创建,因此它首先表示出菜单名,并在剩余的列
中表示菜单项和它们的特性。我们会注意到数组列不必保持一致——只要我们的代码知道将发生的一切事
件,每一列都可以完全不同。
//: Menus。java
// A menu…building system; also demonstrates
// icons in labels and menu items。
package c13。swing;
import java。awt。*;
import java。awt。event。*;
import javax。swing。*;
public class Menus extends JPanel {
static final Boolean
bT = new Boolean(true);
bF = new Boolean(false);
// Dummy class to create type identifiers:
static class MType { MType(int i) {} };
static final MType
mi = new MType(1); // Normal menu item
cb = new MType(2); // Checkbox menu item
rb = new MType(3); // Radio button menu item
JTextField t = new JTextField(10);
JLabel l = new JLabel(〃Icon Selected〃;
Faces。faces'0'; JLabel。CENTER);
ActionListener a1 = new ActionListener() {
public void actionPerformed(ActionEvent e) {
t。setText(
((JMenuItem)e。getSource())。getText());
}
474
…………………………………………………………Page 476……………………………………………………………
};
ActionListener a2 = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JMenuItem mi = (JMenuItem)e。getSource();
l。setText(mi。getText());
l。setIcon(mi。getIcon());
}
};
// Store menu data as 〃resources〃:
public Object'''' fileMenu = {
// Menu name and accelerator:
{ 〃File〃; new Character('F') };
// Name type accel listener enabled
{ 〃New〃; mi; new Character('N'); a1; bT };
{ 〃Open〃; mi; new Character('O'); a1; bT };
{ 〃Save〃; mi; new Character('S'); a1; bF };
{ 〃Save As〃; mi; new Character('A'); a1; bF};
{ null }; // Separator
{ 〃Exit〃; mi; new Character('x'); a1; bT };
};
public Object'''' editMenu = {
// Menu name:
{ 〃Edit〃; new Character('E') };
// Name type accel listener enabled
{ 〃Cut〃; mi; new Character('t'); a1; bT };
{ 〃Copy〃; mi; new Char