8.4 选择组件
经过上节的学习,我们知道了如何利用文本输入组件获取用户输入的文本,但是,在很多情况下,用户可能更倾向于你给他一些选择,而不是让他自己输入这些信息。Java中提供了这样的组件,可以使用户不需输入文字而与GUI界面进行交互。
8.4.1 JCheckBox 复选框
JCheckBox是从JToggleButton类中派生出来的,具有两种状态,通常用于显示文本,并有一个指示是否被选中的方形按钮。
JCheckBox的构造方法较多,详见下表8-7。
表8-7 JCheckBox构造方法
构造方法 | 说明 |
JCheckBox() | 创建一个没有文本、没有图标并且最初未被选定的复选框 |
JCheckBox(Icon icon) | 创建有一个图标、最初未被选定的复选框 |
JCheckBox(Icon icon, boolean selected) | 创建一个带图标的复选框,并指定其最初是否处于选定状态WwW.kao8.Cc |
JCheckBox(String text) | 创建一个带文本的、最初未被选定的复选框 |
JCheckBox(String text, boolean selected) | 创建一个带文本的复选框,并指定其最初是否处于选定状态 |
JCheckBox(String text, Icon icon) | 创建带有指定文本和图标的、最初未选定的复选框 |
JCheckBox(String text, Icon icon,boolean selected) | 创建一个带文本和图标的复选框,并指定其最初是否处于选定状态 |
构造方法中各参数意义
text - 复选框的文本
icon - 要显示的 Icon 图像
selected - 指示最初选择状态的 boolean 值。如果该参数为 true,则复选框被选定
当JCheckBox被选中或取消选中时,会触发一个事件,该事件就是ActionEvent,如果想根据JCheckBox的选中情况进行不同处理,可以编写实现ActionListener接口的类进行处理。
8.4.2 JRadioButton单选按钮
单选按钮JRadioButton与复选按钮JCheckBox几乎是相同的,都是从JToggleButton类中派生出来的,都具有两种状态,主要用于显示文本。JRadioButton有一个指示是否被选中的圆形按钮。不同之处在于单选按钮机会总是用于显示一组互相排斥的选项(如某人的性别,男、女只能选择一项),所以,JRadioButton通常位于一个ButtonGroup按钮组中,不在按钮组中的JRadioButton也就失去了JRadioButton的意义。
在同一个ButtonGroup按钮组种的单选按钮,任何时刻最多有一个单选按钮被选中,因此,如果我们创建的多个单选按钮其初始状态都是选中状态,则最先加入ButtonGroup按钮组的单选按钮的选中状态被保留,其后加入到ButtonGroup按钮组中的其他单选按钮的选中状态被取消。选中状态的保留与加入到ButtonGroup中的次序有关,与加入到其要显示的父容器顺序无关。
如下代码中
Container contentPane = this.getContentPane();
JRadioButton r1 = new JRadioButton("a",true);
JRadioButton r2 = new JRadioButton("b",true);
JRadioButton r3 = new JRadioButton("c",true);
ButtonGroup button = new ButtonGroup();
button.add(r3);
button.add(r2);
button.add(r1);
contentPane.setLayout(new FlowLayout());
contentPane.add(r2);
contentPane.add(r1);
contentPane.add(r3);
加入ButtonGroup中的JRadioButton的顺序为r3,r2,r1,而加入contentPane中的书序则为r2,r1,r2,这时候其运行效果如下:
可见其状态选中是根据加入ButtonGroup中的顺序决定的
JRadioButton提供了与JCheckBox完全相似的构造方法。见下表8-8
表8-8 JRadioButton构造方法
构造方法 | 说明 |
JRadioButton() | 创建一个初始化为未选择的单选按钮,其文本未设定 |
JRadioButton(Icon icon) | 创建一个初始化为未选择的单选按钮,其具有指定的图像但无文本 |
JRadioButton(Icon icon, boolean selected) | 创建一个具有指定图像和选择状态的单选按钮,但无文本 |
JRadioButton(String text) | 创建一个具有指定文本的状态为未选择的单选按钮 |
JRadioButton(String text, boolean selected) | 创建一个具有指定的文本和图像并初始化为未选择的单选按钮 |
JRadioButton(String text, Icon icon) | 创建一个具有指定的文本和图像并初始化为未选择的单选按钮 |
JRadioButton(String text, Icon icon,boolean selected) | 创建一个具有指定的文本、图像和选择状态的单选按钮 |
text -此单选按钮上显示的字符串
icon -此按钮应显示的图像
selected - 指示最初选择状态的 boolean 值。如果该参数为 true,则单选框被选定
当JRadioButton被选中或取消选中时,会触发一个事件,该事件就是ActionEvent,如果想根据JRadioButton的选中情况进行不同处理,可以编写实现ActionListener接口的类进行处理。
例8-5 中在JFrame添加了两个JRadioButton及三个JCheckBox,验证我们所学的部分知识。
[例 8-5]
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class JCheckBoxAndJRadioButtonTest extends JFrame{
private JPanel panelNorth = new JPanel();
private JLabel label1 = new JLabel("性别");
private JRadioButton rb1 = new JRadioButton("男",true);
private JRadioButton rb2 = new JRadioButton("女");
private ButtonGroup group = new ButtonGroup();
private JLabel label2 = new JLabel("擅长");
private JCheckBox cb1= new JCheckBox("书法");
private JCheckBox cb2= new JCheckBox("唱歌");
private JCheckBox cb3= new JCheckBox("跳舞");
private JButton button = new JButton("确定");
private JTextArea ta = new JTextArea(6,10);
public JCheckBoxAndJRadioButtonTest(String title){
super(title);
Container contentPane = this.getContentPane(); [page]
//添加JRadioButton到ButtonGroup中
group.add(rb1);
group.add(rb2);
panelNorth.add(label1);
panelNorth.add(rb1);
panelNorth.add(rb2);
panelNorth.add(label2);
panelNorth.add(cb1);
panelNorth.add(cb2);
panelNorth.add(cb3);
panelNorth.add(button);
contentPane.add(panelNorth,BorderLayout.NORTH);
contentPane.add(ta,BorderLayout.CENTER);
pack();
//监听button的Action事件
button.addActionListener(new MyActionListener());
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String sex="";//记录性别
StringBuffer strBuf=new StringBuffer();//记录擅长
//isSelected表示控件被选中
if(rb1.isSelected()){
sex="男";
}
if(rb2.isSelected()){
sex="女";
}
if(cb1.isSelected()){
strBuf.append("书法 ");
}
if(cb2.isSelected()){
strBuf.append("唱歌 ");
}
if(cb3.isSelected()){
strBuf.append("跳舞 ");
}
ta.setText("您的性别:"+sex+"\t擅长:"+strBuf.toString()+""+ta.getText());
}
}
}
public class Test8_5{
public static void main(String[] args) {
new JCheckBoxAndJRadioButtonTest("单选复选按钮测试");
}
}
运行结果如图8-6所示
图8-6 例8-5多次按下确定按钮的运行结果
例8-5中我们并没有监测JRadioButton和JCheckBox,实际上我们设计类来监测其ActionEvent,同样可以达到本例题的效果,有兴趣的读者可以修改例8-5中事件处理部分来监测两个JRadioButton和三个JCheckBox。
8.4.3JComboBox下拉列表
JComboBox组件也称为下拉列表框,其特点是将所有选项折叠在一起,只显示最前面的或被用户选中的一个。选择时需要单击下拉列表右边的下三角按钮,这时候会弹出包含所有选项的列表。用户可以在列表中进行选择,也可以根据需要直接输入所要的选项。也可以输入选项中没有的内容。
JcomboBox类提供了多个构造方法用于创建JcomboBox类对象,详见下表8-9。
表8-9 JComboBox构造 方法
构造方法 | 说明 |
JComboBox() | 创建一个空的JcomboBox对象,可使用addItem方法添加选项 |
JComboBox(ComboBoxModel aModel) | 创建一个 JComboBox,其项取自现有的 ComboBoxModel |
JComboBox(Object[] items) | 创建包含指定数组中的元素的 JComboBox |
JComboBox(Vector items) | 创建包含指定 Vector 中的元素的 JComboBox |
我们可以利用上表给出的四个方法中的任意一个来创建JComboBox对象,在实际使用中,JComboBox()及JComboBox(Object[] items)方式可能会更常用。
[page]表8-10 JComboBox类的常用方法
成员方法 | 说明 |
void addItem(Object anObject) | 将指定的对象作为项添加到下拉列表框中 |
void insertItemAt | 在下拉列表框中的给定索引处插入项 |
void removeItem(Object anObject) | 在下拉列表框中删除指定的对象项 |
void removeItemAt(int anIndex) | 在下拉列表框中删除指定位置的对象项 |
void removeAllItems() | 从下拉列表框中删除所有项 |
int getItemCount() | 返回下拉列表框中的项数 |
Object getItemAt(int index) | 获取指定下标的列表项,下标从0开始 |
int getSelectedIndex() | 获取当前选择的下标 |
Object getSelectedItem() | 获取当前选择的项 |
JComboBox能够响应两个事件,分别为ItemEvent和ActionEvent,要处理这两个事件,需要创建相应的类实现ItemListener 和ActionListener接口。ItemEvent触发的时机是当下拉列表框中的所选项更改时,ActionEvent触发的时机是当用户在JComboBox上直接输入选择项并回车时。
例8-6演示了如何在程序中为JComboBox添加项,如何删除项以及选中JComboBox中的某项后的事件处理。
[例8-6]
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class JComboBoxTest extends JFrame{
private JComboBox cmb = new JComboBox();
private JLabel label = new JLabel("要添加项的值:");
private JTextField tf = new JTextField(5);
private JButton buttonAdd = new JButton("添加");
private JButton buttonDel = new JButton("删除");
private JTextArea ta = new JTextArea(4,8);
private JPanel panelNorth = new JPanel();
public JComboBoxTest(String title){
super(title);
Container contentPane = this.getContentPane();
panelNorth.add(cmb);
panelNorth.add(label);
panelNorth.add(tf);
panelNorth.add(buttonAdd);
panelNorth.add(buttonDel);
contentPane.add(panelNorth,BorderLayout.NORTH);
contentPane.add(ta,BorderLayout.CENTER);
buttonAdd.addActionListener(new MyActionListener());
buttonDel.addActionListener(new MyActionListener());
cmb.addItemListener(new MyItemListener());
pack();
setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//监听"添加"和"删除"按钮
private class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
//添加按钮处理
if(command.equals("添加")){
if(tf.getText().length()!=0){
cmb.addItem(tf.getText());//添加项
ta.setText("添加成功,添加项:"+tf.getText());
pack();//自动调整窗口大小
}
else{
ta.setText("请输入要添加的项");
}
}
//删除按钮处理
if(command.equals("删除")){
if(cmb.getSelectedIndex()!=-1){
//先获得要删除的项的值
String strDel = cmb.getSelectedItem().toString();
cmb.removeItem(strDel);//删除项
ta.setText("删除成功,删除项:"+strDel);
pack();//自动调整窗口大小
}
else{
ta.setText("请选择要删除的项");
}
}
}
}
private class MyItemListener implements ItemListener{
public void itemStateChanged(ItemEvent e) {
String str = e.getItem().toString();
ta.setText("您选择了项:"+str);
}
}
}
public class Test8_6 {
public static void main(String[] args) {
new JComboBoxTest("JComboBox测试");
}
}
[page]图8-7 例8-6三种不同情况下的运行结果
在添加及删除成功后的代码中,两次使用了“pack()”语句,其作用是,当添加或删除成功后,其JComboBox的宽度可能会有所改变,为了不影响其他组件的显示效果,需要使用“pack()”语句使窗体重新调整大小以适应所有组件的显示。
8.4.4 JList列表框
JList又叫列表框,它和下拉列表有许多不同之处。JList在界面上占据固定行数,既支持单项选择,也支持多项选择(连续区间选择需按住Shift键选择,不连续区间选择需 按住Ctrl键选择)。而JComboBox一次则只能选择一项。
JList提供了多个构造方法用于 创建JList类对象,详见下表8-11。
表8-11 JList构造方法
构造方法 | 说明 |
JList() | 构造一个空的JList对象 |
JList(ListModel dataModel) | 使用dataModel模式构造一个JList对象 |
JList(Object[] listData) | 使用listData数组构造一个JList对象 |
JList(Vector listData) | 使用listData向量数组构造一个JList对象 |
与JComboBox不同,JList类没有提供任何添加、插入和删除项的方法,在完成JList的构造后,唯一可以修改数据的方法时setListDate(),这个方法可以一次指定所有的项。
JList类中常用的成员方法如下表8-12。
表8-12 JList常用成员方法
成员方法 | 说明 |
int getSelectedIndex() | 获取所有选项最小下标 |
int[] getSelectedIndices() | 获取所有选项的下标(按升序排列) |
void setSelectionMode(int selectionMode) | 设置列表的选择模,selectionMode值见说明 |
void setVisibleRowCount(int visibleRowCount) | 设置列表的可见行数 |
说明:selectionMode的值有以下可选值。
(1)ListSelectionModel.SINGLE_SELECTION :一次只能选择一个列表索引。
(2)ListSelectionModel.SINGLE_INTERVAL_SELECTION: 只允许选择连续范围内的多个项,可通过按住Shift键的方式选择。
(3)ListSelectionModel.MULTIPLE_INTERVAL_SELECTION: 列表框的默认模式,既可选择连续范围内的多个项,也可选择不连续的多个项。
JList从够响应两个事件:ListSeletionEvent和MouseEvent,,要处理这两个事件,需要创建相应的类实现ListSeletionListener 和MouseListener接口(或是继承MouseAdapter)。ListSeletionEvent触发的时机是当用户单击列表框中的某一个选项并选中它时,MouseEvent触发的时机是当用户双击列表框中的某个选项时。
JList本身是不带滚动条的,如果将JList放到JScrollPane(滚动面板)中,则会是JList带有滚动条效果。
例8-7演示了JList的创建、显示及对ListSeletionEvent事件的处理情况。
[例8-7]
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
class JListTest extends JFrame{
private JList list = new JList();
private JTextArea ta = new JTextArea(6,8);
public JListTest(String title){
super(title);
String[] citys =
{"北京","天津","上海","广州","深圳","南京","重庆","沈阳","西安"};
list.setListData(citys);
Container contentPane = this.getContentPane();
contentPane.setLayout(new FlowLayout(5));//在界面上显示5行
list.setVisibleRowCount(5);
contentPane.add(new JScrollPane(list));//使JList带有滚动条
contentPane.add(ta);
//注册监听器
list.addListSelectionListener(new MyListSelectionListener());
pack();//重新调整
setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//处理ListSelection事件
private class MyListSelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent arg0) {
StringBuffer selectedCitys = new StringBuffer();
Object[] selectedItems = list.getSelectedValues();
for(int i=0;i selectedCitys.append(selectedItems[i].toString()+"");
}
ta.setText(selectedCitys.toString());
pack();
}
}
}
public class Test8_7 {
public static void main(String[] args) {
new JListTest("JList测试");
}
}
运行结果如图8-8所示
图8-8 例8-7运行结果
程序中对ListSeletionEvent做了处理,对于另一个事件MouseEvent,因为其有多个抽象方法,因此建议使用 继承MouseAdapter的方式去处理。