JavaFXで画面に動的メッセージを表示させたい!

更新:2019/09/12
はじめに
JavaFXを使い始めた最初の頃、入力されたパスワードが一致しないなどのアラート表示させるとき、 以下の写真のように「詳細を見る」などのボタンのイベントを利用してメッセージを表示させる処理をしていました。
ですが、いちいちボタンを押さないとメッセージの内容が見れないのは不便だったのでアラートなどの画面を生成するときに 「詳細を見る」ボタンを押すなどのイベント無しで任意の文字を動的に表示されるようなサンプルアプリを作ってみました。



開発環境
OS : Windows 10 home
IDE : Eclipse Photon

作ったアプリ
よくあるTextFieldに入力された文字をボタンを押すことによって、別のTextFieldに文字を表示させるアプリの発展的なアプリで、 入力された文字を新しく生成された画面に表示させるアプリを作りました。

ディレクトリ構成
このアプリのsrcフォルダの中身は下のようになってます。
 src/
  └application/
    ├Main.java
    ├IndexController.java
    ├MessageController.java
    ├Index.fxml
    └Message.fxml
サンプルコードはこちらから。

簡単にコードを解説
今回のサンプルアプリで最も重要となるのが「MessageController.java」で実装したInitializableインターフェースです。
このインターフェースをオーバーライドしたinitializeメソッド内に書かれた処理は、画面が生成される前に実行されます。

なので、事前にsetMsgメソッドでセットしておいたメッセージをTextFieldにsetTextする事によって、画面生成時に入力したメッセージが表示されるようになります.(画面生成に関する記事はこちらをご覧ください。)

 Main.java 

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
		
public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("Index.fxml"));
			Scene scene = new Scene(root,400,300);
			primaryStage.setScene(scene);
			primaryStage.setTitle("dynamicMessage");
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}


 IndexController.java 

package application;

import java.io.IOException;
			
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class IndexController {
	@FXML
	private TextField message_textField;

	@FXML
	private Button showMessage_button;

	//入力されたメッセージを入れる
	private String msg;

	@FXML
	public void showMessage_button_onClick(Event event) {
		msg = message_textField.getText();
		/*
		 * message_textFieldの入力内容チェック
		 * 何も入力されていない場合、再度入力を要求するメッセージを表示させる。
		 *
		 * 「MessageController.java」のsetterに対して
		 * MessageController.setMsg();の引数としてメッセージをセットする
		 */
		if(msg.equals("")) {
			MessageController.setMsg("入力してください");
			showMessage(event);
		}else {
			MessageController.setMsg(msg);
			showMessage(event);
		}

		//表示されたら入力したメッセージを初期化
		message_textField.setText("");
	}

	/*
	 * Message.fxmlを生成するメソッド
	 */
	private void showMessage(Event event) {
		try {
			Parent parent = FXMLLoader.load(getClass().getResource("Message.fxml"));
			Scene scene = new Scene(parent);
			Stage stage = new Stage();
			stage.setTitle("メッセージ");
			stage.setScene(scene);
			stage.show();
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}


 MessageController.java 

package application;
	
import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Window;

public class MessageController implements Initializable{
	@FXML
	private Label message_textField;

	@FXML
	private Button ok_button;

	//入力されたメッセージを入れる
	private static String msg;

	//message_textFieldに入力されるメッセージのsetter
	public static void setMsg(String msg) {
		MessageController.msg = msg;
	}

	/*
	 * 「Message.fxml」の初期化処理
	 * 「IndexController.java」からsetterに対して渡されたメッセージをTextFieldにセットする
	 */
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		message_textField.setText(msg);
	}

	/*
	 * ウィンドウを閉じる処理
	 */
	@FXML
	public void ok_button_onClick(Event eve) {
		Scene s = ((Node)eve.getSource()).getScene();
		Window window = s.getWindow();
		window.hide();
	}
}


おわりに
動的に文字列を変えることが出来るようになると、作れるアプリの幅も広くなると思います。これからの新しいアプリ作成に活用してみてください!

サンプルコード

関連記事