You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现互斥切换开关:三开关启一则其余两关的方法

嘿,这个需求本质就是做一组互斥的切换开关——同一时间只能有一个处于开启状态,其他自动关闭。下面我给你分别用JavaFX和Swing这两个最常用的Java UI框架来实现,代码都是可以直接运行的~

JavaFX实现方案

JavaFX里自带ToggleGroup组件,专门用来管理一组互斥的Toggle控件,搭配ToggleButton并自定义样式就能做成开关的样子,非常省心:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MutexToggleSwitches extends Application {
    @Override
    public void start(Stage primaryStage) {
        // 创建ToggleGroup,核心就是靠它实现互斥逻辑
        ToggleGroup toggleGroup = new ToggleGroup();

        // 创建三个切换开关(本质是带样式的ToggleButton)
        ToggleButton switch1 = new ToggleButton("选项1");
        ToggleButton switch2 = new ToggleButton("选项2");
        ToggleButton switch3 = new ToggleButton("选项3");

        // 把三个开关加入同一个组,自动实现"开一个关其他"的效果
        switch1.setToggleGroup(toggleGroup);
        switch2.setToggleGroup(toggleGroup);
        switch3.setToggleGroup(toggleGroup);

        // 给开关加样式,改成常见的滑动开关外观
        String switchStyle = """
                .toggle-button {
                    -fx-background-color: #ccc;
                    -fx-background-radius: 20px;
                    -fx-min-width: 60px;
                    -fx-min-height: 30px;
                    -fx-text-fill: transparent;
                }
                .toggle-button:selected {
                    -fx-background-color: #4CAF50;
                }
                .toggle-button .text {
                    -fx-translate-x: -20px;
                }
                .toggle-button:selected .text {
                    -fx-translate-x: 20px;
                    -fx-fill: white;
                }
                """;

        // 应用样式到每个开关
        switch1.setStyle(switchStyle);
        switch2.setStyle(switchStyle);
        switch3.setStyle(switchStyle);

        // 监听选中状态变化,方便调试看效果
        toggleGroup.selectedToggleProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null) {
                System.out.println("选中了:" + ((ToggleButton) newVal).getText());
            }
        });

        // 用VBox布局放开关,加 padding 让界面不拥挤
        VBox vbox = new VBox(10, switch1, switch2, switch3);
        vbox.setPadding(new javafx.geometry.Insets(20));

        Scene scene = new Scene(vbox, 200, 150);
        primaryStage.setTitle("互斥切换开关");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

关键说明

  • ToggleGroup是核心,只要把Toggle控件加入同一组,就会自动处理互斥逻辑,完全不用自己写判断代码。
  • 上面的CSS样式可以根据你的需求调整,比如改开关颜色、大小、文字位置,很灵活。
Swing实现方案

Swing没有原生的ToggleSwitch控件,但我们可以自定义JToggleButton的绘制逻辑,模拟开关样式,再用ButtonGroup实现互斥:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class MutexSwingSwitches extends JFrame {
    public MutexSwingSwitches() {
        setTitle("互斥切换开关");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        setPadding(20);

        // 创建ButtonGroup,管理互斥逻辑
        ButtonGroup buttonGroup = new ButtonGroup();

        // 创建三个自定义开关
        CustomToggleSwitch switch1 = new CustomToggleSwitch("选项1");
        CustomToggleSwitch switch2 = new CustomToggleSwitch("选项2");
        CustomToggleSwitch switch3 = new CustomToggleSwitch("选项3");

        // 加入同一个ButtonGroup,实现互斥
        buttonGroup.add(switch1);
        buttonGroup.add(switch2);
        buttonGroup.add(switch3);

        // 添加状态监听,打印选中结果
        ItemListener listener = e -> {
            CustomToggleSwitch source = (CustomToggleSwitch) e.getSource();
            if (e.getStateChange() == ItemEvent.SELECTED) {
                System.out.println("选中了:" + source.getText());
            }
        };
        switch1.addItemListener(listener);
        switch2.addItemListener(listener);
        switch3.addItemListener(listener);

        // 把开关加到窗口里,加间距让界面更美观
        add(switch1);
        add(Box.createVerticalStrut(10));
        add(switch2);
        add(Box.createVerticalStrut(10));
        add(switch3);

        pack();
        setLocationRelativeTo(null);
    }

    // 自定义开关组件,继承JToggleButton手动绘制样式
    static class CustomToggleSwitch extends JToggleButton {
        private static final int WIDTH = 60;
        private static final int HEIGHT = 30;
        private static final int KNOB_SIZE = 26;

        public CustomToggleSwitch(String text) {
            super(text);
            setPreferredSize(new Dimension(WIDTH + 80, HEIGHT)); // 留空间放文字
            setBorderPainted(false);
            setContentAreaFilled(false);
            setFocusPainted(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 绘制开关背景
            int x = 10;
            int y = (getHeight() - HEIGHT) / 2;
            g2.setColor(isSelected() ? new Color(76, 175, 80) : Color.LIGHT_GRAY);
            g2.fillRoundRect(x, y, WIDTH, HEIGHT, HEIGHT, HEIGHT);

            // 绘制开关旋钮
            int knobX = isSelected() ? x + WIDTH - KNOB_SIZE - 2 : x + 2;
            int knobY = y + (HEIGHT - KNOB_SIZE) / 2;
            g2.setColor(Color.WHITE);
            g2.fillOval(knobX, knobY, KNOB_SIZE, KNOB_SIZE);

            // 绘制开关文字
            g2.setColor(isSelected() ? Color.WHITE : Color.BLACK);
            g2.drawString(getText(), x + WIDTH + 10, y + HEIGHT / 2 + g2.getFontMetrics().getAscent() / 2);

            g2.dispose();
            super.paintComponent(g);
        }
    }

    private void setPadding(int padding) {
        getContentPane().setBorder(BorderFactory.createEmptyBorder(padding, padding, padding, padding));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MutexSwingSwitches().setVisible(true));
    }
}

关键说明

  • ButtonGroup和JavaFX的ToggleGroup作用一致,把多个JToggleButton加入同一组后,就会自动互斥。
  • 自定义的CustomToggleSwitch重写了paintComponent方法,手动绘制了开关的背景和旋钮,你可以调整颜色、尺寸来适配自己的UI风格。

内容的提问来源于stack exchange,提问作者Mourad El

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:01:07