助记符如何与Radio Buttons一起使用

时间:2015-05-14 16:55:07

标签: java javafx

我期待当我使用Alt +助记符时,相关的单选按钮会变得聚焦并被选中。我的期望是基于我对Swing中助记符如何工作的了解。我的期望是错的吗?

在我下面的示例代码中,我将每个单选按钮的编号设置为助记符。

  1. 程序启动时选择“选项1”。
  2. 当我使用Alt + 3时,程序会发出哔哔声,所有助记符都会加下划线,“选项3”会变得有焦点但不会被选中。 GUI现在看起来像这样:
  3. http://i.stack.imgur.com/ip3om.png

    1. 如果我只输入2,“选项2会聚焦,但不会被选中。
    2. 以下是代码:

      import javafx.application.Application;
      import javafx.stage.Stage;
      import javafx.scene.*;
      import javafx.scene.control.*;
      import javafx.scene.layout.*;
      import javafx.scene.image.*;
      import javafx.scene.input.*;
      import javafx.scene.effect.*;
      import javafx.scene.paint.*;
      import javafx.beans.value.*;
      import javafx.geometry.*;
      
      import javafx.event.*;
      
      public class RadioButtonSSCCE extends Application
      {
          public Parent createScene()
          {
              ToggleGroup group = new ToggleGroup();
      
              RadioButton rb1 = new RadioButton( "Option _1" );
              rb1.setUserData("Option 1 selected");
              rb1.setToggleGroup( group );
      
              RadioButton rb2 = new RadioButton( "Option _2" );
              rb2.setUserData("Option 2 selected");
              rb2.setToggleGroup( group );
      
              RadioButton rb3 = new RadioButton( "Option _3" );
              rb3.setUserData("Option 3 selected");
              rb3.setToggleGroup( group );
      
              VBox root = new VBox(5);
              root.setAlignment(Pos.CENTER);
              root.getChildren().addAll(rb1, rb2, rb3);
      
              ChangeListener<Toggle> cl = new ChangeListener<Toggle>()
              {
                  @Override
                  public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle)
                  {
                      if (group.getSelectedToggle() != null)
                      {
                          String text = group.getSelectedToggle().getUserData().toString();
                          System.out.println( text );
                      }
                  }
              };
              group.selectedToggleProperty().addListener(cl);
      
              rb1.setSelected( true );
      
              return root;
          }
      
          @Override
          public void start(Stage primaryStage)
          {
              Scene scene = new Scene(createScene(), 125, 125);
              primaryStage.setScene(scene);
              primaryStage.setTitle("Radio Button SSCCE");
              primaryStage.show();
          }
      
          public static void main(String[] args)
          {
              launch(args);
          }
      }
      

      我发现为了调用助记符,我必须:

      1. 按下并释放Alt键。现在每个单选按钮的助记符都带有下划线。
      2. 按下数字,单选按钮变为焦点。但是,我现在需要使用空格键来选择单选按钮。
      3. 为什么我需要按空格键?按下助记符时是否应该选择单选按钮?

        另外,为什么我不能只使用Alt +助记符作为单个组合键来选择单选按钮?

        我的代码错了吗?

        编辑:

        操作是选择单选按钮的关键。我创建了一个通用动作,由所有按钮共享:

        EventHandler<ActionEvent> onAction = new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent e)
            {
                RadioButton button = (RadioButton)e.getSource();
                button.setSelected(true);
            }
        };
        
        rb1.setOnAction( onAction );
        rb2.setOnAction( onAction );
        rb3.setOnAction( onAction );
        

        由于单选按钮是按钮组的一部分,我不想取消选择按钮。

2 个答案:

答案 0 :(得分:3)

正如OttPrime在他的回答和Mnemonic Javadoc中所说:

  

如果在Mnemonic上注册Scene,并且KeyCombination到达未使用的Scene,那么目标Node将会发送{{ 1}}。

现在我认为这是一个问题,因为你真的不想只有ActionEvent发送到单选按钮,而是想要fire()单选按钮。

  

当且仅当RadioButton尚未选择或不属于ToggleGroup时,才切换单选按钮的状态。

注意:触发一个单选按钮也会向该按钮发送ActionEvent

以下是ActionEvent

的Java 8u40代码
Button::fire

以下是@Override public void fire() { if (!isDisabled()) { fireEvent(new ActionEvent()); } }

的代码
ToggleButton::fire

以下是@Override public void fire() { // TODO (aruiz): if (!isReadOnly(isSelected()) { if (!isDisabled()) { setSelected(!isSelected()); fireEvent(new ActionEvent()); } }

的代码
RadioButton::fire

注意:RadioButton是一个ToggleButton,因此super.fire()调用将调用ToggleButton fire()代码。

因此,按钮的助记符就可以了:所有助记符都在做的是向按钮发送一个ActionEvent(这与按钮的fire实现完全相同)。但是,ToggleButtons和RadioButtons在他们的fire方法中做了额外的东西来操作ToggleButton的选择状态,因此助记符调用不会这样做。

现在,您可能会说,好吧,我只是实施OttPrime的解决方法:

@Override public void fire() {
    // we don't toggle from selected to not selected if part of a group
    if (getToggleGroup() == null || !isSelected()) {
        super.fire();
    }
}

当您通过助记符选择按钮时会很棒,但是(据我所见),它会破坏按钮选择的其他功能(例如,如果您以编程方式触发单选按钮,可能还会如果你用鼠标点击单选按钮)。这是因为按钮的选择状态将改变两次(一次在fire()代码中,再在你的动作代码中),你可能不希望这样。不幸的是,我实际上无法测试这个理论,因为我无法访问可以使用助记符的机器。

那么,回答你原来的问题“助记符如何与无线电按钮配合使用”? =&GT;他们没有(至少在国际海事组织,没有任何真正有意义的方式)。

我建议disabling Mnemonic parsing选择单选按钮和切换按钮。

答案 1 :(得分:2)

JavaFX中的Mnemonic会触发针对已注册Node的{​​{3}}。在RadioButton的情况下,ActionEvent不会切换选择。您可以向RadioButton添加一个通用处理程序,以便像这样在ActionEvent上切换(假设这是JavaFX 8)。

rb1.setOnAction(event -> rb1.setSelected(!rb1.isSelected()));