1

JRadioButtonMenuItem我在菜单中有一组 3个,JToggleButton在工具栏中有 3 个。它们中的每一个都绑定到 3 Action,因此当我禁用一个操作时,相应的项目和按钮都将被禁用。

当我单击一个菜单项时,我希望相应的工具栏按钮也被选中,但似乎“未单击”组对这些事件有自己的奇怪反应方式(使用我没有尝试识别的模式)。

这是菜单组代码(简化):

ButtonGroup menuGrp = new ButtonGroup();

JRadioButtonMenuItem itemA = new JRadioButtonMenuItem(actionA);
JRadioButtonMenuItem itemB = new JRadioButtonMenuItem(actionB);
JRadioButtonMenuItem itemC = new JRadioButtonMenuItem(actionC);

menuGrp.add(itemA);
menuGrp.add(itemB);
menuGrp.add(itemC);

itemA.setSelected(true);

和这里工具栏组代码:

ButtonGroup toolbarGrp = new ButtonGroup();

JToggleButton buttonA = new JToggleButton(actionA);
JToggleButton buttonB = new JToggleButton(actionB);
JToggleButton buttonC = new JToggleButton(actionC);

toolbarGrp.add(buttonA);
toolbarGrp.add(buttonB);
toolbarGrp.add(buttonB);

buttonA.setSelected(true);
4

3 回答 3

2

我不知道你到底是怎么做的,但这段代码对我有用:

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JToggleButton;


public class Button
{
    public static void main(String[] args){
        JFrame frame = new JFrame();
        JMenuBar bar = new JMenuBar();
        JMenu menu = new JMenu("Foo");

        ButtonGroup menuGrp = new ButtonGroup();
        JRadioButtonMenuItem itemA = new JRadioButtonMenuItem();
        JRadioButtonMenuItem itemB = new JRadioButtonMenuItem();
        JRadioButtonMenuItem itemC = new JRadioButtonMenuItem();
        menuGrp.add(itemA);
        menuGrp.add(itemB);
        menuGrp.add(itemC);
        menu.add(itemA);
        menu.add(itemB);
        menu.add(itemC);
        itemA.setSelected(true);

        bar.add(menu);
        frame.setJMenuBar(bar);

        JPanel content = new JPanel();

        ButtonGroup toolbarGrp = new ButtonGroup();
        JToggleButton buttonA = new JToggleButton();
        JToggleButton buttonB = new JToggleButton();
        JToggleButton buttonC = new JToggleButton();
        toolbarGrp.add(buttonA);
        toolbarGrp.add(buttonB);
        toolbarGrp.add(buttonC);
        buttonA.setSelected(true);

        content.add(buttonA);
        content.add(buttonB);
        content.add(buttonC);

        itemA.setAction(new MyAction(buttonA));
        itemB.setAction(new MyAction(buttonB));
        itemC.setAction(new MyAction(buttonC));
        buttonA.setAction(new MyAction(itemA));
        buttonB.setAction(new MyAction(itemB));
        buttonC.setAction(new MyAction(itemC));
        frame.setContentPane(content);
        frame.setSize(300, 300);
        frame.setVisible(true);
    }

    static class MyAction extends AbstractAction
    {
        AbstractButton button;

        public MyAction(AbstractButton button){
            this.button = button;
        }

        @Override public void actionPerformed(ActionEvent e){
            button.setSelected(true);
        }   


    }
}
于 2012-03-15T02:24:39.520 回答
1

您可以通过在它们之间共享按钮模型来链接任意两个(或更多)按钮的状态,在这种情况下:

itemA.setModel(buttonA.getModel());
itemB.setModel(buttonB.getModel());
itemC.setModel(buttonC.getModel());

That way you can avoid calling the putValue(Action.SELECTED_KEY, true). Not sure whether that is actually an improvement, but I do like it more.

于 2012-07-12T08:34:12.043 回答
1

For the record (years later), this is due to a change made in Java 6. You can see JDK-6397556 for some discussion, but the short version is that because fully tying stateful buttons to Actions requires the button to push that state (selected vs unselected) back into the Action, they didn't want to break existing programs that didn't expect it.

So, if you're going to construct a toggle button from an Action, and you want the button's initial selected state to follow the Action's selected state, you have to opt-in by setting Action.SELECTED_KEY to a non-null Boolean value prior to creating the button:

Action action = .....;
action.putValue (Action.SELECTED_KEY, Boolean.TRUE);
JCheckBox checkbox = new JCheckBox(action);

Obviously, pass Boolean.FALSE to fully tie them together with an initial state of "not selected". (If your code has already determined the initial selection state in some other boolean variable, then simply doing Boolean.valueOf(initiallySelectedOrNot) will work, or you can rely on autoboxing to DTRT.)

于 2020-07-17T20:23:59.833 回答