Класс javafx.scene.control.RadioButton представляет переключатель или радиокнопку, которая модет находиться в двух состояниях: отмеченном и неотмеченном. RadioButton унаследован от ранее рассмотренного класса ToggleButton. Благодаря этому из отдельных элементов RadioButton можно создать группу радиокнопок, причем в рамках одной группы одномоментно можно выбрать только один элемент RadioButton.
Класс RadioButton имеет два конструктора:
RadioButton()
: создает кнопку без надписи
RadioButton(String text)
: создает кнопку с определенной надписью
В дополнение к унаследованным свойствам и методам RadioButton добавляет метод fire(), с помощью которого можно программно переключать состояние переключателя.
Используем RadioButton в программе:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javafx.geometry.Orientation; import javafx.geometry.Insets; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) throws Exception { Label selectedLbl = new Label(); RadioButton javaBtn = new RadioButton("Java"); RadioButton jsBtn = new RadioButton("JavaScript"); RadioButton csharpBtn = new RadioButton("C#"); ToggleGroup group = new ToggleGroup(); // установка группы javaBtn.setToggleGroup(group); jsBtn.setToggleGroup(group); csharpBtn.setToggleGroup(group); // установка обработчика события нажатия javaBtn.setOnAction(event -> selectedLbl.setText("Selected: Java")); jsBtn.setOnAction(event -> selectedLbl.setText("Selected: JavaScript")); csharpBtn.setOnAction(event -> selectedLbl.setText("Selected: C#")); FlowPane root = new FlowPane(Orientation.VERTICAL, 10, 10); root.getChildren().addAll(javaBtn, jsBtn, csharpBtn, selectedLbl); root.setPadding(new Insets(10)); Scene scene = new Scene(root, 250, 200); stage.setScene(scene); stage.setTitle("RadioButtons in JavaFX"); stage.show(); } }
Здесь все радиокнопки помещаются в одну группу, соответственно мы можем выбрать только одну радиокнопку в рамках этой группы:
Хотя пример выше работает, но в нем есть одна проблема: мы вынуждены устанавливать обработчик для каждой кнопки, код которого повторяется и меняется только передаваемый текст. Если кнопок десять, соответственно потребуется прикрепить десять обработчиков. А если мы потом захотим изменить логику обработчиков, то потребуется изменить все 10 обработчиков. И в этом случае более оптимальным решением является прослушивание изменений для всей группы в целом. Для этого применяется интерфейс ChangeListener. Итак, изменим код программы следующим образом:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.geometry.Orientation; import javafx.geometry.Insets; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) throws Exception { Label selectedLbl = new Label(); RadioButton javaBtn = new RadioButton("Java"); RadioButton jsBtn = new RadioButton("JavaScript"); RadioButton csharpBtn = new RadioButton("C#"); ToggleGroup group = new ToggleGroup(); // установка группы javaBtn.setToggleGroup(group); jsBtn.setToggleGroup(group); csharpBtn.setToggleGroup(group); group.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){ public void changed(ObservableValue<? extends Toggle> changed, Toggle oldValue, Toggle newValue){ // получаем выбранный элемент RadioButton RadioButton selectedBtn = (RadioButton) newValue; selectedLbl.setText("Selected: " + selectedBtn.getText()); } }); FlowPane root = new FlowPane(Orientation.VERTICAL, 10, 10); root.getChildren().addAll(javaBtn, jsBtn, csharpBtn, selectedLbl); root.setPadding(new Insets(10)); Scene scene = new Scene(root, 250, 200); stage.setScene(scene); stage.setTitle("RadioButtons in JavaFX"); stage.show(); } }
В качестве обработчика изменений передается анонимный объект, который реализует интерфейс ChangeListener, типизированный типом Toggle. Toggle - это интерфейс, которые реализуется в том числе и классом RadioButton.
Для регистрации ChangeListener у ToggleGroup вызывается метод selectedToggleProperty()
, который возвращает объект ReadOnlyObjectProperty.
У этого объекта вызывается метод addListener()
, который устанавливает слушителя изменений.
Интерфейс ChangeListener определяет метод changed(), который принимает три параметра:
observable - значение, которое изменилось
oldValue - ранее выделенный элемент Toggle (RadioButton)
newValue - элемент Toggle (RadioButton), который сейчс был выбран
С помощью метода getSelectedToggle() у ToggleGroup можно получить выбранный объект RadioButton:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Button; import javafx.scene.control.ToggleGroup; import javafx.geometry.Orientation; import javafx.geometry.Insets; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) throws Exception { Label selectedLbl = new Label(); Button selectBtn = new Button("Select"); RadioButton javaBtn = new RadioButton("Java"); RadioButton jsBtn = new RadioButton("JavaScript"); RadioButton csharpBtn = new RadioButton("C#"); ToggleGroup group = new ToggleGroup(); javaBtn.setToggleGroup(group); jsBtn.setToggleGroup(group); csharpBtn.setToggleGroup(group); selectBtn.setOnAction(event -> { RadioButton selection = (RadioButton) group.getSelectedToggle(); selectedLbl.setText("Selected: " + selection.getText()); }); FlowPane root = new FlowPane(Orientation.VERTICAL, 10, 10); root.getChildren().addAll(javaBtn, jsBtn, csharpBtn, selectBtn, selectedLbl); root.setPadding(new Insets(10)); Scene scene = new Scene(root, 250, 200); stage.setScene(scene); stage.setTitle("RadioButtons in JavaFX"); stage.show(); } }
В данном случае по нажатию на кнопку получаем выбранный в ToggleGroup объект. Этот объект представляет интерфейс Toggle, поэтому мы можем привести его к типу RadioButton.