5.4 JCheckBox类
JCheckBox类表示切换组件,在默认情况下,这个组件在接近文本标签处显示了一个复选框图标,用于两状态选项选择。复选框使用一个可选的复选标记来显示对象的当前状态,而不是如JToggleButton保持按钮按下状态。对于JCheckBox,图标显示了对象的状态,而对于JToggleButton,图标则是标签的一部分,通常并不用于显示状态信息。JCheckBox与JToggleButton之间除了UI相关部分不同外,这两个组件是相同的。图5-5演示了在一个匹萨预定程序中复选框的样子。
JCheckBox是由几部分构成的。与JToggleButton类似,JCheckBox使用一个ToggleButtonModel来表示其数据模型。用户界面委托是CheckBoxUI。尽管ButtonGroup可以用来组合复选框,但是通常这并不合适。当多个JCheckBox组件位于一个ButtonGroup中时,他们的行为类似于JRadioButton组件,但是看上去是JCheckBox组件。由于可视化的原因,我们不应将JCheckBox组件放在ButtonGroup中。
现在我们已经了解了JCheckBox的不同部分,下面我们来了解一下如何来使用。
5.4.1 创建JCheckBox组件
JCheckBox有八个构造函数:
- public JCheckBox()
-
JCheckBox aCheckBox = new JCheckBox();
-
-
public JCheckBox(Icon icon)
-
JCheckBox aCheckBox = new JCheckBox(new DiamondIcon(Color.RED, false));
-
aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
-
-
public JCheckBox(Icon icon, boolean selected)
-
JCheckBox aCheckBox = new JCheckBox(new DiamondIcon(Color.RED, false), true);
-
aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
-
-
public JCheckBox(String text)
-
JCheckBox aCheckBox = new JCheckBox("Spinach");
-
-
public JCheckBox(String text, boolean selected)
-
JCheckBox aCheckBox = new JCheckBox("Onions", true);
-
-
public JCheckBox(String text, Icon icon)
-
JCheckBox aCheckBox = new JCheckBox("Garlic", new DiamondIcon(Color.RED, false));
-
aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
-
-
public JCheckBox(String text, Icon icon, boolean selected)
-
JCheckBox aCheckBox = new JCheckBox("Anchovies", new DiamondIcon(Color.RED,
-
false), true);
-
aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
-
-
public JCheckBox(Action action)
-
Action action = ...;
-
JCheckBox aCheckBox = new JCheckBox(action);
每一个构造函数都允许我们定制零个或是至多三个属性:标签,图标或是初始选中状态。除非特别指明,默认情况下并没有标签,而复选框的默认选中/未选中图标表现为未选中。
如果我们在构造函数中初始化图标,图标用于复选框未选中状态,而复选框选中时也使用相同的图标。我们必须或者是通过setSelectedIcon(Icon newValue)方法来初始化选中图标,或者是确保图标是状态相关的并更新自身。如果我们没有配置选中图标,也没有使用状态相关图标,则相同的图标会出现在选中与未选中状态。通常而言,不在选中与未选中状态之间变化其可视外观的图标并不是JCheckBox所要求的。
5.4.2 JCheckBox属性
在创建了JCheckBox之后,我们可以修改其属性。JCheckBox特定的两个属性覆盖了其父类JToggleButton的行为。第三个borderPaintedFlat属性是在JDK 1.3版本中引入的。其余的属性都是通过其父类JToggleButton继承而来的。
JCheckBox属性
属性名
|
数据类型
|
访问性
|
accessibleContext
|
AccessibleContext
|
只读
|
borderPaintedFlat
|
boolean
|
读写绑定
|
UIClassID
|
String
|
只读
|
borderPaintedFlat属性可以将复选图标的边框的观感显示为两维而不是三维。在默认情况下,borderPaintedFlat属性为false,意味着边框将是三维的。图5-6显示了平坦边框的样子,其中第一个,第三个,第五个的边框是平坦的,而第二个与第四个不是。观感可以选择忽略这些属性。然而,对于组件的渲染者,例如表格与树,这个属性是十分用的,因为他们只显示状态而不显示是否可以选中。Windows与Motif观感类型使用这个属性,而Metal(以及Ocean)则不使用这个属性。
正如所列出的构造函数所显示的,如果我们选择通过构造函数设置图标,则构造函数只为未选中的状态设置一个图标。如果我们希望复选框图标显示实际的正确状态,我们必须使用一个状态感知图标,或者是通过setSelectedIcon()为选中状态关联一个不同的图标。具有两个不同的可视状态表示是大多数用户希望JCheckBox所应用的,所有除非我们有特殊的理由,最好是遵循普通用户界面的设计约定。
图5-7所显示的界面底部的第四个按钮演示了JCheckBox的用法。复选框总是显示了选中状态。下图显示了选中Pizza,未选中Calzone,未选中Anchovies以及未选中Crust时的状态。
列表5-3演示了创建具有不同图标的JCheckBox组件的三种可用方法,其中一个使用状态感知图标。最后一个复选框显示了坏图标的用法。
- package net.ariel.ch05;
-
-
import java.awt.Color;
-
import java.awt.Component;
-
import java.awt.EventQueue;
-
import java.awt.Graphics;
-
import java.awt.GridLayout;
-
import java.awt.Image;
-
-
import javax.swing.AbstractButton;
-
import javax.swing.ButtonModel;
-
import javax.swing.Icon;
-
import javax.swing.ImageIcon;
-
import javax.swing.JCheckBox;
-
import javax.swing.JFrame;
-
-
import net.ariel.ch04.DiamondIcon;
-
-
public class IconCheckBoxSample {
-
-
private static class CheckBoxIcon implements Icon {
-
private ImageIcon checkedIcon = new ImageIcon("plus.png");
-
private ImageIcon uncheckedIcon = new ImageIcon("minus.png");
-
-
public void paintIcon(Component component, Graphics g, int x, int y) {
-
AbstractButton abstractButton = (AbstractButton)component;
-
ButtonModel buttonModel = abstractButton.getModel();
-
g.translate(x, y);
-
ImageIcon imageIcon = buttonModel.isSelected() ? checkedIcon : uncheckedIcon;
-
Image image = imageIcon.getImage();
-
g.drawImage(image, 0, 0, component);
-
g.translate(-x, -y);
-
}
-
-
public int getIconWidth() {
-
return 20;
-
}
-
-
public int getIconHeight() {
-
return 20;
-
}
-
}
-
/**
-
* @param args
-
*/
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
-
Runnable runner = new Runnable() {
-
public void run() {
-
JFrame frame = new JFrame("Iconizing CheckBox");
-
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-
Icon checked = new DiamondIcon(Color.BLACK, true);
-
Icon unchecked = new DiamondIcon(Color.BLACK, false);
-
-
JCheckBox aCheckBox1 = new JCheckBox("Pizza", unchecked);
-
JCheckBox aCheckBox2 = new JCheckBox("Calzone");
-
aCheckBox2.setIcon(unchecked);
-
aCheckBox2.setSelectedIcon(checked);
-
-
Icon checkBoxIcon = new CheckBoxIcon();
-
JCheckBox aCheckBox3 = new JCheckBox("Anchovies", checkBoxIcon);
-
JCheckBox aCheckBox4 = new JCheckBox("Stuffed Crust", checked);
-
-
frame.setLayout(new GridLayout(0, 1));
-
frame.add(aCheckBox1);
-
frame.add(aCheckBox2);
-
frame.add(aCheckBox3);
-
frame.add(aCheckBox4);
-
-
frame.setSize(300, 200);
-
frame.setVisible(true);
-
}
-
};
-
-
EventQueue.invokeLater(runner);
-
}
-
-
}
5.4.3 处理JCheckBox选中事件
与JToggleButton类似,我们也可以使用三种方法来处理JCheckBox事件:使用ActionListener,ItemListener或是ChangeListener。接受Action的构造函数只是添加一个参数作为ActionListener。
使用ActionListener监听JCheckBox事件
使用ActionListener订阅ActionEvent事件可以使得我们确定用户何时切换JCheckBox状态。与JToggleButton类似,所订阅的监听器会被通知选中,但并不会通知新状态。要确定选中状态,我们必须获取事件源的模型并进行查询,如下面的ActionListener源码所示。这个监听器修改了复选框的标签来反映选中状态。
- ActionListener actionListener = new ActionListener() {
-
public void actionPerformed(ActionEvent actionEvent) {
-
AbstractButton abstractButton = (AbstractButton)actionEvent.getSource();
-
boolean selected = abstractButton.getModel().isSelected();
-
String newLabel = (selected ? SELECTED_LABEL : DESELECTED_LABEL);
-
abstractButton.setText(newLabel);
-
}
-
};
使用ItemListener监听JCheckBox事件
与JToggleButton类似,对于JCheckBox而言,更为适合的监听器是ItemListener。传递给ItemListener的itemStateChanged()方法的ItemEvent事件包含复选框的当前状态。这使得我们可以进行正确的响应,而无需查询当前的按钮状态。
为了进行演示,下面的ItemListener依据选中组件的状态切换前景色与背景色。在这个ItemListener中,只有状态被选中时才会进行前景色与背景色的切换。
- ItemListener itemListener = new ItemListener() {
-
public void itemStateChanged(ItemEvent itemEvent) {
-
AbstractButton abstractButton = (AbstractButton)itemEvent.getSource();
-
Color foreground = abstractButton.getForeground();
-
Color background = abstractButton.getBackground();
-
int state = itemEvent.getStateChange();
-
if (state == ItemEvent.SELECTED) {
-
abstractButton.setForeground(background);
-
abstractButton.setBackground(foreground);
-
}
-
}
-
};
使用ChangeListener监听JCheckBox事件
与JToggleButton类似,ChangeListener也可以响应JCheckBox事件。当按钮被armed, pressed, selected, released时所订阅的ChangeListener会得到通知。另外,ChangeListener也会得到ButtonModel变化的通知,但是复选框的键盘快捷键。因为在JToggleButton与JCheckBox之间并没有ChangeListener的区别,所以我们可以将JToggleButton中的监听器关联到JCheckBox,而我们会得到相同的选中响应。
列表5-4中的示例程序演示了监听一个JCheckBox事件的所有监听器。为了演示ChangeListener会得到其他按钮模型属性变化的通知,我们将一个执键与组件相关联。由于ChangeListener的注册发生在mnemonic属性变化之前,所以ChangeListener会得到这个属性变化的通知。因为前景色,背景色与文本标签并不是按钮模型属性,ChangeListener并不会得到其他监听器所引起的这些属性变化的通知。
- package net.ariel.ch05;
-
-
import java.awt.BorderLayout;
-
import java.awt.Color;
-
import java.awt.EventQueue;
-
import java.awt.event.ActionEvent;
-
import java.awt.event.ActionListener;
-
import java.awt.event.ItemEvent;
-
import java.awt.event.ItemListener;
-
import java.awt.event.KeyEvent;
-
-
import javax.swing.AbstractButton;
-
import javax.swing.ButtonModel;
-
import javax.swing.JCheckBox;
-
import javax.swing.JFrame;
-
import javax.swing.event.ChangeEvent;
-
import javax.swing.event.ChangeListener;
-
-
public class SelectingCheckBox {
-
-
private static String DESELECTED_LABEL = "Deselected";
-
private static String SELECTED_LABEL = "Selected";
-
/**
-
* @param args
-
*/
-
public static void main(String[] args) {
-
// TODO Auto-generated method stub
-
-
Runnable runner = new Runnable() {
-
public void run() {
-
JFrame frame = new JFrame("Selecting CheckBox");
-
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-
JCheckBox checkBox = new JCheckBox(DESELECTED_LABEL);
-
-
ActionListener actionListener = new ActionListener() {
-
public void actionPerformed(ActionEvent event) {
-
AbstractButton abstractButton = (AbstractButton)event.getSource();
-
boolean selected = abstractButton.isSelected();
-
String newLabel = (selected ? SELECTED_LABEL : DESELECTED_LABEL);
-
abstractButton.setText(newLabel);
-
}
-
};
-
-
ChangeListener changeListener = new ChangeListener() {
-
public void stateChanged(ChangeEvent event) {
-
AbstractButton abstractButton = (AbstractButton)event.getSource();
-
ButtonModel buttonModel = abstractButton.getModel();
-
boolean armed = buttonModel.isArmed();
-
boolean pressed = buttonModel.isPressed();
-
boolean selected = buttonModel.isSelected();
-
System.out.println("Changed: "+armed+"/"+pressed+"/"+selected);
-
}
-
};
-
-
ItemListener itemListener = new ItemListener() {
-
public void itemStateChanged(ItemEvent event) {
-
AbstractButton abstractButton = (AbstractButton)event.getSource();
-
Color foreground = abstractButton.getForeground();
-
Color background = abstractButton.getBackground();
-
int state = event.getStateChange();
-
if(state == ItemEvent.SELECTED) {
-
abstractButton.setForeground(background);
-
abstractButton.setBackground(foreground);
-
}
-
}
-
};
-
-
checkBox.addActionListener(actionListener);
-
checkBox.addChangeListener(changeListener);
-
checkBox.addItemListener(itemListener);
-
-
checkBox.setMnemonic(KeyEvent.VK_S);
-
-
frame.add(checkBox, BorderLayout.NORTH);
-
-
frame.setSize(300, 100);
-
frame.setVisible(true);
-
}
-
};
-
EventQueue.invokeLater(runner);
-
}
-
-
}
SelectingCheckBox类在选中并取消选中后所产生的程序界面如图5-8所示。
5.4.4 自定义JCheckBox观感
每一个安装的Swing观感都会提供一个不同的JCheckBox外观与一个默认的UIResource值集合。图5-9显示了预安装的观感类型集合的JCheckBox组件外观:Motif,Windows,Ocean。第一,第三与第五个复选框为选中状态,而第三个具有输入焦点。
表5-4显示了JCheckBox的UIResource相关属性的集合。JCheckBox组件具有20个不同的属性。
JCheckBox UIResource元素
属性字符串
|
对象类型
|
CheckBox.background
|
Color
|
CheckBox.border
|
Border
|
CheckBox.darkShadow
|
Color
|
CheckBox.disabledText
|
Color
|
CheckBox.focus
|
Color
|
CheckBox.focusInputMap
|
Object[]
|
CheckBox.font
|
Font
|
CheckBox.foreground
|
Color
|
CheckBox.gradient
|
List
|
CheckBox.highlight
|
Color
|
CheckBox.icon
|
Icon
|
CheckBox.interiorBackground
|
Color
|
CheckBox.light
|
Color
|
CheckBox.margin
|
Insets
|
CheckBox.rollover
|
Boolean
|
CheckBox.select
|
Color
|
CheckBox.shadow
|
Color
|
CheckBox.textIconGap
|
Integer
|
CheckBox.textShiftOffset
|
Integer
|
CheckBoxUI
|
String
|
阅读(1848) | 评论(0) | 转发(0) |