【Swing】Java Swing实现省市区选择编辑器
【Swing】Java Swing实现省市区选择编辑器
- 1.需求描述
- 2.需求实现
- 3.效果展示
系统:Win10
JDK:1.8.0_351
IDEA:2022.3.3
1.需求描述
在公司的一个 Swing 的项目上需要实现一个选择省市区的编辑器,这还是第一次做这种编辑器,在前端实现各种地区选择编辑器都比较常见,反而是 Swing 实现还是第一次,故将结果记录下来。
2.需求实现
地区选择从原理上来看很简单,通过级联的方式,将某个对象的所属对象数据展示出来,比如先选择省,就将省下的市等数据展示出来再选。
在 Swing 里我选择使用JPopupMenu 的方式来展示省市区的选择,相对于JDialog 来说,JPopupMenu 的级联操作更加简单一点。
实现代码如下:
import com.lijinjiang.beautyeye.BeautyEyeLNFHelper;import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;/*** @Description 地址选择器demo* @Author 03010430* @ModifyDate 2024/3/13 13:20*/
public class CityPickerDemo {public static JTextField textField;public static JPopupMenu popupMenu;public static DefaultListModel<String> provinceModel;public static JList<String> provinceList;//省份列表public static DefaultListModel<String> cityModel;public static JList<String> cityList;//城市列表public static DefaultListModel<String> districtModel;public static JList<String> districtList;//区县列表public static boolean haveInit;//初始化完毕public static void main(String[] args) {try {BeautyEyeLNFHelper.frameBorderStyle = BeautyEyeLNFHelper.FrameBorderStyle.generalNoTranslucencyShadow;BeautyEyeLNFHelper.launchBeautyEyeLNF();} catch (Exception e) {e.printStackTrace();}JFrame frame = new JFrame();JPanel panel = new JPanel(null);JLabel label = new JLabel("选择地址");label.setBounds(10, 30, 80, 36);panel.add(label);textField = new JTextField();textField.setEditable(false);textField.setBounds(100, 30, 270, 36);textField.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {clickFieldAction();}});panel.add(textField);frame.add(panel);frame.setSize(400, 150);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认关闭操作frame.setVisible(true);}public static void clickFieldAction() {popupMenu = new JPopupMenu();//初始化菜单面板provinceModel = new DefaultListModel<>();provinceList = new JList<>(provinceModel);//省份列表cityModel = new DefaultListModel<>();cityList = new JList<>(cityModel);//城市列表districtModel = new DefaultListModel<>();districtList = new JList<>(districtModel);//区县列表haveInit = false;//初始化赋值popupMenu.setLayout(new GridLayout(1, 3));//添加省份模块JScrollPane scrollPane1 = new JScrollPane(provinceList);scrollPane1.setBorder(BorderFactory.createTitledBorder("省级"));popupMenu.add(scrollPane1);//添加城市模块JScrollPane scrollPane2 = new JScrollPane(cityList);scrollPane2.setBorder(BorderFactory.createTitledBorder("地级/县级"));popupMenu.add(scrollPane2);//添加区县模块JScrollPane scrollPane3 = new JScrollPane(districtList);scrollPane3.setBorder(BorderFactory.createTitledBorder("县级"));popupMenu.add(scrollPane3);String text = textField.getText();if (text != null && !text.isEmpty()) {initProvinceData();String[] arr = text.trim().split("/");if (arr.length > 0) {String oldProvince = arr[0];if (provinceModel.contains(oldProvince)) {provinceList.setSelectedValue(oldProvince, true);}if (arr.length > 1) {String oldCity = arr[1];if (cityModel.contains(oldCity)) {cityList.setSelectedValue(oldCity, true);}if (arr.length > 2) {String oldDistrict = arr[2];if (districtModel.contains(oldDistrict)) {districtList.setSelectedValue(oldDistrict, true);}}}}} else {initProvinceData();//初始化省份列表}haveInit = true;//标识初始化结束showPopupMenu(textField, popupMenu);}//第一级:省级public static void initProvinceData() {try {List<String> list = getProvinceData();//模拟省份数据for (String str : list) {provinceModel.addElement(str);}//添加事件监听provinceList.addListSelectionListener(e -> {String province = provinceList.getSelectedValue();if (province != null && !province.isEmpty()) {initCityData(province);}});} catch (Exception e) {throw new RuntimeException(e);}}//第二级:地级/县级public static void initCityData(String province) {try {cityModel.removeAllElements();//清空城市数据districtModel.removeAllElements();//清空区县数据List<String> list = getCityData(province);//模拟城市数据if (haveInit && list.size() == 0) {//第二级没有数据时,直接第一级的数据填写上textField.setText(province);//取值popupMenu.setVisible(false); //隐藏菜单popupMenu.removeAll(); //移除所有菜单项} else {for (String str : list) {cityModel.addElement(str);}//添加事件监听cityList.addListSelectionListener(e -> {String selectedProvince = provinceList.getSelectedValue();String selectedCity = cityList.getSelectedValue();if (selectedCity != null && !selectedCity.isEmpty()) {initDistrictData(selectedProvince, selectedCity);}});}} catch (Exception e) {throw new RuntimeException(e);}}public static void initDistrictData(String province, String city) {try {districtModel.removeAllElements();//先清空区县数据List<String> list = getDistrictData(province,city);//模拟区县数据if (haveInit && list.size() == 0) {//区县没有数据时,直接将市的数据填写上String value = province + "/" + city;textField.setText(value);//取值popupMenu.setVisible(false); //隐藏菜单popupMenu.removeAll(); //移除所有菜单项} else {for (String str : list) {districtModel.addElement(str);}//添加事件监听districtList.addListSelectionListener(e -> {if (haveInit) {String selectedDistrict = districtList.getSelectedValue();if (selectedDistrict != null && !selectedDistrict.isEmpty()) {String selectedProvince = provinceList.getSelectedValue();String selectedCity = cityList.getSelectedValue();String value = selectedProvince + "/" + selectedCity + "/" + selectedDistrict;textField.setText(value);//取值popupMenu.setVisible(false); //隐藏菜单popupMenu.removeAll(); //移除所有菜单项}}});}} catch (Exception e) {throw new RuntimeException(e);}}//点击按钮事件,继承该类的编辑器都要复写改代码public static void showPopupMenu(JComponent parent, JPopupMenu popupMenu) {GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();Rectangle maximumWindowBounds = graphicsEnvironment.getMaximumWindowBounds();double deskHeight = maximumWindowBounds.getHeight();//桌面高度(不包括任务栏)int width = parent.getWidth();if (width < 400) {width = 400;}popupMenu.setPreferredSize(new Dimension(width, 200));int popupMenuBottom = parent.getLocationOnScreen().y + parent.getHeight() + 200;if (deskHeight < popupMenuBottom) {//超出桌面高度显示在输入框上面popupMenu.show(parent, parent.getWidth() - width, -200);} else {popupMenu.show(parent, 0, parent.getHeight());}}//模拟省份数据private static List<String> getProvinceData() {List<String> list = new ArrayList<>();list.add("北京市");list.add("上海市");list.add("江西省");list.add("福建省");list.add("浙江省");list.add("江苏省");list.add("河北省");list.add("安徽省");list.add("台湾省");return list;}//模拟城市数据private static List<String> getCityData(String province) {List<String> list = new ArrayList<>();switch (province) {case "北京市": {list.add("东城区");list.add("西城区");list.add("朝阳区");break;}case "上海市": {list.add("黄浦区");list.add("徐汇区");list.add("长宁区");list.add("静安区");break;}case "江西省": {list.add("南昌市");list.add("景德镇市");list.add("萍乡市");list.add("九江市");list.add("新余市");list.add("鹰潭市");list.add("赣州市");list.add("吉安市");list.add("宜春市");list.add("抚州市");list.add("上饶市");break;}case "福建省": {list.add("福州市");list.add("厦门市");list.add("莆田市");break;}default:break;}return list;}private static List<String> getDistrictData(String province, String city) {List<String> list = new ArrayList<>();if ("江西省".equals(province)){if ("南昌市".equals(city)){list.add("东湖区");list.add("西湖区");list.add("青云谱区");list.add("青山湖区");list.add("新建区");list.add("红谷滩区");list.add("南昌县");list.add("安义县");list.add("进贤县");} else if ("上饶市".equals(city)){list.add("信州区");list.add("广丰区");list.add("广信区");list.add("玉山县");list.add("铅山县");list.add("横峰县");list.add("弋阳县");list.add("余干县");list.add("鄱阳县");list.add("万年县");list.add("婺源县");list.add("德兴市");}}return list;}
}
3.效果展示
我这里测试代码中的数据只模拟了一部分数据,在生产中根据实际接口获取数据。这里推荐使用 2022年中华人民共和国县以上行政区划代码 国家区划数据

