| 特性 | JCheckBox (核取方塊) | JRadioButton (單選按鈕) |
|---|---|---|
| 外觀 | 方框,勾選標記 | 圓形,圓點標記 |
| 預設行為 | 可多選 | 需配合 ButtonGroup 單選 |
| 適用場景 | 獨立開關、多項選擇 | 互斥選項(性別、付款方式) |
| 事件模型 | ItemListener / ActionListener | ItemListener / ActionListener |
// JCheckBox
new JCheckBox()
new JCheckBox(String text)
new JCheckBox(String text, boolean selected)
new JCheckBox(Icon icon)
new JCheckBox(String text, Icon icon, boolean selected)
// JRadioButton (參數相同)
new JRadioButton()
new JRadioButton(String text)
new JRadioButton(String text, boolean selected)
ButtonGroup 本身不顯示,僅管理一組按鈕的互斥狀態。
ButtonGroup group = new ButtonGroup();
JRadioButton r1 = new JRadioButton("選項 A");
JRadioButton r2 = new JRadioButton("選項 B");
JRadioButton r3 = new JRadioButton("選項 C");
group.add(r1); group.add(r2); group.add(r3);
// 程式預選
r2.setSelected(true);
// 取得目前選中的模型
ButtonModel selected = group.getSelection();
itemStateChanged(ItemEvent e),可區分 SELECTED/DESELECTED,適合核取方塊。actionPerformed(ActionEvent e),僅在按鈕被點擊(狀態改變)觸發,適合單選按鈕。package swing.demo;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ProductSelector extends JFrame implements ItemListener {
// 單選:品牌
private JRadioButton rbDell, rbHp, rbLenovo;
private ButtonGroup brandGroup;
// 核取:配件
private JCheckBox cbMouse, cbBag, cbWarranty;
// 顯示區
private JTextArea logArea;
public ProductSelector() {
setTitle("產品選購示範");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout(10,10));
// 品牌面板
JPanel brandPanel = new JPanel(new GridLayout(0,1));
brandPanel.setBorder(BorderFactory.createTitledBorder("品牌 (單選)"));
brandGroup = new ButtonGroup();
rbDell = createRadio("Dell", brandPanel, brandGroup);
rbHp = createRadio("HP", brandPanel, brandGroup);
rbLenovo = createRadio("Lenovo", brandPanel, brandGroup);
rbDell.setSelected(true);
// 配件面板
JPanel accPanel = new JPanel(new GridLayout(0,1));
accPanel.setBorder(BorderFactory.createTitledBorder("配件 (多選)"));
cbMouse = createCheck("滑鼠", accPanel);
cbBag = createCheck("筆電包", accPanel);
cbWarranty = createCheck("延保服務", accPanel);
// 顯示區
logArea = new JTextArea(8, 30);
logArea.setEditable(false);
JScrollPane scroll = new JScrollPane(logArea);
// 佈局
JPanel left = new JPanel(new GridLayout(2,1,5,5));
left.add(brandPanel);
left.add(accPanel);
add(left, BorderLayout.WEST);
add(scroll, BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
}
private JRadioButton createRadio(String text, Container parent, ButtonGroup group) {
JRadioButton rb = new JRadioButton(text);
rb.addItemListener(this);
group.add(rb);
parent.add(rb);
return rb;
}
private JCheckBox createCheck(String text, Container parent) {
JCheckBox cb = new JCheckBox(text);
cb.addItemListener(this);
parent.add(cb);
return cb;
}
@Override
public void itemStateChanged(ItemEvent e) {
Object src = e.getItemSelectable();
String action = (e.getStateChange() == ItemEvent.SELECTED) ? "選取" : "取消";
StringBuilder sb = new StringBuilder();
sb.append("[").append(action).append("] ");
if (src == rbDell) sb.append("品牌:Dell");
else if (src == rbHp) sb.append("品牌:HP");
else if (src == rbLenovo) sb.append("品牌:Lenovo");
else if (src == cbMouse) sb.append("配件:滑鼠");
else if (src == cbBag) sb.append("配件:筆電包");
else if (src == cbWarranty) sb.append("配件:延保服務");
logArea.append(sb.toString() + "\n");
logArea.setCaretPosition(logArea.getDocument().getLength());
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ProductSelector().setVisible(true));
}
}
JCheckBox 對應「獨立開關」,JRadioButton + ButtonGroup 對應「互斥單選」。善用 ItemListener 獲取狀態變化細節,配合邊框標題與佈局管理器,可快速建構清晰的選項介面。