S-JIS[2012-06-09] 変更履歴

RadioButton(JavaFX Scene Builder)

JavaFX Scene BuilderのRadioButtonのメモ。


概要

選択肢一覧の中から1つを選択するのがラジオボタン。

ひとまとまりのラジオボタン群であることを示すのにToggleGroupを使う。
Javaソース上でシーングラフを作る場合は、RadioButtonインスタンスに自分が所属するToggleGroupインスタンスをセットする。
Scene Builderでは、画面上にRadioButtonコントロールを貼り付け、Propertiesの「Toggle Group」に適当なトグルグループIDを入力する。
一度入力すればトグルグループのコンボボックスの一覧に追加されるので、他のラジオボタンでは同じトグルグループIDを選択すればよい。

また、デフォルトで選択されるラジオボタンには、Propertiesの「Selected」にチェックを入れておく。


ユーザーデータ

複数の中からどのラジオボタンかを特定する為に、RadioButtonにはユーザーデータを登録することが出来る。
Scene Builder上ではユーザーデータは登録できないので、コントローラークラスinitialize()で初期化する。

import javafx.fxml.Initializable;
import javafx.scene.control.RadioButton;
public class ExampleRadioController implements Initializable {

	public RadioButton radio1;
	public RadioButton radio2;
	public RadioButton radio3;
	@Override
	public void initialize(java.net.URL location, java.util.ResourceBundle resources) {
		radio1.setUserData("r1");
		radio2.setUserData("r2");
		radio3.setUserData("r3");
	}
}

		String ud = (String)radio1.getUserData();

getUserData()の戻り型はObjectなので、自分が使う型にキャストする必要がある。


ちなみに、RadioButton#getId()はCSS用のIDなので、個別にCSSを設定するならともかく、ラジオボタンを識別するIDとして使うには駄目そう。


RadioButtonのイベント

ラジオボタンが選択されたときのイベントは、RadioButtonのonActionで捕捉できる。

FXMLのコントローラークラスにそのメソッドを記述する。
(On Actionに入れたのが「#handleRadio1」だとすると、メソッド名は「handleRadio1」になる)

import javafx.event.ActionEvent;
	public void handleRadio1(ActionEvent event) {
		RadioButton rb = (RadioButton) event.getSource();

		System.out.println(rb.getUserData());
	}

そのラジオボタンが選択されたときにこのハンドラーが呼ばれる。

この方法の場合、ラジオボタン毎に個別のハンドラーが作れる反面、似たようなメソッドがたくさん並ぶことになる。

複数のラジオボタンのOn Actionに同じハンドラー名を付けると、メソッドが共通化できる。


ToggleGroupのイベント

ラジオボタンが選択されたときのイベントは、ラジオボタンが属しているToggleGroupでも捕捉することが出来る。
ただしScene Builder上ではToggleGroupオブジェクトのイベントを直接指定することが出来ないので、initialize()でイベントハンドラーを登録しておく。

Scene BuilderでFXMLファイルを作るとToggleGroup自体は記述されているので、普通のコントロール(コンポーネント)と同様にコントローラークラス内にフィールドを定義することが出来る。

FXMLファイル:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="example.ExampleRadioController">
	<children>
		<RadioButton id="radioButton1" fx:id="radio1" layoutX="143.0" layoutY="61.0" selected="true" text="RadioButton1">
			<toggleGroup>
				<ToggleGroup fx:id="toggle1" />
			</toggleGroup>
		</RadioButton>
		<RadioButton id="radioButton1" fx:id="radio2" layoutX="143.0" layoutY="99.0"  text="RadioButton2" toggleGroup="$toggle1" />
		<RadioButton id="radioButton1" fx:id="radio3" layoutX="143.0" layoutY="135.0" text="RadioButton3" toggleGroup="$toggle1" />
	</children>
</AnchorPane>

コントローラークラス:

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
public class ExampleRadioController implements Initializable {

	public RadioButton radio1;
	public RadioButton radio2;
	public RadioButton radio3;

	public ToggleGroup toggle1;
	@Override
	public void initialize(java.net.URL location, java.util.ResourceBundle resources) {
		toggle1.selectedToggleProperty().addListener(
			new ChangeListener<Toggle>() {
				@Override
				public void changed(ObservableValue<? extends Toggle> ov, Toggle oldToggle, Toggle newToggle) {
					System.out.println("old=" + oldToggle);
					System.out.println("new=" + newToggle);
					System.out.println("sel=" + toggle1.getSelectedToggle());
				}
			});
	}
}

新たなラジオボタンが選択されると、ChangeListener#changed()が呼ばれる。
ここでは選択前のラジオボタンと新たに選択されたラジオボタンが引数として渡ってくる。
(RadioButtonクラスはToggleインターフェースを実装している)

また、この時点でToggleGroupのgetSelectedToggle()を呼び出すと新しく選択された方のラジオボタンインスタンスが返ってくる。

個別のRadioButtonイベントとToggleGroupによるイベントのハンドラーが両方とも定義されている場合、
先にToggleGroupによるハンドラーが呼ばれ、その後にRadioButtonのハンドラーが呼ばれる。

ToggleGroup#getSelectedToggle()や引数newToggleのインスタンスは、コントローラークラスのRadioButtonフィールド(fx:idが付けられているもの)と同じインスタンスっぽいので、「==演算子」で比較することも出来そうだが、その方法が保証された方法なのかどうかは知らない。


選択有無の取得

どのラジオボタンが選択されているかを取得する方法。

RadioButtonクラスにisSelected()があるので、個別のラジオボタンが選択されているかどうかを判別できる。

また、ToggleGroupクラスにgetSelectedToggle()があるので、選択されているラジオボタンを取得できる。

import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
public class ExampleRadioController {

	public RadioButton radio1;
	public RadioButton radio2;
	public RadioButton radio3;

	public ToggleGroup toggle1;
	public void handleButton(javafx.event.ActionEvent event) {
		System.out.println(radio1.isSelected());
		System.out.println(radio2.isSelected());
		System.out.println(radio3.isSelected());

		Toggle s = toggle1.getSelectedToggle();
		RadioButton r = (RadioButton) s;
		System.out.println("selected=" + r);

		//「==演算子」でちゃんと判別できるけど、この方法が保証されているのかどうかは不明
		System.out.println(r == radio1);
		System.out.println(r == radio2);
		System.out.println(r == radio3);
	}
}

使用法に戻る / Scene Builder目次へ戻る / JavaFXへ戻る / Javaへ戻る / 技術メモへ戻る
メールの送信先:ひしだま