相关文章:
【Swing】Java Swing实现省市区选择编辑器
【Swing】Java Swing实现省市区选择编辑器 1.需求描述2.需求实现3.效果展示 系统:Win10 JDK:1.8.0_351 IDEA:2022.3.3 1.需求描述 在公司的一个 Swing 的项目上需要实现一个选择省市区的编辑器,这还是第一次做这种编辑器…...
spring suite搭建springboot操作
一、前言 有时候久了没开新项目了,重新开发一个新项目,搭建springboot的过程都有点淡忘了,所有温故知新。 二、搭建步骤 从0开始搭建springboot 1.创建work空间。步骤FileNewJava Working Set。 2.选择Java Working Set。 3.自…...
mysql重构
力扣题目链接 列转行 SELECT product_id, store1 store, store1 price FROM products WHERE store1 IS NOT NULL UNION SELECT product_id, store2 store, store2 price FROM products WHERE store2 IS NOT NULL UNION SELECT product_id, store3 store, store3 price FROM p…...
Linux用户、用户组
用户管理命令: 首先要先知道两个配置文件:/etc/group 用户组配置文件/etc/passwd 保存了所有用户的用于读取的必要信息**/etc/shadow **是 Linux 系统中用于存储用户密码信息的文件。这个文件也被称为“影子文件”,因为它包含了 /etc/passwd…...
操作系统系列学习——信号量的代码实现
文章目录 前言信号量的代码实现 前言 一个本硕双非的小菜鸡,备战24年秋招,计划学习操作系统并完成6.0S81,加油! 本文总结自B站【哈工大】操作系统 李治军(全32讲) 老师课程讲的非常好,感谢 【哈…...
【Python操作基础】——变量操作
🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享 擅长Python、Matlab、R等主流编程软件 累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…...
滑模控制算法(SMC)讲解-案例(附C代码)
目录 一、滑模控制算法的基本原理 1)滑模面(Sliding Surface)的设计 2)达到条件(Reaching Condition)...
Redis数据结构对象之集合对象和有序集合对象
集合对象 集合对象的编码可以是intset或者hashtable. 概述 intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面。 另一方面,hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个…...
不要百花齐放
javascript中数组的遍历有如下方法: 1、for (var i 0; i < arr.length; i) 2、for(var item of arr) 3、for(var item in arr) 4、arr.forEach 5、arr.map 6、arr.filter 7、arr.find 8、arr.findIndex 9、arr.indexOf arr.lastIndexOf 10、arr.every…...
使用Java JDBC连接数据库
在Java应用程序中,与数据库交互是一个常见的任务。Java数据库连接(JDBC)是一种用于在Java应用程序和数据库之间建立连接并执行SQL查询的标准API。通过JDBC,您可以轻松地执行各种数据库操作,如插入、更新、删除和查询数…...
阿里云2核4G4M轻量应用服务器价格165元一年
阿里云优惠活动,2核4G4M轻量应用服务器价格165元一年,4Mbps带宽下载速度峰值可达512KB/秒,系统盘是60GB高效云盘,不限制月流量,2核2G3M带宽轻量服务器一年87元12个月,在阿里云CLUB中心查看 aliyun.club 当前…...
连续纯合片段(runs of homozygosity, ROH)的原理
连续纯合片段(Runs of Homozygosity, ROH)的原理及其结果查看方式包含以下几个方面: 原理 定义和识别: ROH是指基因组中由相同祖先遗传下来的连续纯合等位基因组成的片段。它们可以通过比较个体基因组上的等位基因序列来识别。当…...
UCORE 清华大学os实验 lab0 环境配置
打卡 lab 0 : 环境配置 : 首先在ubt 上的环境,可以用虚拟机或者直接在windows 上面配置 然后需要很多工具 如 qemu gdb cmake git 就是中间犯了错误,误以为下载的安装包,一直解压不掉,结果用gpt 检查 结…...
linux 安装常用软件
文件传输工具 sudo yum install –y lrzsz vim编辑器 sudo yum install -y vimDNS 查询 sudo yum install bind-utils用法可以参考文章 《掌握 DNS 查询技巧,dig 命令基本用法》 net-tools包 yum install net-tools -y简单用法: # 查看端口占用情况…...
OpenMP使用教程:入门到精通
在并行编程的领域中,OpenMP无疑是一个强大而又便捷的工具,它让程序员能够以最少的努力实现程序的并行化。本文将详细介绍OpenMP的基本概念、环境配置、核心指令以及实际代码示例,旨在帮助读者从入门到精通OpenMP的使用。 什么是OpenMP&#…...
华为组网:核心交换机旁挂防火墙,基于ACL重定向配置实验
如图所示,由于业务需要,用户有访问Internet的需求。 用户通过接入层交换机SwitchB和核心层交换机SwitchA以及接入网关Router与Internet进行通信。为了保证数据和网络的安全性,用户希望保证Internet到服务器全部流量的安全性,配置重…...
HarmonyOS NEXT应用开发—投票动效实现案例
介绍 本示例介绍使用绘制组件中的Polygon组件配合使用显式动画以及borderRadius实现投票pk组件。 效果预览图 使用说明 加载完成后会有一个胶囊块被切割成两个等大的图形来作为投票的两个选项,中间由PK两字分隔开点击左边选项,两个图形会随着选择人数…...
服务器端(Debian 12)配置jupyter与R 语言的融合
融合前: 服务器端Debian 12,域名:www.leyuxy.online 1.安装r-base #apt install r-base 2.进入R并安装IRkernel #R >install.packages(“IRkernel”) 3.通过jupyter notebook的Terminal执行: R >IRkernel::installspec() 报错 解决办…...
C语言---指针的两个运算符:点和箭头
目录 点(.)运算符箭头(->)运算符需要注意实际例子 C语言中的指针是一种特殊的变量,它存储了一个内存地址。点(.)和箭头(->)是用于访问结构体和联合体成员的运算符。…...
Linux 发布项目到OpenEuler虚拟机
后端:SpringBoot 前端:VUE3 操作系统:Linux 虚拟机:OpenEuler 发布项目是需要先关闭虚拟机上的防火墙 systemctl stop firewalld 一、运行后端项目到虚拟机 1、安装JDK软件包 查询Jdk是否已安装 dnf list installed | grep jd…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
