Java开发笔记(一百三十一)Swing的列表框
前面介绍了选择框的用法,当时为了方便用户勾勾点点,无论是复选框还是单选按钮,统统把所有选项都摆在界面上。倘若只有两三个选项还好办,要是选项数量变多比如超过五个,这么多的选择框一齐在界面罗列,不光程序员排版费劲,用户瞅着也容易眼花。鉴于这些选择框往往选完一次就了事,难得有重新选择第二次的机会,因而在界面上全部铺开这些选择框实属浪费。更好的做法是在选择的时候才展开所有选项,选完之后就缩回只显示选中的那一项,一伸一缩之间才能充分利用有限的屏幕界面。
以单选按钮的组合为例,许多个单选按钮只能选择其中一个,这种情况就很适合展开与收缩的处理逻辑。Swing给该场景提供了专门的下拉框控件JComboBox,为了往下拉框塞进各个选项,还需要将它与下拉框模型DefaultComboBoxModel搭配使用才行。下拉框具体的调用过程分为下列三个步骤:
1、创建一个下拉框模型,并调用模型对象的addElement方法依次添加每个选项;
2、创建一个下拉框控件,注意要在JComboBox的构造方法中填入第一步的模型对象;
3、调用下拉框对象的addItemListener方法给它添加一个点击监听器,每当用户在下拉面板中选择某一项,都会触发监听器的itemStateChanged方法。此时即可通过下拉框对象的getSelectedIndex方法获得选中项的序号,还可通过getSelectedItem方法获得选中项的对象。
下面是利用JComboBox实现下拉选择功能的代码例子:
JPanel panelTop = new JPanel(); // 创建顶部面板
// 创建一个下拉框模型
DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<String>();
comboModel.addElement("鱼香肉丝饭"); // 往下拉模型中添加元素
comboModel.addElement("香菇滑鸡饭"); // 往下拉模型中添加元素
comboModel.addElement("黑椒牛排饭"); // 往下拉模型中添加元素
comboModel.addElement("梅菜扣肉饭"); // 往下拉模型中添加元素
comboModel.addElement("糖醋里脊饭"); // 往下拉模型中添加元素
comboModel.addElement("红烧排骨饭"); // 往下拉模型中添加元素
comboModel.addElement("台式卤肉饭"); // 往下拉模型中添加元素
JComboBox<String> comboBox = new JComboBox<String>(comboModel); // 创建一个下拉框
panelTop.add(comboBox); // 在顶部面板上添加下拉框
frame.add(panelTop, BorderLayout.NORTH); // 把顶部面板添加到窗口的北边(上方)
comboBox.setEditable(false); // 设置下拉框能否编辑。默认不允许编辑
comboBox.addItemListener(new ItemListener() { // 给下拉框添加一个点击监听器
public void itemStateChanged(ItemEvent e) { // 下拉框被选择
// 获取下拉框内选中项的序号及其描述
// getSelectedIndex方法可获得选中项的序号,getSelectedItem方法可获得选中项的对象
String desc = String.format("您点了第%d项,套餐名称是%s",
comboBox.getSelectedIndex(), comboBox.getSelectedItem().toString());
label.setText(desc); // 在标签上显示当前选中的文本项
}
});
运行上面的下拉框代码,弹出如下图所示的窗口界面,可见一开始下拉框只占据长条般的空间,并且默认展示第一个选项。

接着单击下拉框的长条区域,界面会向下弹出包含所有选项的下拉面板,选中面板上的某一项后,下拉面板消失不见,同时长条框内的文字变成了刚才选中项的文本。选择前后的窗口界面分别如以下两张图所示。


