取消所有作为一组添加的复选框的勾选。

3

我有4个复选框,它们被组合在一起以便我只能选择其中一个。 但是如果我选择其中一个,现在想要取消所有复选框的选择,我无法做到。有人知道如何解决吗?

6个回答

5

您所询问的行为是半复选框和半单选按钮,以下是正确的做法:将其设置为五个单选按钮组,其中第一个(或最后一个)基本上表示“没有其他选项”。


2

在@trashgod的答案基础上,这里提供一个可运行的代码示例,其中一个JButton与一组JRadioButton对象连接起来,使用ButtonGroup.clearSelection()清除选择:

public class ClearableRadioButtons extends JFrame {

    public ClearableRadioButtons() {
        JPanel content = new JPanel();
        content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

        final ButtonGroup group = new ButtonGroup();
        for (int i = 1; i < 10; i++) {
            JRadioButton nextButton = new JRadioButton("Button " + i);
            group.add(nextButton);
            content.add(nextButton);
        }
        content.add(new JButton(new AbstractAction("Clear") {
            public void actionPerformed(ActionEvent arg0) {
                // This is the one line you really care about:
                group.clearSelection();
            } 
        }));

        setLayout(new BorderLayout());
        add(content, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ClearableRadioButtons();
            }
        });
    }
}

请注意,如果您将所有的JRadioButton实例替换为JCheckBox,此代码同样适用。然而,不建议这样做,因为标准的表示只能选择一项的方法是使用单选按钮而不是复选框。如果用户看到复选框,通常会期望允许选择多个,当选择其中一个复选框导致其他复选框取消选择时,他们会感到烦恼。
如果您真的不喜欢JRadioButton按钮的外观,则建议尝试更改Swing外观和感觉以改变应用程序中所有复选框和单选按钮,直到您满意为止。

+1个好的例子,也是@Chris建议的有趣替代方案。 - trashgod
我不确定为什么这篇文章会得到赞。它可能能够工作,但效果不佳。有一种非常简单且长期被接受的方法可以实现@newbee想要的功能,并且我已经在我的答案中描述了它。如果你使用其他方法,你会让用户感到困惑,因为你正在制作与他们在其他应用程序、网页甚至纸张上看到的控件行为不同的控件。这使得你的产品更难使用,也会让你付出代价。 - Chris
@Chris:我有点困惑——我告诉@newbee应该使用JRadioButton而不是JCheckBox,并警告不要违反单选按钮(只能选择0或1项)与复选框(可以选择任意数量)的标准行为。我到底建议@newbee“制作与他们一再见过的控件行为不同”的地方在哪里?我肯定没有打算建议这样做,如果我无意中这样做了,我将编辑我的答案以删除这个建议。 - Joe Carnahan
使用按钮来清除单选按钮是非标准行为。事实上,清除单选按钮本身就是非标准的,因为单选按钮的设计是至少要选择一个选项。 - Chris
我认为这是一个灰色地带。我肯定看到过单选按钮控件(包括汽车收音机,从中源于该隐喻!)在没有按钮被按下的情况下。诚然,根据应用程序,"未按下任何按钮"状态通常只允许作为初始状态或根本不允许。然而,我认为这种限制取决于应用程序。同时,单选按钮的重要之处就在于选择一个选项会取消选择其他选项。 - Joe Carnahan

2
您可以使用 clearSelection(),它“清除选择,使得ButtonGroup中的按钮都没有被选中。”
另外,对于单选组,使用JRadioButton可能比复选框更容易理解。
补充说明:@Joe Carnahan和@Chris提出了明确表示“无选择”选项的清晰方式。您还可以查看Java外观设计指南的第10章,其中讨论了与切换按钮相关的独立和互斥选择。

0

--[编辑]--
我犯了一个错误,我回答这个问题时认为它是关于另一个问题的C# .NET项目。如果您愿意,可以投票关闭它,但在选择投反对票之前请阅读此说明。
--[/编辑]--

根据您之后所说的,您想要使用单选框来作为复选框(重新点击相同的单选框应取消选中状态)。为此,您可以使用radiobuttons并添加一个名为“none”的选项,该选项将像未选择任何选项一样,或者放置一个“清除”按钮,以取消选择每个单选框。

或者,如果您真的想这样做,您可以使用CheckBox_CheckedChanged处理程序,每次选中或取消选中复选框时都会触发它,因此您必须在处理程序内查看复选框是否被选中。处理程序内的代码应如下所示:

