JavaFX チュートリアル〜今度こそ、初めてでも大丈夫4:RadioButton〜

イントロダクション

以前記載した記事で「初めてでも大丈夫」などと記載していましたが、ちょっと「危ういな」と思いチュートリアルをやってみようとなりました。

今回はラジオボタンの表示をやります。

チュートリアル

ここのページを、戦国Xサラの要領でガンガン斬り伏せながらやっていきます。

<チュートリアル>

基本のコード(ちょっとダメなコード)

public class Lv3_RadioButton extends Application {

	/**
	 * このメソッドは、Applicationクラス(JavaFXのフレームワーク部品)
	 * のメソッドをオーバーライドする。
	 * {@link Application#launch(String...)}から呼び出される。
	 */
	@Override
	public void start(Stage primaryStage) throws Exception {
		// チュートリアルには省略されている部分
		Group group = new Group();
		// この部分がチュートリアルに記載されている。
		//A radio button with an empty string for its label
		RadioButton rb1 = new RadioButton();
		//Setting a text label
		rb1.setText("Home");
		//A radio button with the specified label
		RadioButton rb2 = new RadioButton("Calendar");

		// 上のコンポーネント(Labelとか、イメージとか)
		group.getChildren().addAll(rb1, rb2);
		// チュートリアルでは省略されている
		Scene scene = new Scene(group, 300, 300);
		primaryStage.setScene(scene);
		primaryStage.setTitle("チュートリアル1");
		primaryStage.show();
	}

	/**
	 * メインメソッド。
	 * Apllicationクラスのlaunchメソッドを呼び出す。
	 * 
	 * @param args プログラム引数
	 */
	public static void main(String[] args) {
		launch(args);
	}
}

今回は、ちょっとダメなコードを基本にしていきます。なんでダメなのかは実行結果を見れば一目瞭然。。。

コンポーネントが重なってしまい、意味がわかりません。

ここで、start()メソッドの初めの部分で「Group group = new Group();」というコードがありますが、この部品をGroupからVBoxへ変更します。

Groupはレイアウトクラスですが、VBoxの親の親。。。とちょっと遠い親戚な関係です。下のJavaDocをみてください。

こんな感じでクラスの系譜がちょっと違うのです。コンポーネントを配置するコンテナクラスという意味で「レイアウトクラス」という文言を使いましたが、とりあえずは「VBoxも Groupもコンポーネントを保持するんだな」と理解してくれればOK!

そして、以下の様にVBoxをGroupの代わりに使用してみると。。。

こんな感じで表示されます。

そしてコードはこんな感じになりました。これもイマイチ。。。Gitからダウンロード

public void start(Stage primaryStage) throws Exception {
	// チュートリアルには省略されている部分
	VBox group = new VBox(20b);
	// この部分がチュートリアルに記載されている。

	//A radio button with an empty string for its label
	RadioButton rb1 = new RadioButton();
	//Setting a text label
	rb1.setText("Home");
	rb1.setSelected(true);
	group.getChildren().add(rb1);

	//A radio button with the specified label
	RadioButton rb2 = new RadioButton("Calendar");
	rb2.setToggleGroup(togle);
	group.getChildren().add(rb2);

	RadioButton rb = new RadioButton("Agree");
	group.getChildren().add(rb);

	
	// 上のコンポーネント(Labelとか、イメージとか)
	group.getChildren().addAll(rb1, rb2, rb);
	// チュートリアルでは省略されている
	Scene scene = new Scene(group, 300, 300);
	primaryStage.setScene(scene);
	primaryStage.setTitle("チュートリアル3");
	primaryStage.show();
}

これで、3つあるラジオボタンの1つを選択するとそれのみを選択する様になります。選択することができます。表示結果は下の様になります、

これでは味気ないので次の様な機能を実装しようと思います。

  1. 初期表示時には「家の画像」を表示する
  2. ラジオボタンで選択すると選択した画像を表示する

それぞれ、Home, Calender, Agreeで以下の様な画像です。

Home
Calender
Agree

ちょっとややこしくなってしまいました。。。

<ソースコード>

@Override
public void start(Stage primaryStage) throws Exception {
	// チュートリアルには省略されているものから変更
	// 横のレイアウト
	HBox lineLayout = new HBox();
	// 縦のレイアウト
	VBox group = new VBox(20d);
	// 横のレイアウトに追加
	lineLayout.getChildren().add(group);

	/* トグル・グループの追加
	 * トグルが設定されているラジオボタンは
	 * 1つのグループとして扱われる
	 */
	final ToggleGroup togle = new ToggleGroup();
	//A radio button with an empty string for its label
	RadioButton rb1 = new RadioButton();
	//Setting a text label
	rb1.setText("Home");
	rb1.setToggleGroup(togle);
	rb1.setSelected(true);
	// イベント用UserData
	rb1.setUserData("home");
	// 縦のレイアウトに追加
	group.getChildren().add(rb1);
	//A radio button with the specified label
	RadioButton rb2 = new RadioButton("Calendar");
	rb2.setToggleGroup(togle);
	// イベント用UserData
	rb2.setUserData("calendar");
	// 縦のレイアウトに追加
	group.getChildren().add(rb2);

	RadioButton rb = new RadioButton("Agree");
	// イベント用UserData
	rb.setUserData("contacts");
	// サイズを合わせる
	rb.setToggleGroup(togle);
	// 縦のレイアウトに追加
	group.getChildren().add(rb);
	
	// 横のレイアウトに追加
	ImageView imageView = new ImageView();
	lineLayout.getChildren().add(imageView);
	final Map<String, Image> imageMap = createImageMap(imageView);

	// イベント処理
	togle.selectedToggleProperty().addListener(
			(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) ->{
				if (togle.getSelectedToggle() != null) {
					String userData = togle.getSelectedToggle().getUserData().toString();
					imageView.setImage(imageMap.get(userData));
				}
			});
	// 上のコンポーネント(Labelとか、イメージとか)
	// チュートリアルでは省略されている
	Scene scene = new Scene(lineLayout, 1000, 300);
	primaryStage.setScene(scene);
	primaryStage.setTitle("チュートリアル3");
	primaryStage.show();
}

実行結果

上から順番に、

// 横のレイアウト
HBox lineLayout = new HBox();
// 縦のレイアウト
VBox group = new VBox(20d);
// 横のレイアウトに追加
lineLayout.getChildren().add(group);
  1. 横と縦のレイアウトを用意する。
  2. 縦のレイアウトは20d(double型の20)分の間隔をあけてやる。
  3. 横のレイアウトに縦のレウアウトを追加

イメージは下の様な感じです。

でわでわ。。。