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{/** 开关状态 */privatebooleanswitchedfalse;/** 是否启用 */privatebooleanenabledtrue;/** * 构造函数 */publicSwitchComponent(){setPreferredSize(newDimension(60,25));setOpaque(false);setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));addMouseListener(newMouseAdapter(){OverridepublicvoidmouseClicked(MouseEvente){if(enabled){switched!switched;repaint();// 触发父容器的重绘ContainerparentgetParent();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.switchedswitched;repaint();}/** * 设置是否启用 * param enabled 是否启用 */OverridepublicvoidsetEnabled(booleanenabled){this.enabledenabled;repaint();}OverrideprotectedvoidpaintComponent(Graphicsg){Graphics2Dg2(Graphics2D)g;g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);intwidthgetWidth();intheightgetHeight();// 绘制背景ColorbgColor;if(!enabled){bgColorColor.LIGHT_GRAY;}elseif(switched){bgColorColor.decode(#67C23A);// 开启状态绿色}else{bgColorColor.decode(#DCDFE6);// 关闭状态灰色}g2.setColor(bgColor);g2.fillRoundRect(0,0,width,height,height,height);// 绘制圆形滑块ColorknobColorColor.WHITE;intknobDiameterheight-4;intknobXswitched?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));FontMetricsfmg2.getFontMetrics();Stringtextswitched?ON:OFF;inttextWidthfm.stringWidth(text);inttextXswitched?6:width-textWidth-6;inttextYheight/2fm.getAscent()/2;g2.drawString(text,textX,textY);}}四、核心功能说明状态管理switched开关状态true开启false关闭enabled是否启用禁用时不响应点击显示灰色isSwitched() / setSwitched()获取/设置状态setEnabled()设置启用状态外观绘制paintComponent背景圆角矩形根据状态开启/关闭/禁用使用不同颜色滑块圆形根据状态移动到左侧或右侧带轻微阴影文字ON开启显示在左侧OFF关闭显示在右侧外观绘制paintComponent鼠标点击时切换状态并重绘悬停时显示手型光标禁用状态下光标为默认样式五、使用示例5.1 基本用法SwitchComponentswnewSwitchComponent();panel.add(sw);5.2 设置初始状态SwitchComponentswnewSwitchComponent();sw.setSwitched(true);// 默认开启panel.add(sw);5.3 监听状态变化SwitchComponentswnewSwitchComponent();sw.addMouseListener(newMouseAdapter(){OverridepublicvoidmouseClicked(MouseEvente){System.out.println(开关状态(sw.isSwitched()?开启:关闭));}});5.4 禁用开关SwitchComponentswnewSwitchComponent();sw.setEnabled(false);panel.add(sw);5.5 自定义尺寸通过 setPreferredSizeSwitchComponentswnewSwitchComponent();sw.setPreferredSize(newDimension(80,30));panel.add(sw);5.6 配合表格使用见后续表格篇章// 在表格的开关列中使用SwitchCellEditoreditornewSwitchCellEditor(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 中根据状态绘制不同颜色和滑块位置鼠标点击事件中切换状态并重绘