Chinaunix首页 | 论坛 | 博客
  • 博客访问: 900665
  • 博文数量: 96
  • 博客积分: 10681
  • 博客等级: 上将
  • 技术积分: 2449
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-16 17:52
文章分类

全部博文(96)

文章存档

2011年(30)

2009年(36)

2008年(30)

分类: Java

2011-03-21 12:45:23

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有八个构造函数:

  1. public JCheckBox()
  2. JCheckBox aCheckBox = new JCheckBox();
  3.  
  4. public JCheckBox(Icon icon)
  5. JCheckBox aCheckBox = new JCheckBox(new DiamondIcon(Color.RED, false));
  6. aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
  7.  
  8. public JCheckBox(Icon icon, boolean selected)
  9. JCheckBox aCheckBox = new JCheckBox(new DiamondIcon(Color.RED, false), true);
  10. aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
  11.  
  12. public JCheckBox(String text)
  13. JCheckBox aCheckBox = new JCheckBox("Spinach");
  14.  
  15. public JCheckBox(String text, boolean selected)
  16. JCheckBox aCheckBox = new JCheckBox("Onions", true);
  17.  
  18. public JCheckBox(String text, Icon icon)
  19. JCheckBox aCheckBox = new JCheckBox("Garlic", new DiamondIcon(Color.RED, false));
  20. aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
  21.  
  22. public JCheckBox(String text, Icon icon, boolean selected)
  23. JCheckBox aCheckBox = new JCheckBox("Anchovies", new DiamondIcon(Color.RED,
  24.   false), true);
  25. aCheckBox.setSelectedIcon(new DiamondIcon(Color.PINK, true));
  26.  
  27. public JCheckBox(Action action)
  28. Action action = ...;
  29. 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组件的三种可用方法,其中一个使用状态感知图标。最后一个复选框显示了坏图标的用法。

  1. package net.ariel.ch05;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.EventQueue;
  6. import java.awt.Graphics;
  7. import java.awt.GridLayout;
  8. import java.awt.Image;
  9.  
  10. import javax.swing.AbstractButton;
  11. import javax.swing.ButtonModel;
  12. import javax.swing.Icon;
  13. import javax.swing.ImageIcon;
  14. import javax.swing.JCheckBox;
  15. import javax.swing.JFrame;
  16.  
  17. import net.ariel.ch04.DiamondIcon;
  18.  
  19. public class IconCheckBoxSample {
  20.  
  21.     private static class CheckBoxIcon implements Icon {
  22.         private ImageIcon checkedIcon = new ImageIcon("plus.png");
  23.         private ImageIcon uncheckedIcon = new ImageIcon("minus.png");
  24.  
  25.         public void paintIcon(Component component, Graphics g, int x, int y) {
  26.             AbstractButton abstractButton = (AbstractButton)component;
  27.             ButtonModel buttonModel = abstractButton.getModel();
  28.             g.translate(x, y);
  29.             ImageIcon imageIcon = buttonModel.isSelected() ? checkedIcon : uncheckedIcon;
  30.             Image image = imageIcon.getImage();
  31.             g.drawImage(image, 0, 0, component);
  32.             g.translate(-x, -y);
  33.         }
  34.  
  35.         public int getIconWidth() {
  36.             return 20;
  37.         }
  38.  
  39.         public int getIconHeight() {
  40.             return 20;
  41.         }
  42.     }
  43.     /**
  44.      * @param args
  45.      */
  46.     public static void main(String[] args) {
  47.         // TODO Auto-generated method stub
  48.  
  49.         Runnable runner = new Runnable() {
  50.             public void run() {
  51.                 JFrame frame = new JFrame("Iconizing CheckBox");
  52.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  53.  
  54.                 Icon checked = new DiamondIcon(Color.BLACK, true);
  55.                 Icon unchecked = new DiamondIcon(Color.BLACK, false);
  56.  
  57.                 JCheckBox aCheckBox1 = new JCheckBox("Pizza", unchecked);
  58.                 JCheckBox aCheckBox2 = new JCheckBox("Calzone");
  59.                 aCheckBox2.setIcon(unchecked);
  60.                 aCheckBox2.setSelectedIcon(checked);
  61.  
  62.                 Icon checkBoxIcon = new CheckBoxIcon();
  63.                 JCheckBox aCheckBox3 = new JCheckBox("Anchovies", checkBoxIcon);
  64.                 JCheckBox aCheckBox4 = new JCheckBox("Stuffed Crust", checked);
  65.  
  66.                 frame.setLayout(new GridLayout(0, 1));
  67.                 frame.add(aCheckBox1);
  68.                 frame.add(aCheckBox2);
  69.                 frame.add(aCheckBox3);
  70.                 frame.add(aCheckBox4);
  71.  
  72.                 frame.setSize(300, 200);
  73.                 frame.setVisible(true);
  74.             }
  75.         };
  76.  
  77.         EventQueue.invokeLater(runner);
  78.     }
  79.  
  80. }

5.4.3 处理JCheckBox选中事件

与JToggleButton类似,我们也可以使用三种方法来处理JCheckBox事件:使用ActionListener,ItemListener或是ChangeListener。接受Action的构造函数只是添加一个参数作为ActionListener。

使用ActionListener监听JCheckBox事件

使用ActionListener订阅ActionEvent事件可以使得我们确定用户何时切换JCheckBox状态。与JToggleButton类似,所订阅的监听器会被通知选中,但并不会通知新状态。要确定选中状态,我们必须获取事件源的模型并进行查询,如下面的ActionListener源码所示。这个监听器修改了复选框的标签来反映选中状态。

  1. ActionListener actionListener = new ActionListener() {
  2.    public void actionPerformed(ActionEvent actionEvent) {
  3.      AbstractButton abstractButton = (AbstractButton)actionEvent.getSource();
  4.      boolean selected = abstractButton.getModel().isSelected();
  5.      String newLabel = (selected ? SELECTED_LABEL : DESELECTED_LABEL);
  6.      abstractButton.setText(newLabel);
  7.    }
  8. };

使用ItemListener监听JCheckBox事件

与JToggleButton类似,对于JCheckBox而言,更为适合的监听器是ItemListener。传递给ItemListener的itemStateChanged()方法的ItemEvent事件包含复选框的当前状态。这使得我们可以进行正确的响应,而无需查询当前的按钮状态。

为了进行演示,下面的ItemListener依据选中组件的状态切换前景色与背景色。在这个ItemListener中,只有状态被选中时才会进行前景色与背景色的切换。

  1. ItemListener itemListener = new ItemListener() {
  2.    public void itemStateChanged(ItemEvent itemEvent) {
  3.      AbstractButton abstractButton = (AbstractButton)itemEvent.getSource();
  4.      Color foreground = abstractButton.getForeground();
  5.      Color background = abstractButton.getBackground();
  6.      int state = itemEvent.getStateChange();
  7.      if (state == ItemEvent.SELECTED) {
  8.        abstractButton.setForeground(background);
  9.        abstractButton.setBackground(foreground);
  10.      }
  11.    }
  12. };

使用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并不会得到其他监听器所引起的这些属性变化的通知。

  1. package net.ariel.ch05;
  2.  
  3. import java.awt.BorderLayout;
  4. import java.awt.Color;
  5. import java.awt.EventQueue;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.ItemEvent;
  9. import java.awt.event.ItemListener;
  10. import java.awt.event.KeyEvent;
  11.  
  12. import javax.swing.AbstractButton;
  13. import javax.swing.ButtonModel;
  14. import javax.swing.JCheckBox;
  15. import javax.swing.JFrame;
  16. import javax.swing.event.ChangeEvent;
  17. import javax.swing.event.ChangeListener;
  18.  
  19. public class SelectingCheckBox {
  20.  
  21.     private static String DESELECTED_LABEL = "Deselected";
  22.     private static String SELECTED_LABEL = "Selected";
  23.     /**
  24.      * @param args
  25.      */
  26.     public static void main(String[] args) {
  27.         // TODO Auto-generated method stub
  28.  
  29.         Runnable runner = new Runnable() {
  30.             public void run() {
  31.                 JFrame frame = new JFrame("Selecting CheckBox");
  32.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  33.  
  34.                 JCheckBox checkBox = new JCheckBox(DESELECTED_LABEL);
  35.  
  36.                 ActionListener actionListener = new ActionListener() {
  37.                     public void actionPerformed(ActionEvent event) {
  38.                         AbstractButton abstractButton = (AbstractButton)event.getSource();
  39.                         boolean selected = abstractButton.isSelected();
  40.                         String newLabel = (selected ? SELECTED_LABEL : DESELECTED_LABEL);
  41.                         abstractButton.setText(newLabel);
  42.                     }
  43.                 };
  44.  
  45.                 ChangeListener changeListener = new ChangeListener() {
  46.                     public void stateChanged(ChangeEvent event) {
  47.                         AbstractButton abstractButton = (AbstractButton)event.getSource();
  48.                         ButtonModel buttonModel = abstractButton.getModel();
  49.                         boolean armed = buttonModel.isArmed();
  50.                         boolean pressed = buttonModel.isPressed();
  51.                         boolean selected = buttonModel.isSelected();
  52.                         System.out.println("Changed: "+armed+"/"+pressed+"/"+selected);
  53.                     }
  54.                 };
  55.  
  56.                 ItemListener itemListener = new ItemListener() {
  57.                     public void itemStateChanged(ItemEvent event) {
  58.                         AbstractButton abstractButton = (AbstractButton)event.getSource();
  59.                         Color foreground = abstractButton.getForeground();
  60.                         Color background = abstractButton.getBackground();
  61.                         int state = event.getStateChange();
  62.                         if(state == ItemEvent.SELECTED) {
  63.                             abstractButton.setForeground(background);
  64.                             abstractButton.setBackground(foreground);
  65.                         }
  66.                     }
  67.                 };
  68.  
  69.                 checkBox.addActionListener(actionListener);
  70.                 checkBox.addChangeListener(changeListener);
  71.                 checkBox.addItemListener(itemListener);
  72.  
  73.                 checkBox.setMnemonic(KeyEvent.VK_S);
  74.  
  75.                 frame.add(checkBox, BorderLayout.NORTH);
  76.  
  77.                 frame.setSize(300, 100);
  78.                 frame.setVisible(true);
  79.             }
  80.         };
  81.         EventQueue.invokeLater(runner);
  82.     }
  83.  
  84. }

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

阅读(1848) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~