You may want to bind the RadioButton selection to an enumerated type. Say, you have an enumeration ChoiceType with 3 values. You want to map each of those 3 values to a RadioButton. Moreover, you'd like to maintain a single field of ChoiceType for use in a model component.
While there are cool binding expressions that can be used on the RadioButton controls and the owning ToggleGroup, these are limited to one-way bindings. Specifically, you can build a case statement with the When/then/otherwise construct which will convert the boolean selections to then enumerated type.
This sample program does not use JavaFX Binding and instead uses a pair of listeners. One listener will set the RadioButtons based on the current ChoiceType. The other listener will set the ChoiceType from the RadioButtons.
I'm using a free-form data structure associated with each control "Properties" to associated a RadioButton with a particular ChoiceType. userData will work equally as well, but you may be using that already.
public class RBTest extends Application { private static String CHOICE_PROPERTY_NAME = "choice"; enum ChoiceType { C1, C2, C3 } private ObjectProperty<ChoiceType> choice = new SimpleObjectProperty<>(); @Override public void start(Stage primaryStage) throws Exception { RadioButton rb1 = new RadioButton( "Choice 1"); rb1.getProperties().put( CHOICE_PROPERTY_NAME, ChoiceType.C1 ); RadioButton rb2 = new RadioButton( "Choice 2" ); rb2.getProperties().put( CHOICE_PROPERTY_NAME, ChoiceType.C2 ); RadioButton rb3 = new RadioButton( "Choice 3" ); rb3.getProperties().put( CHOICE_PROPERTY_NAME, ChoiceType.C3 ); ToggleGroup tg = new ToggleGroup(); tg.getToggles().addAll( rb1, rb2, rb3 ); tg.selectedToggleProperty().addListener( (obs,ov,nv) -> { choice.set( (ChoiceType)nv.getProperties().get(CHOICE_PROPERTY_NAME) ); }); choice.addListener( (obs,ov,nv) -> { if( nv != null ) { tg.getToggles() .stream() .filter( (rb) -> rb.getProperties().get(CHOICE_PROPERTY_NAME).equals(nv) ) .forEach( tg::selectToggle ); } }); choice.set( ChoiceType.C3 ); Button btn = new Button("Print Choice"); btn.setOnAction( (evt) -> System.out.println( choice.get() )); VBox vbox = new VBox( rb1, rb2, rb3, btn ); vbox.setAlignment(Pos.CENTER); vbox.setSpacing(10.0d); Scene scene = new Scene(vbox, 320, 480 ); primaryStage.setScene( scene ); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
Which is exactly what JFXtras' ToggleGroupValue control does.
ReplyDeletehttp://jfxtras.org/overview.html#_togglegroupvalue