#概要
JavaFXでゲームを作成した際に、Label
に会話イベントを表示させたい場面があったので、そのことについて書きます。
##環境
- java 13.0.2
- JavaFX 13.0.2
- zsh 5.7.1 (x86_64-apple-darwin19.0.0)
- MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
実装
考え方
今回やろうとしていることは、会話文を一文字ずつ公開範囲を広げつつその度に出力させれば実装できると考えました。
手順
- fxmlファイルの作成(今回はSceneBuilderを利用)
- 起動するためのファイルを作成
- 画面をコントロールするためのファイルを作成(ここに出力の処理を加えます)
- 実行する
##fxmlファイルの作成
SceneBuilder
で画面を作成します。今回は文字を出力させるスペースのLabel
と、Button
を一つずつ設置しました。
コントローラを設定するところがあるので、今回はTestController
としました。
完成したら、表示
またはView
からサンプル・コントローラ・スケルトン
もしくはShow Sample Controller Skelton
を選びます。
コントローラのスケルトンコードが表示されたら、右下のFULL
にチェックを入れて、全体をコピーします。
このfxmlを今回はTest.fxml
という名前で保存します。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="TestController">
<children>
<Label fx:id="textLabel" layoutX="148.0" layoutY="102.0" prefHeight="120.0" prefWidth="305.0" />
<Button fx:id="button" layoutX="260.0" layoutY="292.0" mnemonicParsing="false" onAction="#buttonOnAction" prefHeight="48.0" prefWidth="82.0" />
</children>
</Pane>
起動ファイルの作成
JavaFXを起動するためのファイルを作成します。Start.java
とします。
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.*;
import javafx.scene.Scene;
import javafx.scene.Parent;
public class Start extends Application {
private Scene startScene;
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("test");
startScene = new Scene(FXMLLoader.load(getClass().getResource("Test.fxml")));
primaryStage.setScene(startScene);
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String args[]) {
launch(args);
}
}
##画面をコントロールするためのファイルを作成
最後に画面をコントロールするためのファイルを作成します。
先述の考えをTimeline
を使って実現します。
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.util.Duration;
public class TestController {
private int i;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private Label textLabel;
@FXML
private Button button;
@FXML
void buttonOnAction(ActionEvent event) {
showText("ボタンが押されました");
}
void showPerText(String showText, int i){
textLabel.setText(showText.substring(0, i));
}
void showText(String showText){
i = 0;
Timeline timeline = new Timeline(
new KeyFrame(
new Duration(100),
/*
new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event){
i+=1;
showPerText(showText, i);
}
}
*/
(event) -> {
i+=1;
showPerText(showText, i);
}
)
);
timeline.setCycleCount(showText.length());
timeline.play();
}
@FXML
void initialize() {
assert textLabel != null : "fx:id=\"textLabel\" was not injected: check your FXML file 'Test.fxml'.";
assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'Test.fxml'.";
textLabel.setText("ボタンを押してください");
}
}
ソースファイルはこちらからも見ていただけます。
##実行する
コンパイルする時は*.java
でディレクトリ内の全てのjavaファイルを指定すると楽です。
コンパイルをしたらjava Start
で実行できます。