12.9 使用JList,JComboBox创建列表框 12.9.1 简单列表框

12.9 使用JList,JComboBox创建列表框

无论从哪个角度来看,JListJComboBox都是极其相似的,它们都有一个列表框,只是JComboBox的列表框需要以下拉方式显示出来;JListJComboBox都可以通过调用setRenderer()方法来改变列表项的表现形式。甚至维护这两个组件的Model都是相似的,JList使用ListModel,JComboBox使用ComboBoxModel,而ComboBoxModelListModel的子类。

12.9.1 简单列表框

如果仅仅希望创建一个简单的列表框(包括JListJComboBox),则直接使用它们的构造器即可,它们的构造器都可接收一个对象数组或元素类型任意的Vector作为参数,这个对象数组或元素类型任意的Vector里的所有元素将转换为列表框的列表项。

创建简单列表框步骤

使用JLitJComboBox来创建简单列表框非常简单,只需要按如下步骤进行即可

创建列表框对象

  1. 使用JList或者JComboBox的构造器创建一个列表框对象,创建JListJComboBox时,应该传入一个Vector对象或者Object数组作为构造器参数,其中使用JCombobox创建的列表框必须单击右边的向下箭头才会出现。

设置列表框的外观行为

  1. 调用JListJComboBox的各种方法来设置列表框的外观行为,其中

JList常用设置外观的方法

JList可以调用如下几个常用的方法。

方法 描述
void addSelectionInterval(int anchor, int lead) 在已经选中列表项的基础上增加选中从anchorlead索引范围内的所有列表项。
void setFixedCellHeight(int height) 设置列表项的高度
void setFixedCellWidth(int width) 设置列表项的宽度
void setLayoutOrientation(int layoutOrientation) 设置列表框的布局方向,该属性可以接收三个值,即JList.HORIZONTAL_WRAPJList.VERTICAL_WRAPJList.VERTICAL(默认),用于指定当列表框长度不足以显示所有的列表项时,列表框如何排列所有的列表项。
void setSelectedIndex(int index) 设置默认选择哪一个列表项
void setSelectedIndices(int[] indices) 设置默认选择哪一批列表项
void setSelectedValue(Object anObject, boolean shouldScroll) 设置选中哪个列表项的值,第二个参数决定是否滚动到选中项。
void setSelectionBackground(Color selectionBackground) 设置选中项的背景色。
void setSelectionForeground(Color selectionForeground) 设置选中项的前景色。
void setSelectionInterval(int anchor, int lead) 设置选中从anchorlead索引范围内的所有列表项
void setSelectionMode(int selectionMode) 设置选中模式。支持如下3个值。
  • ListSelectionModel.SINGLE_SELECTION:每次只能选择一个列表项。在这种模式中setSelectionIntervaladdSelectionInterval是等效的
  • ListSelectionModel.SINGLE_INTERVAL_SELECTION:每次只能选择一个连续区域。在此模式中,如果需要添加的区域没有与已选择区域相邻或重叠,则不能添加该区域。简而言之,在这种模式下每次可以选择多个列表项,但多个列表项必须处于连续状态。
  • ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:在此模式中,选择没有任何限制。该模式是默认设置
void setVisibleRowCount(int visibleRowCount) 设置该列表框的可视高度足以显示多少项

JComboBox常用设置外观的方法

JComboBox则提供了如下几个常用方法。

方法 描述
void setEditable(boolean aFlag) 设置是否允许直接修改JComboBox文本框的值,默认不允许
void setMaximumRowCount(int count) 设置下拉列表框的可视高度可以显示多少个列表项
void setSelectedIndex(int anIndex) 根据索引设置默认选中哪一个列表项。
void setSelectedItem(Object anObject) 根据列表项的值设置默认选中哪一个列表项

JComboBox没有设置选择模式的方法,因为JComboBox最多只能选中一项,所以没有必要设置选择模式

监听事件

如果需要监听列表框选择项的变化,则可以通过添加对应的监听器来实现。通常

  • JList使用addListSelectionListener()方法添加监听器,
  • JComboBox采用addItemListener()方法添加监听器。

程序 JList和JCombox

下面程序示范了JListJCombox的用法,并允许用户通过单选按钮来控制JList的选项布局、选择模式,在用户选择图书之后,这些图书会在窗口下面的文本域里显示出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import java.util.*;
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.border.*;