虽然下拉框比起单选按钮组合要节省屏幕空间,但它的实现机制也导致了如下几点局限:
1、下拉框只实现了单选功能,不支持多选功能,无法同时选择好几个选项;
2、重新选择之时,要先点一下长条区域,才能在弹出的下拉面板中挑选新的选项,简简单单的选择操作也花费了两个步骤,甚不经济;
以上两点局限的起因,皆来源于下拉面板的弹出与缩回机制,每次都要单击长条框才会弹出下拉面板,单击选中某一项后又会自动关闭下拉面板,正是这种单次点击单次响应的行为决定了下拉框只能用于单选操作,而不能用于多选操作。要想实现多选功能,还得将所有选项铺开展示,就像文件列表那样,用户才能按下Ctrl键逐个选中,或者按下Shift键选择一段连续的数个选项。这种平铺直叙所有选项的控件也叫列表框,对应于Swing中的JList类型,列表框的用法类似下拉框,它的调用过程依然分为以下三个步骤:
1、创建一个列表框模型DefaultListModel,并调用模型对象的addElement方法依次添加每个选项;
2、创建一个列表框控件,注意要在JList的构造方法中填入第一步的模型对象;
3、调用列表框对象的addListSelectionListener方法给它添加一个点击监听器,每当用户单击列表框中的某一项,都会触发监听器的valueChanged方法。此时即可通过列表框对象的getSelectedIndex方法获得选中项的序号,通过getSelectedValue方法获得选中项的值,还能通过getSelectedValuesList方法获得所有选中项的值列表。
下面是利用JList实现多次选择功能的代码例子:
JPanel panelLeft = new JPanel(); // 创建左边面板
// 创建一个列表框模型
DefaultListModel<String> listModel = new DefaultListModel<String>();
listModel.addElement("鱼香肉丝饭"); // 往列表模型中添加元素
listModel.addElement("香菇滑鸡饭"); // 往列表模型中添加元素
listModel.addElement("黑椒牛排饭"); // 往列表模型中添加元素
listModel.addElement("梅菜扣肉饭"); // 往列表模型中添加元素
listModel.addElement("糖醋里脊饭"); // 往列表模型中添加元素
listModel.addElement("红烧排骨饭"); // 往列表模型中添加元素
listModel.addElement("台式卤肉饭"); // 往列表模型中添加元素
JList<String> listBox = new JList<String>(listModel); // 创建一个列表框
panelLeft.add(listBox); // 在顶部面板上添加列表框
frame.add(panelLeft, BorderLayout.WEST); // 把顶部面板添加到窗口的西边(左侧)
listBox.addListSelectionListener(new ListSelectionListener() { // 给列表框添加一个点击监听器
public void valueChanged(ListSelectionEvent arg0) { // 列表框被选择
// 获取列表框内选中项的序号及其描述
// getSelectedIndex方法可获得选中项的序号,getSelectedValue方法可获得选中项的值
String desc = String.format("您点了第%d项,套餐名称是%s",
listBox.getSelectedIndex(), listBox.getSelectedValue());
labelBottom.setText(desc); // 在标签上显示当前选中的文本项
String total = "<html>您已选择的套餐列表如下:<br>";
// 获取列表框内的所有选择项,并拼接html格式的描述串
for (String str : listBox.getSelectedValuesList()) {
total = String.format("%s<center>%s</center>", total, str);
}
total += "</html>";
labelCenter.setText(total); // 在标签上显示所有选中的文本项
}
});
运行以上的列表框代码,弹出如下图所示的窗口界面,可见列表框一开始就展示了所有选项。

然后按住Ctrl键,从下往上依次单击选中第七项、第五项、第三项、第一项,每次单击之后的界面效果分别如以下四张图片所示。




