🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
RPG

RPG (Report Program Generator)とは、IBMの System i(AS/400)サーバ向けのプログラミング言語です。

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

FXML

FXMLは、JavaFXに用意されているXMLベースのGUI記述言語です

Q&A

解決済

1回答

2221閲覧

Javaで、入力されたキーによって画面にテキストを表示したいです

nemo3002

総合スコア3

RPG

RPG (Report Program Generator)とは、IBMの System i(AS/400)サーバ向けのプログラミング言語です。

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

FXML

FXMLは、JavaFXに用意されているXMLベースのGUI記述言語です

1グッド

0クリップ

投稿2020/12/10 09:15

編集2020/12/10 11:41

前提・実現したいこと

Javaを使ってドラクエのようなRPGゲームを作ろうとしています。壁にぶつかってしまったので皆様の知恵をお借りしたいです。

UI開発にJavaFX(GUIビルダーとしてscene builder)を使っています。

今戦闘画面を作っていてプレイヤーの入力したキーによって画面にテキストを表示するということをやろうとしているのですが、原因のわからないNullPointerExceptionが出てきてしまいました。

このエラーの解決方法を教えていただきたいです。またプレイヤーの入力したキーによって画面にテキストを表示するのによい方法があったら教えていただきたいです。

ソースコードほぼ全文なのでとても長くなってしまいましたが、基本的にはBattleScreenクラスのところが一番関係していると思います。

発生している問題・エラーメッセージ

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot invoke "javafx.scene.control.Label.setText(String)" because "this.hp" is null at application.BattleScreenController.textSet1(BattleScreenController.java:38) at application.Main.keyPressed(Main.java:41) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) //省略

該当のソースコード

//import文を省略 public class Main extends Application { private Scene sc1, sc2; BattleScreenController bsc = new BattleScreenController(); @Override public void start(Stage primaryStage) { try { VBox root1 = (VBox)FXMLLoader.load(getClass().getResource("Sample.fxml")); sc1 = new Scene(root1); Pane root2 = (Pane)FXMLLoader.load(getClass().getResource("BattleScreen.fxml")); sc2 = new Scene(root2); primaryStage.setScene(sc1); primaryStage.show(); sc1.setOnKeyPressed(e -> primaryStage.setScene(sc2)); sc2.setOnKeyPressed(this::keyPressed); } catch(Exception exception) { exception.printStackTrace(); } } private void keyPressed(KeyEvent event) { switch (event.getCode()) { case ENTER: bsc.textSet1(); break; case BACK_SPACE: break; default: break; } } public static void main(String[] args) { launch(args);    } }

BattleScreen

1//省略 2public class BattleScreenController { 3 Hero hero = new Hero(); 4 Enemy enemy = new Enemy(); 5 @FXML 6 private ResourceBundle resources; 7 8 @FXML 9 private URL location; 10 11 @FXML 12 private Label sentence3; 13 14 @FXML 15 private Label sentence4; 16 17 @FXML 18 private Label name; 19 20 @FXML 21 private Label hp; 22 23 @FXML 24 private Label sentence1; 25 26 @FXML 27 private Label sentence2; 28 29 public void textSet1 () { 30 enemy.damageC(hero.getAttack(), enemy.getDefence()); 31 hp.setText(String.valueOf(hero.getHp())); 32 sentence1.setText("ゆうしゃの攻撃!!"); 33 sentence2.setText("ゆうしゃはマスターソードを天にかざした"); 34 sentence3.setText("魔王に" + String.valueOf(hero.getAddDamage()) + "ダメージ!!"); 35 sentence4.setText("Press any key to continue"); 36 } 37 38 @FXML 39 void initialize() { 40 assert sentence3 != null : "fx:id=\"sentence3\" was not injected: check your FXML file 'BattleScreen.fxml'."; 41 assert sentence4 != null : "fx:id=\"sentence4\" was not injected: check your FXML file 'BattleScreen.fxml'."; 42 assert name != null : "fx:id=\"name\" was not injected: check your FXML file 'BattleScreen.fxml'."; 43 assert hp != null : "fx:id=\"hp\" was not injected: check your FXML file 'BattleScreen.fxml'."; 44 assert sentence1 != null : "fx:id=\"sentence1\" was not injected: check your FXML file 'BattleScreen.fxml'."; 45 assert sentence2 != null : "fx:id=\"sentence2\" was not injected: check your FXML file 'BattleScreen.fxml'."; 46 } 47}

Hero