public class ListTest {
private JFrame mainWin = new JFrame("测试列表框");
String[] books = new String[] { "疯狂Java讲义", "轻量级Java EE企业应用实战", "疯狂Android讲义", "疯狂Ajax讲义", "经典Java EE企业应用实战" };
// 用一个字符串数组来创建一个JList对象
JList<String> bookList = new JList<>(books);
JComboBox<String> bookSelector;
// 定义布局选择按钮所在的面板
JPanel layoutPanel = new JPanel();
ButtonGroup layoutGroup = new ButtonGroup();
// 定义选择模式按钮所在的面板
JPanel selectModePanel = new JPanel();
ButtonGroup selectModeGroup = new ButtonGroup();
JTextArea favoriate = new JTextArea(4, 40);

public void init() {
// 设置JList的可视高度可同时显示三个列表项
bookList.setVisibleRowCount(3);
// 默认选中第三项到第五项(第一项的索引是0)
bookList.setSelectionInterval(2, 4);
addLayoutButton("纵向滚动", JList.VERTICAL);
addLayoutButton("纵向换行", JList.VERTICAL_WRAP);
addLayoutButton("横向换行", JList.HORIZONTAL_WRAP);
addSelectModelButton("无限制", ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
addSelectModelButton("单选", ListSelectionModel.SINGLE_SELECTION);
addSelectModelButton("单范围", ListSelectionModel.SINGLE_INTERVAL_SELECTION);
Box listBox = new Box(BoxLayout.Y_AXIS);
// 将JList组件放在JScrollPane中,再将该JScrollPane添加到listBox容器中
listBox.add(new JScrollPane(bookList));
// 添加布局选择按钮面板、选择模式按钮面板
listBox.add(layoutPanel);
listBox.add(selectModePanel);
// 为JList添加事件监听器
bookList.addListSelectionListener(e -> { // ①
// 获取用户所选择的所有图书
List<String> books = bookList.getSelectedValuesList();
favoriate.setText("");
for (String book : books) {
favoriate.append(book + "\n");
}
});
Vector<String> bookCollection = new Vector<>();
bookCollection.add("疯狂Java讲义");
bookCollection.add("轻量级Java EE企业应用实战");
bookCollection.add("疯狂Android讲义");
bookCollection.add("疯狂Ajax讲义");
bookCollection.add("经典Java EE企业应用实战");
// 用一个Vector对象来创建一个JComboBox对象
bookSelector = new JComboBox<>(bookCollection);
// 为JComboBox添加事件监听器
bookSelector.addItemListener(e -> { // ②
// 获取JComboBox所选中的项
Object book = bookSelector.getSelectedItem();
favoriate.setText(book.toString());
});
// 设置可以直接编辑
bookSelector.setEditable(true);
// 设置下拉列表框的可视高度可同时显示4个列表项
bookSelector.setMaximumRowCount(4);
JPanel p = new JPanel();
p.add(bookSelector);
Box box = new Box(BoxLayout.X_AXIS);
box.add(listBox);
box.add(p);
mainWin.add(box);
JPanel favoriatePanel = new JPanel();
favoriatePanel.setLayout(new BorderLayout());
favoriatePanel.add(new JScrollPane(favoriate));
favoriatePanel.add(new JLabel("您喜欢的图书:"), BorderLayout.NORTH);
mainWin.add(favoriatePanel, BorderLayout.SOUTH);
mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWin.pack();
mainWin.setVisible(true);
}

private void addLayoutButton(String label, final int orientation) {
layoutPanel.setBorder(new TitledBorder(new EtchedBorder(), "确定选项布局"));
JRadioButton button = new JRadioButton(label);
// 把该单选按钮添加到layoutPanel面板中
layoutPanel.add(button);
// 默认选中第一个按钮
if (layoutGroup.getButtonCount() == 0)
button.setSelected(true);
layoutGroup.add(button);
button.addActionListener(event ->
// 改变列表框里列表项的布局方向
bookList.setLayoutOrientation(orientation));
}

private void addSelectModelButton(String label, final int selectModel) {
selectModePanel.setBorder(new TitledBorder(new EtchedBorder(), "确定选择模式"));
JRadioButton button = new JRadioButton(label);
// 把该单选按钮添加到selectModePanel面板中
selectModePanel.add(button);
// 默认选中第一个按钮
if (selectModeGroup.getButtonCount() == 0)
button.setSelected(true);
selectModeGroup.add(button);
button.addActionListener(event ->
// 改变列表框里的选择模式
bookList.setSelectionMode(selectModel));
}

public static void main(String[] args) {
new ListTest().init();
}
}

上面程序中实现了使用字符串数组创建个JList对象,并通过调用一些方法来改变该JList的表现外观;使用Vector创建一个JComboBox对象,并通过调用些方法来改变该JComboBox的表现外观
程序中①②号代码为JList对象和JComboBox对象添加事件监听器,当用户改变两个列表框里的选择时,程序会把用户选择的图书显示在下面的文本域内。运行上面程序,会看到如图12.34所示的效果。

从图12.34中可以看出,因为JComboBox设置了seteditable(true),所以可以直接在该组件中输入用户自己喜欢的图书,当输入结束后,输入的图书名会直接显示在窗口下面的文本域内。

通常会将JList放到JScrollPane中

JList默认没有滚动条,必须将其放在JScrollpane中才有滚动条,通常总是将JList放在JScrollPane中使用,所以程序中先将JList放到JScrollPane容器中,再将该JScrollPane添加到窗口中。
要在JList中选中多个选项,可以使用CtrlShift辅助键:

  • 按住Ctrl键才可以在原来选中的列表项基础上添加选中新的列表项;
  • Shift键可以选中连续区域的所有列表项。