首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Swing JRadioButton 單選按鈕實戰詳解:從基礎用法到動作命令模式

     編輯:Java 相關知識

概述

JRadioButton 是 Swing 中實現「多選一」交互的核心組件。不同於 CheckBox 的獨立勾選,RadioButton 必須配合 ButtonGroup 形成邏輯互斥組。本文通過完整示例講解創建、分組、事件處理、佈局與進階模式。

最小可運行示例

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

public class SimpleRadioDemo extends JFrame {
    public SimpleRadioDemo() {
        setTitle("單選按鈕基礎示例");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        setSize(300, 150);
        setLocationRelativeTo(null);

        // 1. 創建按鈕
        JRadioButton r1 = new JRadioButton("蘋果");
        JRadioButton r2 = new JRadioButton("香蕉");
        JRadioButton r3 = new JRadioButton("橘子");

        // 2. 分組 (核心步驟!)
        ButtonGroup bg = new ButtonGroup();
        bg.add(r1); bg.add(r2); bg.add(r3);

        // 3. 默認選中
        r1.setSelected(true);

        // 4. 監聽選中變化
        ActionListener listener = e -> {
            JRadioButton src = (JRadioButton) e.getSource();
            if (src.isSelected()) { // 只處理「被選中」事件,忽略「被取消選中」
                System.out.println("用戶選擇: " + src.getText());
            }
        };
        r1.addActionListener(listener);
        r2.addActionListener(listener);
        r3.addActionListener(listener);

        // 5. 添加到界面
        add(r1); add(r2); add(r3);
    }

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

核心機制深度剖析

ButtonGroup 內部原理

  • 維護一個 ArrayList<AbstractButton> 存儲成員。
  • 監聽每個按鈕的 ItemEvent (而非 ActionEvent)。
  • 當某按鈕狀態變為選中時,遍歷列表將其他按鈕 setSelected(false)。
  • 不負責佈局,僅負責邏輯協調。

事件模型:ActionEvent vs ItemEvent

事件類型觸發時機典型用途
ActionEvent按鈕被點擊/空格鍵觸發 (邏輯動作)業務響應:提交表單、切換面板
ItemEvent選中狀態改變 (selected ↔ deselected)狀態同步:ButtonGroup 內部、即時預覽

建議:業務代碼使用 ActionListener,並在處理前判斷 isSelected() 過濾掉取消選中的噪音事件。

進階模式:ActionCommand 解耦顯示與業務


enum PaymentType { ALIPAY("支付寶"), WECHAT("微信支付"), UNIONPAY("銀聯"); 
    final String label; PaymentType(String l){label=l;} 
    public String getLabel(){return label;}
}

JPanel createPaymentPanel() {
    JPanel p = new JPanel(new GridLayout(0,1));
    ButtonGroup g = new ButtonGroup();
    
    for (PaymentType pt : PaymentType.values()) {
        JRadioButton rb = new JRadioButton(pt.getLabel());
        rb.setActionCommand(pt.name()); // 業務枚舉名作為命令
        rb.addActionListener(e -> {
            if (rb.isSelected()) {
                PaymentType selected = PaymentType.valueOf(e.getActionCommand());
                processPayment(selected); // 直接用枚舉處理業務
            }
        });
        g.add(rb);
        p.add(rb);
    }
    return p;
}

void processPayment(PaymentType type) {
    System.out.println("調用 " + type + " 支付通道");
}

佈局與外觀定製

垂直列表佈局 (表單常用)


setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
// 或
setLayout(new GridLayout(0, 1, 5, 5)); // 0行1列,間隙5px

HTML 富文本標籤


JRadioButton rb = new JRadioButton(
    "高級會員
享9折優惠 + 免運費" );

自定義圖標 (替換默認圓點)


// 全局設置 (需在創建組件前)
UIManager.put("RadioButton.icon", loadIcon("radio_off.svg"));
UIManager.put("RadioButton.select", loadIcon("radio_on.svg"));

// 單個組件設置
rb.setIcon(new ImageIcon("off.png"));
rb.setSelectedIcon(new ImageIcon("on.png"));
rb.setDisabledIcon(new ImageIcon("off_dis.png"));
rb.setDisabledSelectedIcon(new ImageIcon("on_dis.png"));

常見坑位與解決方案

  1. 忘記加入 ButtonGroup → 所有按鈕可同時選中。
  2. 在 ItemListener 中處理業務 → 會觸發兩次 (選中+取消),改用 ActionListener + isSelected() 判斷。
  3. 動態添加/移除按鈕 → 移除時必須 group.remove(btn),否則內部列表殘留引用導致內存洩漏。
  4. 啟用/禁用狀態不同步 → 禁用組內某按鈕時,若它被選中,需先 group.clearSelection() 或選中另一個。

總結

JRadioButton 的核心在於 ButtonGroup 邏輯互斥 與 ActionCommand 業務解耦。掌握「創建 → 分組 → 監聽 → 佈局」四步驟,結合枚舉驅動的 ActionCommand 模式,即可構建清晰、可維護的單選交互界面。遷移到 JavaFX 時,對應關係為 RadioButton + ToggleGroup,API 設計理念一致。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved