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