1package application; 2 3public class Hero { 4 private int hp = 500; 5 private int attack = 100; 6 private int defence = 50; 7 8 private int addDamage; 9 10 public void damageC(int attack, int defence) { 11 int damage = 0; 12 if (attack - defence > 0) { 13 damage = attack - defence; 14 } else if (attack - defence <= 0) { 15 damage = 1; 16 } 17 this.hp -= damage; 18 this.addDamage = damage; 19    } 20 //getterやsetterを省略
```FXML <?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.*?> <?import javafx.scene.image.*?> <?import javafx.scene.text.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.layout.AnchorPane?> <Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.BattleScreenController"> <children> <VBox prefHeight="480.0" prefWidth="640.0"> <children> <VBox alignment="CENTER" prefHeight="119.0" prefWidth="640.0"> <children> <Label fx:id="name" text="なまえ"> <font> <Font size="26.0" /> </font> </Label> <HBox alignment="CENTER" prefHeight="53.0" prefWidth="507.0"> <children> <Label alignment="CENTER_RIGHT" text="HP:"> <font> <Font size="26.0" /> </font> </Label> <Label fx:id="hp" text="L"> <font> <Font size="26.0" /> </font> </Label> </children> </HBox> </children> </VBox> <ImageView fitHeight="240.0" fitWidth="560.0"> <image> <Image url="@../../../../Documents/プログラミング/キャラチップ/pipo-enemy46set/120x120/pipo-boss004.png" /> </image> <VBox.margin> <Insets left="40.0" right="40.0" /> </VBox.margin> </ImageView> <HBox prefHeight="124.0" prefWidth="640.0"> <children> <VBox alignment="CENTER" prefHeight="200.0" prefWidth="320.0"> <children> <Label text="1: コウゲキ"> <font> <Font size="29.0" /> </font> </Label> <Label text="2: ニゲル"> <font> <Font size="29.0" /> </font> </Label> </children> </VBox> <VBox alignment="CENTER" prefHeight="200.0" prefWidth="320.0"> <children> <Label fx:id="sentence1" alignment="CENTER" prefHeight="25.0" prefWidth="365.0" text="L"> <font> <Font size="20.0" /> </font> </Label> <Label fx:id="sentence2" alignment="CENTER" prefHeight="25.0" prefWidth="365.0" text="L"> <font> <Font size="20.0" /> </font> </Label> <Label fx:id="sentence3" alignment="CENTER" prefHeight="25.0" prefWidth="370.0" text="L"> <font> <Font size="20.0" /> </font> </Label> <Label fx:id="sentence4" alignment="CENTER" prefHeight="25.0" prefWidth="372.0" text="L"> <font> <Font size="20.0" /> </font> </Label> </children> </VBox> </children> </HBox> </children> </VBox> </children> </Pane>

試したこと

問題の大元がBattleScreenクラスのLabel型のhpやnameの定義の部分にあるだろうということまでは考えました。そこでhpやnameに対応する部分のFXMLファイルを調べたのですがやはりよくわかりませんでした。

補足情報(FW/ツールのバージョンなど)

省略しましたがEnemyクラスはHeroクラスと変数、メソッド共にほぼ同じ内容です。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

原因のわからないNullPointerExceptionが出てきてしまいました。

newしたbscと、表示されているシーンのコントローラは全く別物です。
@FXMLが差し込まれることもありませんし、initializeも呼ばれていません。
そのためhp.setTextでヌルポです。

コントローラを取得するにはこのようにします。

Java

1package application; 2 3import javafx.application.Application; 4import javafx.fxml.FXMLLoader; 5import javafx.scene.Scene; 6import javafx.scene.input.KeyEvent; 7import javafx.scene.layout.Pane; 8import javafx.scene.layout.VBox; 9import javafx.stage.Stage; 10 11 12public class Main extends Application { 13 public static void main(String[] args) { launch(args); } 14 15 private Scene sc1, sc2; 16 BattleScreenController bsc;// = new BattleScreenController(); 17 18 @Override 19 public void start(Stage primaryStage) { 20 try { 21 VBox root1 = (VBox) FXMLLoader.load(getClass().getResource("Sample.fxml")); 22 sc1 = new Scene(root1); 23 24// Pane root2 = (Pane)FXMLLoader.load(getClass().getResource("BattleScreen.fxml")); 25 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("BattleScreen.fxml")); 26 Pane root2 = (Pane) fxmlLoader.load(); 27 sc2 = new Scene(root2); 28 bsc = (BattleScreenController) fxmlLoader.getController(); 29 30 primaryStage.setScene(sc1); 31 primaryStage.show(); 32 33 sc1.setOnKeyPressed(e -> primaryStage.setScene(sc2)); 34 sc2.setOnKeyPressed(this::keyPressed); 35 } catch (Exception exception) { 36 exception.printStackTrace(); 37 } 38 } 39 40 private void keyPressed(KeyEvent event) { 41 switch (event.getCode()) { 42 case ENTER: 43 bsc.textSet1(); 44 break; 45 case BACK_SPACE: 46 break; 47 default: 48 break; 49 } 50 } 51}

またプレイヤーの入力したキーによって画面にテキストを表示するのによい方法があったら教えていただきたいです。

何が問題になりそうと考えていますか?

投稿2020/12/10 15:02

編集2020/12/11 04:22
TN8001

総合スコア9855

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nemo3002

2020/12/11 04:03

お返事ありがとうございます!!インステンス化しただけでは@FXMLが差し込まれないし、initializeも呼ばれない。ということをわかっていませんでした。まだ問題は解決できていないのですが一歩進んだのでもう少し自分で考えてそれでもわからなかったらまた質問させていただきます!ありがとうございます!!
TN8001

2020/12/11 04:22

> まだ問題は解決できていない 部分的過ぎましたか。。コードを全文に直しました。 fxmlからのコントローラ取得は定型コードなので、考えてもあまり意味がないです。 そういうもんだと思って覚えちゃってください。
nemo3002

2020/12/11 05:24

コピペして実行し見たら思ったとおりに動きました!!二日以上詰まっていたのでめちゃくちゃ嬉しいです。本当にありがとうございます!コントローラーの取得の方法を定型として覚えておきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問