当前位置: 首页 > news >正文

Java Swing 自定义组件库分享(九)

Java Swing 自定义组件库分享(九):滑动开关 — SwitchComponent

  • 一、背景
  • 二、核心设计
  • 三、类源码
  • 四、核心功能说明
  • 五、使用示例
  • 六、注意事项
  • 七、小结

一、背景

在 Web 端和移动端应用中,滑动开关(Toggle Switch)是一种常见的 UI 交互组件,用于切换开启/关闭状态。Swing 原生没有提供类似的组件,通常只能用复选框(JCheckBox)来模拟,但样式陈旧且不够直观。
SwitchComponent 的作用就是:自绘一个滑动开关组件,支持开启/关闭状态切换、禁用状态、自定义颜色和文字,提供更现代的交互体验。

二、核心设计

SwitchComponent 继承 JComponent,通过重写 paintComponent 方法自绘开关外观,包括背景圆角矩形、圆形滑块和 ON/OFF 文字。

开启状态:绿色背景,滑块在右侧,显示 “ON”

关闭状态:灰色背景,滑块在左侧,显示 “OFF”

禁用状态:浅灰色背景,不响应点击

三、类源码

importjavax.swing.*;importjava.awt.*;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;/** * 滑动开关组件 * 自绘实现,支持开启/关闭状态切换、禁用状态、文字显示 * * 使用示例: * SwitchComponent sw = new SwitchComponent(); * sw.setSwitched(true); * sw.addMouseListener(new MouseAdapter() { * public void mouseClicked(MouseEvent e) { * System.out.println("状态:" + sw.isSwitched()); * } * }); */publicclassSwitchComponentextendsJComponent{/** 开关状态 */privatebooleanswitched=false;/** 是否启用 */privatebooleanenabled=true;/** * 构造函数 */publicSwitchComponent(){setPreferredSize(newDimension(60,25));setOpaque(false);setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));addMouseListener(newMouseAdapter(){@OverridepublicvoidmouseClicked(MouseEvente){if(enabled){switched=!switched;repaint();// 触发父容器的重绘Containerparent=getParent();if(parent!=null){parent.repaint();}}}@OverridepublicvoidmouseEntered(MouseEvente){if(enabled){setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));}else{setCursor(Cursor.getDefaultCursor());}}});}/** * 获取开关状态 * @return true=开启,false=关闭 */publicbooleanisSwitched(){returnswitched;}/** * 设置开关状态 * @param switched 状态 */publicvoidsetSwitched(booleanswitched){this.switched=switched;repaint();}/** * 设置是否启用 * @param enabled 是否启用 */@OverridepublicvoidsetEnabled(booleanenabled){this.enabled=enabled;repaint();}@OverrideprotectedvoidpaintComponent(Graphicsg){Graphics2Dg2=(Graphics2D)g;g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);intwidth=getWidth();intheight=getHeight();// 绘制背景ColorbgColor;if(!enabled){bgColor=Color.LIGHT_GRAY;}elseif(switched){bgColor=Color.decode("#67C23A");// 开启状态绿色}else{bgColor=Color.decode("#DCDFE6");// 关闭状态灰色}g2.setColor(bgColor);g2.fillRoundRect(0,0,width,height,height,height);// 绘制圆形滑块ColorknobColor=Color.WHITE;intknobDiameter=height-4;intknobX=switched?width-knobDiameter-2:2;g2.setColor(knobColor);g2.fillOval(knobX,2,knobDiameter,knobDiameter);// 添加阴影效果g2.setColor(newColor(0,0,0,30));g2.drawOval(knobX,2,knobDiameter,knobDiameter);// 绘制开关文字g2.setColor(enabled?Color.WHITE:Color.GRAY);g2.setFont(getFont().deriveFont(Font.BOLD,10f));FontMetricsfm=g2.getFontMetrics();Stringtext=switched?"ON":"OFF";inttextWidth=fm.stringWidth(text);inttextX=switched?6:width-textWidth-6;inttextY=height/2+fm.getAscent()/2;g2.drawString(text,textX,textY);}}

四、核心功能说明

状态管理:

  • switched:开关状态(true=开启,false=关闭)
  • enabled:是否启用(禁用时不响应点击,显示灰色)
  • isSwitched() / setSwitched():获取/设置状态
  • setEnabled():设置启用状态

外观绘制(paintComponent):

  • 背景:圆角矩形,根据状态(开启/关闭/禁用)使用不同颜色
  • 滑块:圆形,根据状态移动到左侧或右侧,带轻微阴影
  • 文字:ON(开启)显示在左侧,OFF(关闭)显示在右侧

外观绘制(paintComponent):

  • 鼠标点击时切换状态并重绘
  • 悬停时显示手型光标
  • 禁用状态下光标为默认样式

五、使用示例

5.1 基本用法

SwitchComponentsw=newSwitchComponent();panel.add(sw);

5.2 设置初始状态

SwitchComponentsw=newSwitchComponent();sw.setSwitched(true);// 默认开启panel.add(sw);

5.3 监听状态变化

SwitchComponentsw=newSwitchComponent();sw.addMouseListener(newMouseAdapter(){@OverridepublicvoidmouseClicked(MouseEvente){System.out.println("开关状态:"+(sw.isSwitched()?"开启":"关闭"));}});

5.4 禁用开关

SwitchComponentsw=newSwitchComponent();sw.setEnabled(false);panel.add(sw);

5.5 自定义尺寸(通过 setPreferredSize)

SwitchComponentsw=newSwitchComponent();sw.setPreferredSize(newDimension(80,30));panel.add(sw);

5.6 配合表格使用(见后续表格篇章)

// 在表格的开关列中使用SwitchCellEditoreditor=newSwitchCellEditor(metTable,(row,newState)->{System.out.println("第"+row+"行状态变为:"+newState);returntrue;});

六、注意事项

  • 尺寸默认值:默认尺寸为 60x25,可通过 setPreferredSize 调整
  • 文字语言:默认显示 “ON”/“OFF”,可根据需要修改 paintComponent 中的文字
  • 颜色值:开启状态绿色 #67C23A 为 Element UI 风格,可根据主题自行调整
  • 父容器重绘:点击切换后主动调用父容器 repaint(),确保父容器刷新
  • 透明背景:setOpaque(false) 让组件背景透明,便于融入不同背景的父容器

七、小结

SwitchComponent 是一个自绘的滑动开关组件,通过 paintComponent 实现完整外观,支持开启/关闭状态切换、禁用状态、文字显示和悬停光标效果。
核心实现要点:

  • 继承 JComponent 而非 JToggleButton,完全自绘控制外观
  • paintComponent 中根据状态绘制不同颜色和滑块位置
  • 鼠标点击事件中切换状态并重绘
http://www.cnnetsun.cn/news/2632472.html

相关文章:

  • PowerDesigner 15保姆级教程:从安装汉化到逆向生成数据库ER图,手把手带你避坑
  • 别再手动改后缀了!手把手教你从arXiv论文一键导入Overleaf的正确姿势
  • 【NCCL】transport数据传输(二)
  • MLIR与CGRA编译优化技术解析
  • Cloudflare AI Labyrinth:用数字迷宫反制AI爬虫,保护原创内容
  • ELK日志平台实战
  • 告别手动操作:用Python脚本批量调用SAP BAPI,自动化FICO凭证与MM物料创建
  • 搞定7nm DRC收敛:一份来自Innovus和ICC2实战的避坑清单(附脚本)
  • 多软件互通避坑:模型互导不碎面、不丢材质
  • 智能戒指技术解析:从多模态传感到开源生态
  • AI与机器学习驱动的智能运营:从数据到决策的自动化闭环
  • Claude Code + GLM-5 深度赋能测试:开发 8 大 Skill 构建 AI 测试助手集群
  • 自动语音识别技术原理与实战:从MFCC到端到端模型
  • 神仙免费云服务器 - 阿贝云
  • GEO(生成式引擎优化)完全指南:让你的技术内容被AI看见
  • AI搜索优化值不值?价格与效果真实解析
  • 软件设计师备考 第0章 题型分布、示例、学习路线
  • 为什么92%的Gemini正则失败源于上下文锚定错误?——6个生产环境真实Case逆向拆解
  • iPaaS集成平台选型参考:五款热门产品能力介绍
  • FPGA如何精准控制三片ADS1282同步采样?SPI时序与同步逻辑的保姆级解析
  • 聊天机器人数据分析实战:从黑盒到白盒的优化闭环
  • Linux dd命令实战:手把手教你用/dev/zero和seek参数精准擦除eMMC分区
  • 从CTF实战看LFSR与BM算法:如何破解流密码与伪随机生成器
  • Windows 10/11系统下,用YOLOv8改进YOLOv5的C3模块:一份给CV新手的保姆级数据集训练指南
  • 告别同步烦恼:手把手教你用AD9680+LMK04828搭建多板卡JESD204B采集系统(附Vivado调试技巧)
  • 你的STM32循迹小车跑不直?可能是编码器测速的‘坑’没避开
  • 保姆级教程:用CarSim 2020和Simulink手把手搭建平行泊车仿真(附MPC控制器模型)
  • Cadence Allegro铺铜实战:从动态避让到静态优化,手把手教你高效处理PCB电源层
  • 终极热键侦探:3分钟快速定位Windows快捷键占用程序
  • AI系统审计:如何识别数据投毒与对抗性攻击的微观威胁