How mnemonics work with the radio buttons

I expected that when I use Alt + mnemonics, the associated switch will be focused and selected. My expectations are based on my knowledge of how mnemonics work in Swing. Are my expectations expected?

In my code example below, I set the amount of each switch as a mnemonic.

  • When the program starts, "Option 1" is selected.
  • When I use Alt + 3, the program beeps for me, all mnemonics become underlined, and "Option 3" becomes focused, but NOT selected. Now the GUI looks like this:

http://i.stack.imgur.com/ip3om.png

  1. If I just type 2, "Option 2 becomes focused, but NOT selected.

Here is the code:

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); } } 

I found that to call the mnemonics, I have to:

  • press and release the Alt key. Now the mnemonics of each switch are underlined.
  • press the number and the switch will be focused. However, now I need to use the spacebar to select the switch.

Why do I need to press the spacebar? If the switch is not selected by pressing the mnemonics?

Also, why can't I use Alt + mnemonics as a single key combination to select a radio button?

Is my code wrong?

Edit:

Action is the key to choosing a switch. I created a common action for sharing all buttons:

 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 ); 

Since radio buttons are part of a button group, I donโ€™t need the ability to deselect a button.

+5
source share
2 answers

Mnemonic in JavaFX launches an ActionEvent aimed at a registered Node . In the case of RadioButton ActionEvent does not toggle the selection. You can add a generic handler to RadioButton to switch to an ActionEvent like this (assuming it's JavaFX 8).

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

As OttPrime notes in his answer and in the Mnemonic Javadoc:

When a Mnemonic registered on the Scene , and the KeyCombination reaches the Scene intact, then the target Node will be sent an ActionEvent .

Now I think this is kind of a problem, because you really do not want the ActionEvent be sent to the ActionEvent , instead you want the fire() radio button.

Toggles the state of the switch if and only if RadioButton has not yet selected or is not part of ToggleGroup.

Note: turning on the radio button will also send the ActionEvent button to the button.

Here is the Java 8u40 code for Button::fire

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

Here is the code for ToggleButton::fire

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

And here is the code for RadioButton::fire

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

Note. RadioButton is ToggleButton, so calling super.fire () calls the ToggleButton fire () code.

So, the mnemonics for the button will be fine: all that the mnemonics does is send an ActionEvent to the button (which is exactly the same as implementing the fire for the button). However, ToggleButtons and RadioButtons do additional things in their fire methods to control the state of the ToggleButton selection, so mnemonic calls are not going to do this.

Now you can say that itโ€™s good that I just use the OttPrime workaround:

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

It will be great if you select a button using mnemonics, but (as far as I can see), it will violate other functions for selecting buttons (for example, if you programmatically launch a switch and, possibly, also if you click on a switch with the mouse). This is because the state of the button selection will change twice (once in the fire code () and again in your action code), and you probably do not want this. Unfortunately, I cannot verify this theory, since I do not have access to a machine that can use mnemonics.

So, to answer your original question: "How does mnemonics work with radio buttons"? => They are not (at least in IMO, in no way make sense).

I would suggest just disabling Mnemonic analysis for the switches and toggle buttons.

+3
source

All Articles