从这些效果图可以看到,在按住Ctrl键的时候,列表框可以实现多选功能;未按住Ctrl键的时候,列表框变成实现单选功能。
更多Java技术文章参见《Java开发笔记(序)章节目录》
Java开发笔记(一百三十一)Swing的列表框的更多相关文章
- Java开发笔记(三十一)字符类型的表达
前面介绍的Java编程,要么是与数字有关的计算,要么是与逻辑有关的推理,充其量只能实现计算器和状态机.若想让Java运用于更广阔的业务领域,就得使其支撑更加血肉丰满的业务场景,而丰满的前提是能够表达大 ...
- Java开发笔记(三十八)利用正则表达式校验字符串
前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...
- Java开发笔记(八十一)如何使用系统自带的注解
之前介绍继承的时候,提到对于子类而言,父类的普通方法可以重写也可以不重写,但是父类的抽象方法是必须重写的,如果不重写,编译器就直接在子类名称那里显示红叉报错.例如,以前演示抽象类用法之时,曾经把Chi ...
- Java开发笔记(三十)大小数BigDecimal
前面介绍的BigInteger只能表达任意整数,但不能表达小数,要想表达任意小数,还需专门的大小数类型BigDecimal.如果说设计BigInteger的目的是替代int和long类型,那么设计Bi ...
- Java开发笔记(三十四)字符串的赋值及类型转换
不管是基本的char字符型,还是包装字符类型Character,它们的每个变量只能存放一个字符,无法满足对一串字符的加工.为了能够直接操作一连串的字符,Java设计了专门的字符串类型String,该类 ...
- Java开发笔记(三十五)字符串格式化
前面介绍了字符串变量的四种赋值方式,对于简单的赋值来说完全够用了,即便是两个字符串拼接,也只需通过加号把两个目标串连起来即可.但对于复杂的赋值来说就麻烦了,假设现在需要拼接一个很长的字符串,字符串内部 ...
- Java开发笔记(三十六)字符串的常用方法
不管是给字符串赋值,还是对字符串格式化,都属于往字符串填充内容,一旦内容填充完毕,则需开展进一步的处理.譬如一段Word文本,常见的加工操作就有查找.替换.追加.截取等等,按照字符串的处理结果异同,可 ...
- Java开发笔记(三十七)利用正则串分割字符串
前面介绍了处理字符串的常用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串.分割规则通常是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号.空格等等都可 ...
- Java开发笔记(三十九)日期工具Date
Date是Java最早的日期工具,编程中经常通过它来获取系统的当前时间.当然使用Date也很简单,只要一个new关键字就能创建日期实例,就像以下代码示范的那样: // 创建一个新的日期实例,默认保存的 ...
- Java开发笔记(四十一)日历工具Calendar
前面的文章提到,Date是Java最早的日期工具,估计当时的设计师是个技术宅男,未经过充分调研就拍脑袋写下了Date的源码,造成该工具存在先天不足,比如getYear方法返回的不是纯正的公元纪年.ge ...
随机推荐
- Java方法覆盖重写
方法覆盖重写注意事项: 1.必须保证方法名相同,返回值也相同 @Override:写在方法前面,用来检测方法的覆盖重写是否有效,这个注解不是必要的,就算不写,方法覆盖重写符合要求也是正确的 2. ...
- webpack的plugin原理
plugin是webpack生态的重要组成,它为用户提供了一种可以直接访问到webpack编译过程的方式.它可以访问到编译过程触发的所有关键事件. 1. 基本概念 1. 如何实现一个插件 1. plu ...
- Java Web 项目的文件/文件夹上传下载
需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...
- git version info & svn version info map(七)
To generate the same version number as SVN, we can generate the same version number as SVN with the ...
- 使用rrweb 进行web 操作录制以及回放
rrweb 是使用typescript 开发的web 操作录制以及回放框架,包含了比较完整的系统组件 rrweb-snapshot 进行dom 与操作实践的关联处理 rrweb 主要包含了record ...
- CF1098E Fedya the Potter
CF1098E Fedya the Potter 题意:有一个序列\(A\). 对所有\(1\leq l\leq r\leq |A|\),将\(\gcd_{i=l}^{r}A_i\)加入\(B\)中. ...
- P2388 阶乘之乘
首先感谢wxy学长之前告诉我这道题,结果今天竟然一眼切了,咕咕咕 题目链接: P2388 阶乘之乘 题目思路: 第一眼看到一定想到的是先求一下阶乘然后看最后又几个零,但是这样会TIL啊 想一下0是怎么 ...
- 【后缀数组】【SP1811】 LCS - Longest Common Substring
题目链接 题意翻译 输入2 个长度不大于250000的字符串,输出这2 个字符串的最长公共子串.如果没有公共子串则输出0 . 思路 求两个串的最长公共子串 代码 #include<iostrea ...
- [C++] 对象指针使用方法
对象指针:指向类对象的指针 类指针指向类变量(对象)的地址 对象指针定义格式: 类类型 *变量名: 举例: #include <iostream> using namespace std; ...
- 【mybatis源码学习】mybatis的结果映射
一.mybatis结果映射的流程 二.mybatis结果映射重要的类 1.org.apache.ibatis.executor.resultset.ResultSetWrapper(对sql执行返回的 ...