Toggle Buttons(三)

5.4 JCheckBox类

JCheckBox类表示切换组件,在默认情况下,这个组件在接近文本标签处显示了一个复选框图标,用于两状态选项选择。复选框使用一个可选的复选标记来显示对象的当前状态,而不是如JToggleButton保持按钮按下状态。对于JCheckBox,图标显示了对象的状态,而对于JToggleButton,图标则是标签的一部分,通常并不用于显示状态信息。JCheckBox与JToggleButton之间除了UI相关部分不同外,这两个组件是相同的。图5-5演示了在一个匹萨预定程序中复选框的样子。

Swing_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)则不使用这个属性。

swing_5_6

正如所列出的构造函数所显示的,如果我们选择通过构造函数设置图标,则构造函数只为未选中的状态设置一个图标。如果我们希望复选框图标显示实际的正确状态,我们必须使用一个状态感知图标,或者是通过setSelectedIcon()为选中状态关联一个不同的图标。具有两个不同的可视状态表示是大多数用户希望JCheckBox所应用的,所有除非我们有特殊的理由,最好是遵循普通用户界面的设计约定。

图5-7所显示的界面底部的第四个按钮演示了JCheckBox的用法。复选框总是显示了选中状态。下图显示了选中Pizza,未选中Calzone,未选中Anchovies以及未选中Crust时的状态。

swing_5_7

列表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所示。

swing_5_8

5.4.4 自定义JCheckBox观感

每一个安装的Swing观感都会提供一个不同的JCheckBox外观与一个默认的UIResource值集合。图5-9显示了预安装的观感类型集合的JCheckBox组件外观:Motif,Windows,Ocean。第一,第三与第五个复选框为选中状态,而第三个具有输入焦点。

swing_5_9

表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

原文地址:https://www.cnblogs.com/dyllove98/p/2461914.html