If (CheckBox1.Checked)
{
    CheckBox2.Checked = False;
    CheckBox3.Checked = False;
    CheckBox4.Checked = False;
    CheckBox5.Checked = False;
}
// same for other checkboxes

或者编写一个函数,它接收当前选中的复选框并取消其他复选框的选择,并将其放置在每个处理程序中,每个处理程序发送所需的复选框。

但是我强烈建议您选择我提供的第一种解决方案之一..


刚注意到这是一个JAVA问题,我在这里干嘛呢?哈哈 - Marcelo

0

这是一个老问题...但我遇到了完全相同的问题,不想采用添加“清除选择按钮”的解决方案。 因此,我编写了自己的ButtonGroup来解决原始问题(可以取消选择按钮,使组中没有按钮被选中)。 它还添加了能够被java.util.Observer观察到的功能,每当选定的按钮更改时都会通知观察者。

以下是代码:

package net.yapbam.gui.util;

import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.io.Serializable;

import javax.swing.JToggleButton;

/**
 * This class is, like javax.swing.ButtonGroup, used to create a multiple-exclusion scope for
 * a set of buttons. Creating a set of buttons with the same <code>ButtonGroup</code> object means that
 * turning "on" one of those buttons turns off all other buttons in the group.
 * <p>
 * The main difference of this group with the swing one is that you can deselected buttons by clicking on them
 * and have a group without no selected button.<br>
 * Another difference is that this class extends the java.util.Observable class and calls its observers update method
 * when the selected button changes. 
 * </p>
 */
public class ButtonGroup extends Observable implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     *  The buttons list
     */
    private List<JToggleButton> buttons;
    /**
     * The current selection.
     */
    private JToggleButton selected;
    private ItemListener listener;

    /**
     * Constructor.
     */
    public ButtonGroup() {
        this.buttons = new ArrayList<JToggleButton>();
        this.selected = null;
        this.listener = new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JToggleButton b = (JToggleButton) e.getItem();
                if (e.getStateChange()==ItemEvent.SELECTED) {
                    setSelected(b);
                } else {
                    if (selected==b) setSelected(null);
                }
            }
        };
    }

    /**
     * Adds a button to this group.
     * @param b the button to be added
     * @exception NullPointerException if the button is null
     */
    public void add(JToggleButton b) {
        if (b==null) throw new NullPointerException();
        buttons.add(b);
        b.addItemListener(listener);
        if (b.isSelected()) setSelected(b);
    }

    /**
     * Removes a button from this group.
     * @param b the button to be removed
     * @exception IllegalArgumentException if the button is unknown in this group
     * @exception NullPointerException if the button is null
     */
    public void remove(JToggleButton b) {
        if (b == null) throw new NullPointerException();
        if (this.buttons.remove(b)) {
            b.removeItemListener(this.listener);
            if (this.selected==b) setSelected(null);
        } else {
            throw new IllegalArgumentException();
        }
    }

    /**
     * Clears the selection such that none of the buttons in the
     * <code>ButtonGroup</code> are selected.
     */
    public void clearSelection() {
        if (selected != null) setSelected(null);
    }

    /**
     * Returns the selected button.
     * @return the selected button
     */
    public JToggleButton getSelected() {
        return this.selected;
    }

    /** Changes the selected button.
     * @param b the button to be selected (null deselects all buttons)
     * @exception IllegalArgumentException if the button is not in this group
     */
    public void setSelected(JToggleButton b) {
        if (b==this.selected) return;
        if ((b!=null) && (!this.buttons.contains(b))) throw new IllegalArgumentException();
        JToggleButton old = this.selected;
        this.selected = b;
        if (b!=null) b.setSelected(true);
        if (old!=null) old.setSelected(false);
        this.setChanged();
        this.notifyObservers(this.selected);
    }
}

0
您正在描述一个 RadioButton 的行为,它是一个选择组,一次只允许选择一个选项;Swing 内置了对此的支持。

编辑:我误读了问题。

要取消选择所有复选框,您可以迭代Container的子项或更简单地使用ButtonGroup.getElements()来枚举特定组中的按钮。


@软件猴子:是的,你说得对,支持让你一次只选择一个按钮,但如果现在你想取消选择组中的所有按钮呢?这就是我所问的。 - newbee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接