質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

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

Java

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

Q&A

解決済

1回答

6784閲覧

JavaFXでの画面遷移がわからないです。

hositaka

総合スコア14

JavaFX

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

Java

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

0グッド

1クリップ

投稿2017/12/18 09:36

編集2017/12/19 07:21

###前提・実現したいこと
JavaFXを使って画面遷移をさせたいのですが、やり方がよくわからないです。

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

java.lang.NullPointerException <略>

###該当のソースコード
Original.java

package fx; <略> /** * * @author takahara */ public class Original extends Application { private static Original instance; private Stage stage; private Stage stage2; @Override public void start(Stage primaryStage) throws Exception { try { FXMLLoader loader = new FXMLLoader(getClass().getResource("hello.fxml")); Parent root = loader.load(); // fx:rootに紐付いたノードインスタンスが得られる HelloController controller = loader.getController(); // fx:controllerに紐付いたコントローラインスタンスが得られる primaryStage.setTitle("Hello"); // シーン生成 Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } instance = this; } public static void main(String[] args) { launch(args); } /** * Page1へ遷移する * @param labelText */ public void sendhelloController(String labelText) { stage.setTitle("Hello"); /*HelloController controller = new HelloController(); this.replaceSceneContent(controller);*/ } /** * シーンの変更 * @param controller */ private void replaceSceneContent(Parent controller) { Scene scene = stage.getScene(); if (scene == null) { scene = new Scene(controller); stage.setScene(scene); } else { stage.getScene().setRoot(controller); } } public void MainController() { //stage.setTitle("Page2"); try { FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml")); Parent root = loader.load(); HelloController controller = loader.getController(); stage2.setTitle("Hello"); // シーン生成 Scene scene = new Scene(root); stage2.setScene(scene); stage2.show(); } catch(Exception e) { e.printStackTrace(); } } public static Original getInstance() { return instance; } } ```HelloController.java

package fx;

<略>

public class HelloController extends AnchorPane{

@FXML private Button helloButton; @FXML private Label helloLabel; private int cnt; @FXML public void onHelloButtonClicked(ActionEvent event) { Original.getInstance().MainController(); } public void onClick(ActionEvent event) { }

}

hello.fxml

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

<略>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.HelloController"> <children> <Label fx:id="helloLabel" layoutX="156.0" layoutY="158.0" text="Hello World!!" textFill="#da0606"> <font> <Font size="55.0" /> </font> </Label> <Button fx:id="helloButton" layoutX="216.0" layoutY="72.0" mnemonicParsing="false" onAction="#onHelloButtonClicked" text="Button"> <font> <Font size="34.0" /> </font> </Button> </children> </AnchorPane> ```Main.fxml ``` <?xml version="1.0" encoding="UTF-8"?> <略> <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.HelloController"> <children> <VBox layoutX="127.0" layoutY="35.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> <省略> </children> </GridPane> </children> </VBox> </children> </AnchorPane> ```

###試したこと
https://teratail.com/questions/97665 こちらの質問や
https://qiita.com/mix/items/7c797eccad0a5e3a43c3
http://javafx-trick.appspot.com/article/110001/110009/80051.html これらのサイトを見ながらやったですが、JavaFX自体をイマイチ理解しておらず、
fxml上でcontrollerのIDを指定するやり方でやったほうがいいと記載されていたので、何とかそっちでやろうとしていますが丸2日奮闘しても対策方法が見つけることが出来ていません。
Controllerなどの引数のLabelTextとはコピペの名残で使用はしていません。
instanceも何に使っているのかわかってないです。
ゆくゆくは、postgresqlを使って会員サイトのようなものを作りたいのですが、javaプログラム上でcontrollerのIDを指定するのと、fxml上で指定するのどちらが良いかも教えていただけたら幸いです。
初めての質問なので欠けている項目などありましたら、ご指摘承りたく存じます。何卒よろしくお願いします

###補足情報(言語/FW/ツール等のバージョンなど)
java version "1.8.0_151"
eclipse:Version: Oxygen.1a Release (4.7.1a)

###追記
MainController.java

package fx; import <略> public class MainController extends AnchorPane implements Initializable{ @FXML private ChoiceBox<String> dropDown; @FXML private TextField textBox; @FXML private Button button; @Override public void initialize(URL location, ResourceBundle resources) { // 何もしない } public MainController() { } @FXML public void onClick(ActionEvent event) { // テキストボックスに文字列をセットする textBox.setText("ボタンを押しました。"); } }

MainConrollerへの切り替え Hellocontroller.java

package fx; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; public class HelloController extends AnchorPane{ @FXML private Button helloButton; @FXML private Label helloLabel; private int cnt; @FXML public void onHelloButtonClicked(ActionEvent event) throws IOException { /*this.helloLabel.setText("clicked! : " + cnt); cnt++;*/ Original.getInstance().MainController(); } public void onClick(ActionEvent event) { /*this.helloLabel.setText("clicked! : " + cnt); cnt++;*/ //Original.getInstance().MainController(); } }

Original.java

package fx; import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Original extends Application { private static Original instance; private Stage stage; @Override public void start(Stage primaryStage) throws Exception { // インスタンス instance = this; try { FXMLLoader loader = new FXMLLoader(getClass().getResource("hello.fxml")); Parent root = loader.load(); // fx:rootに紐付いたノードインスタンスが得られる stage = primaryStage; // タイトルセット primaryStage.setTitle("Hello"); // シーン生成 Scene scene = new Scene(root); //scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } public void sendhelloController(String labelText) { stage.setTitle("Hello"); HelloController controller = new HelloController(); this.replaceSceneContent(controller); } private void replaceSceneContent(Parent controller) { Scene scene = stage.getScene(); if (scene == null) { scene = new Scene(controller); stage.setScene(scene);//このステージで使用されるシーンを指定 System.out.println("a");//確認用文字出力 } else { stage.getScene().setRoot(controller); } } public void MainController() throws IOException { stage.setTitle("Main"); FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml")); Parent root = loader.load(); // fx:rootに紐付いたノードインスタンスが得られる MainController controller = loader.getController(); // fx:controllerに紐付いたコントローラインスタンスが得られる this.replaceSceneContent(controller); } public static Original getInstance() { return instance; } }

Main.fxml

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import javafx.scene.text.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <?import javafx.collections.FXCollections ?> <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.MainController"> <略> </AnchorPane>

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

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

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

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

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

masaya_ohashi

2017/12/19 01:08

stageとstage2で変数がわかれていますが、ウィンドウは2つ表示する予定ですか?
hositaka

2017/12/19 04:32

ウィンドウは1つだけ表示する予定です。
guest

回答1

0

ベストアンサー

エラー箇所

Java

1stage2.setTitle("Hello");

stage2という変数はここに至るまで一なにも代入されていないためnullな状態です。
Main.fxmlを「別ウィンドウ」として表示するのであればstageとstage2を分ける必要がありますが、画面が切り替わるだけであればstageを流用しなければなりません。そもそもstart()の中でprimaryStageをstageへ代入する処理もないので、stageもnullですね。そこも直さないといけません。

replaceSceneContentが用意されているのに使っていない

コメントアウトしている様子から、おそらくエラーが出たので自分なりにstart()の中をコピペしてMainController()のシーン生成部分を作られたのでしょうが、「JavaFXを理解していない」と自分でわかっていながら「アレンジ」を加えるのはよくありません。躓いたからといってお手本から逃げることは余計に悪化する一方です。料理初心者がレシピを守らずアレンジを加えて悲惨になることは容易に想像がつきます。
ただ、これは「ウィンドウは一つで中身が切り替わる画面遷移」の処理なので、ウィンドウが2つである場合、この処理を使っていないのは正解です。

やりたいことが違うのにコントローラが1つしかない

JavaFXで、fxmlとcontrollerは対のものであり、hello.fxmlとMain.fxmlどちらもHelloControllerに紐付いているのはおかしいです。「レイアウトが違うだけで要素は同じ」である場合、このようなことも有りえますが、おそらくhelloButtonやhelloLabelがあるのはhello.fxmlだけであり、Main.fxmlにはないですよね?なのにMain.fxmlがHelloControllerに紐付いているのはおかしいです。MainControllerといった具合に、Main.fxml用のコントローラを専用に用意するべきです。Main.fxmlのfx:controllerにはそのMainControllerにしてください。

javaプログラム上でcontrollerのIDを指定するのと、fxml上で指定するのどちらが良いか

あなたが参考にしたteratailの質問でも私が言っているように、fxml上でコントローラを指定することを推奨しています。fxml側でコントローラを指定しておけば、

全体

コードを見るに、あなたはまだJavaの知識すら初歩段階であるにもかかわらず、JavaFXの知識ばかりを身に着けようとし、3ステップくらい先のことをやろうとしています。これではいつまでも理解が追いつかないままで進んでしまいます。私はこういったことをしてしまう初心者には厳しくあたって方向修正するようにしています。

追記

不要コードとおぼしきものの削除、インデントの整理、処理の共通化を行いました。

Original.java

Java

1public class Original extends Application { 2 private static Original instance; 3 private Stage stage; 4 @Override 5 public void start(Stage primaryStage) throws Exception { 6 // インスタンス 7 instance = this; 8 stage = primaryStage; 9 try { 10 // replaceSceneContentを改善してFXMLLoaderの処理の内包、 11 // ウィンドウタイトルの変更も同時に行うよう修正。 12 replaceSceneContent("hello.fxml", "Hello"); 13 } catch(Exception e) { 14 e.printStackTrace(); 15 } 16 } 17 18 public static void main(String[] args) { 19 launch(args); 20 } 21 22 private void replaceSceneContent(String fxmlFile, String windowTitle) { 23 FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFile)); 24 Parent root = loader.load(); // fxmlに定義したノードの一番根っこの部分(hello.fxml、Main.fxmlで言えばAnchorPane)が得られる 25 26 Scene scene = stage.getScene(); 27 if (scene == null) { 28 scene = new Scene(root); // シーンの初期化に必要なのはノード 29 stage.setScene(scene);//このステージで使用されるシーンを指定 30 stage.show(); 31 System.out.println("a");//確認用文字出力 32 } else { 33 stage.getScene().setRoot(root); 34 } 35 36 // タイトルセット 37 stage.setTitle(windowTitle); 38 } 39 40 public void MainController() throws IOException { 41 this.replaceSceneContent("Main.fxml", "Main"); 42 } 43 44 public static Original getInstance() { 45 return instance; 46 } 47}

MainController.java

Java

1package fx; 2 3import <> 4 5public class MainController implements Initializable { // extends AnchorPaneをやめる。コントローラとノードは別であるべき。 6 @FXML 7 private ChoiceBox<String> dropDown; 8 @FXML 9 private TextField textBox; 10 @FXML 11 private Button button; 12 13 @Override 14 public void initialize(URL location, ResourceBundle resources) { 15 // 何もしない 16 } 17 18 public MainController() { 19 } 20 21 @FXML 22 public void onClick(ActionEvent event) { 23 // テキストボックスに文字列をセットする 24 textBox.setText("ボタンを押しました。"); 25 } 26}

HelloController.java

Java

1package fx; 2 3import java.io.IOException; 4import java.net.URL; 5import java.util.ResourceBundle; 6import javafx.event.ActionEvent; 7import javafx.fxml.FXML; 8import javafx.fxml.FXMLLoader; 9import javafx.fxml.Initializable; 10import javafx.scene.control.Button; 11import javafx.scene.control.Label; 12import javafx.scene.layout.AnchorPane; 13 14public class HelloController implements Initializable {// extends AnchorPaneをやめる。コントローラとノードは別であるべき。コントローラクラスにはInitializableインタフェースを実装しておくべき。 15 @FXML 16 private Button helloButton; 17 @FXML 18 private Label helloLabel; 19 private int cnt; 20 21 @Override 22 public void initialize(URL location, ResourceBundle resources) { 23 // 何もしない 24 } 25 26 @FXML 27 public void onHelloButtonClicked(ActionEvent event) throws IOException { 28 /*this.helloLabel.setText("clicked! : " + cnt); 29 cnt++;*/ 30 Original.getInstance().MainController(); 31 } 32}

hello.fxml、Main.fxmlに変更はなし。

投稿2017/12/19 01:35

編集2017/12/19 08:34
masaya_ohashi

総合スコア9206

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

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

hositaka

2017/12/19 04:37

Controllerのプログラムを2つ作り、replaceSceneContentを使うことで、タイトルだけがMainの画面には行ったのですが、Main.fxmlをうまく読み込めていないせいで画面が真っ白なままになってしまいます。 public void MainController() { stage.setTitle("Main"); MainController controller = new MainController(); this.replaceSceneContent(controller); } hello.fxmlやMain.fxmlでは<fx:root>を使用していないので、コピペした通りsetroot();をしても意味がないというのは何となく分かってはいるのですが、どのようにしたらよいのでしょうか?
masaya_ohashi

2017/12/19 04:42

Main.fxmlのfx:controllerには新しく作ったControllerが紐付いていますか?
hositaka

2017/12/19 05:58

お早いご返答大変ありがとうございます。 紐付いております。 コピペのfxmlでは<fx:root type="javafx.scene.layout.AnchorPane" xmlns:fx="http://javafx.com/fxml"> <!-- page1,2fxmlではココでcontrollerを指定してない!-->このようになっているので、Controllerのプログラムでfxmlloader.setRootが有効になっているのかな?と思っているのですがよくわかっていません。 https://teratail.com/questions/97665 こちらのサイトのように、呼び出す側であるOriginal.javaで、 public void MainController() throws IOException { stage.setTitle("Main"); //MainController controller = new MainController(); FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml")); Parent root = loader.load(); // fx:rootに紐付いたノードインスタンスが得られる MainController controller = loader.getController(); // fx:controllerに紐付いたコントローラインスタンスが得られる this.replaceSceneContent(controller); } このようにして、Main.fxmlを読み込んでそのcontrollerをゲットしてreplace~Contentに渡せばいいのかと思いやっていますが、出来ず理解不足です。 自分のfxmlで<fx:root>タグで囲んで、http://javafx-trick.appspot.com/article/110001/110009/80051.html こちらのサイトのサンプルを自分のに置き換えてやったほうが良いのでしょうか? 取り敢えず今、fxmlを最初から理解しようと奮闘中でございます。付き合っていただき本当にありがとうございます
masaya_ohashi

2017/12/19 06:03

「やっていますが、出来ず理解不足です。」ここなんですが、エラーメッセージが出るはずですよね?おそらくstageがnullなことが原因かと思います。私の回答の一番上に「エラー箇所」として書かれていることです。そこを直さないとreplaceSceneContentを何回呼んでもエラーになりますよ。
hositaka

2017/12/19 06:18

startメソッドでstage = primaryStage;を追加いたしました。記載し忘れており申し訳ありません。 プログラムを実行するとHello.fxmlが表示され、ボタンを押すと、ウィンドウタイトルがMainになり中身のほうは真っ白になっているのが、現状になっております。
hositaka

2017/12/19 06:23

public MainController() { FXMLLoader fxmlLoader = new FXMLLoader(Original.class.getResource("Main.fxml")); fxmlLoader.setRoot(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } MainControllerのコンストラクタをこのようにしたところ、 Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774) at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Node.fireEvent(Node.java:8413) at javafx.scene.control.Button.fire(Button.java:185) at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:417) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416) at com.sun.glass.ui.View.handleMouseEvent(View.java:555) at com.sun.glass.ui.View.notifyMouse(View.java:937) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769) ... 48 more Caused by: javafx.fxml.LoadException: /home/a/eclipse-workspace/JavaFXHelloWorld/bin/fx/Main.fxml:11 at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409) at fx.Original.MainController(Original.java:103) at fx.HelloController.onHelloButtonClicked(HelloController.java:27) ... 58 more Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root value already specified. /home/a/eclipse-workspace/JavaFXHelloWorld/bin/fx/Main.fxml at fx.MainController.<init>(MainController.java:49) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51) at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927) at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971) at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220) at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744) at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527) ... 62 more Caused by: javafx.fxml.LoadException: Root value already specified. /home/a/eclipse-workspace/JavaFXHelloWorld/bin/fx/Main.fxml at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597) at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2755) at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2704) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409) at fx.MainController.<init>(MainController.java:47) ... 74 more 以下のようなエラーが出ておりました、コンストラクタなのにvoidをつけていた自分のミスです。困惑させて申し訳ございません
masaya_ohashi

2017/12/19 06:29

fxmlのfx:controllerを設定しているのであれば、new MainController()のように直接コントローラのインスタンスを作成してはいけません。また、コンストラクタの中でfxmlを読み込む処理をすると https://teratail.com/questions/97665 と同じようにコンストラクタが無限ループしてしまいます。 MainControllerのコンストラクタ内でfxmlを読み込むのはやめましょう。 質問文に「追記」する形で、現在のMainControllerのコード、Main.fxmlの内容、MainControllerへ画面を切り替える処理の部分を書き加えてください。質問文に元々書かれていたそれぞれのコードを編集してはいけません。質問のやりとりの時系列が追えなくなります。
hositaka

2017/12/19 07:24 編集

お手数おかけいたします。fxmlは変更はありません。 Controller側で、fxmlをロードせずに、replaceSceneContentメソッドを用いて、どのようにシーンを変えられるのかが疑問に思っております。 追記忘れです。Main.fxmlとMAinControllerは紐付けておきました。新たに追記しました。すみません
masaya_ohashi

2017/12/19 07:15

変更なかったらMain.fxmlとMainController紐付いてないじゃないですか。fx:controllerにMainControllerを指定しないと紐付かないですよ。
masaya_ohashi

2017/12/19 07:21

「Controller側で、fxmlをロードする」のではなく、「ロードしたfxmlから紐付いたControllerを取り出す というのがfxmlでのコントローラ指定の役割です。以下のコードにはそういう意味があります。 public void MainController() throws IOException { stage.setTitle("Main"); //MainController controller = new MainController(); FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml")); Parent root = loader.load(); // fx:rootに紐付いたノードインスタンスが得られる MainController controller = loader.getController(); // fx:controllerに紐付いたコントローラインスタンスが得られる this.replaceSceneContent(controller); }
hositaka

2017/12/19 07:34

replaceSceneContentメソッドの一番下でstage.getScene().setRoot(controller);と行っておりますが、setRootの説明が「オブジェクト階層のルートを設定します。このメソッドに渡される値は、<fx:root>タグの値として使用されます。このメソッドは、<fx:root>を使用するときにドキュメントをロードする前に呼び出す必要があります 。」と記載されていたので、Main.fxmlでは、fx:rootタグで囲んでいないので、処理が上手くいかずに、画面が真っ白という解釈でよろしいのでしょうか? ここまで来てなぜ画面が上手く表示されないのか困惑しています。
hositaka

2017/12/19 07:40

Parent root = loader.load();MainControllerメソッドでこちらのノードインスタンスを使用していないのもおかしいですか?質問攻めで申し訳ないです
masaya_ohashi

2017/12/19 07:41

まずControllerそのものをAnchorPaneの拡張クラスになっていることがおかしな原因なので、もういっそのこと正しく動くであろうコードを追記します。
masaya_ohashi

2017/12/19 08:09

追記しました。最低限のことだけにコードを減らしました。
masaya_ohashi

2017/12/19 08:10

動作テストはしてないのでエラーが起こるかもしれません。
hositaka

2017/12/19 08:31

コンソールに確認文字出力である「a」が表示されるだけで、画面も表示されなくなってしまいました。
masaya_ohashi

2017/12/19 08:35

すいません、削除した中にstage.show()が含まれていました。これは呼ばなければウィンドウが出てこないのでreplaceSceneContentに追加しました。位置を確認して追加してみてください。
hositaka

2017/12/19 09:15 編集

大変誠に感謝申し上げます。ありがとうございました。ついに出来ました。泣きそうです。 先ほどのstage.show()の追加はトップ画面はNULLなのでif文で分岐されてしまうから、入れたということですね。 お答えいただかなくても結構なので、もし、お時間があればでよろしいので、最後に質問させていただきます。 ①replaceSceneContentの3行目のScene scene = stage.getScene();はどういった処理がなされているのでしょうか?プロパティシーンの取得というのが分からないです。 ②stage.getScene().setRoot(root);でMain.fxmlが表示される理屈が分からないです。 ③最終的にはpostgresqlを使って会員の認証を行った後、会員ごとにデータを挿入したり取ってきたりする予定なのですが、今回のプログラムを拡張させていけば完成する見込みはありますでしょうか? ④正直、私の知識だとJavafxでやるよりSwingでやったほうが早いと思いますか? ⑤質問者様が私のようにプログラミングで壁にぶち当たった時は、どのようにして対処なされておりますでしょうか? 長々と大変失礼いたしました。感謝してもしきれないです。ありがとうございました。
masaya_ohashi

2017/12/19 09:27

①例え話ですが、Stageは文字通り舞台のステージで、Sceneは背景の書き割りだと思ってください。 Stageに設定されているSceneを取得するのがgetSceneです。初期段階では何のSceneも設定されていないので、nullが返ります。「あ、まだScene設定してないのね」とわかったら、渡されたrootを元にSceneを作ってStageに設定します。②に繋がることですが、「すでにSceneがあったら、土台を再利用して見た目だけ変えよう」というのがgetScene().setRoot()です。 ③それはもちろんいつかは完成すると思いますが、次はpostgresqlをJavaで使うためにJDBCという技術が必要になります。それの勉強もまた大きな課題です。 ④Java8の時点でOracleはSwingのサポート(というよりJavaFX以外のUI系のサポート)を打ち切ると言っています。まあ、かといってJavaFXが今後主流になるかと言われると、Oracleが早速放置し始めたのでなんとも言えないです。ですが、一応メインストリームはJavaFXのほうをやっていたほうがいいでしょう。 ⑤関連ワードをとにかく拾い上げて検索します。エラーメッセージで検索するのはもちろん、使おうとしている技術の「入門」の資料を読み漁ります。
hositaka

2017/12/19 09:41

わざわざご丁寧に回答していただきありがとうございます。javafx-postgresqlで検索しても、あまりヒットせず戦慄していますが、やれるところまではやってみます。また、すぐにお世話になるかもしれませんが、何卒よろしくお願いします。質問者様に足を向けては寝られません。丸一日付き合っていただき本当にありがとうございました。
masaya_ohashi

2017/12/20 00:06

javafxとpostgresqlに直接的な関係はありません。JavaFXはデータを画面に表示するもの、PostgreSQLはDBからデータを引き出すもの、JDBCはJavaでDBにアクセスするためのもの、と役割が一つずつ分離しています。なので、個々の勉強をすれば自ずと組み立て方はわかるものです。ゆっくり一つずつ使いこなせるようになりましょう。 あと、⑤の追加回答ですが、まずはエラーのスタックトレースを舐めるように見ることです。一番上には主因たる内容がきちんと書かれていますし、次の行以下には「どこで呼び出したメソッドで問題が起きたか」等の位置まで確認できます。はっきり言ってミスの8割はエラーメッセージとスタックトレースを見るだけで解決できるはずです。複雑な要因になってくると、ソースコードを深く追っていくことになりますが、それもきちんとめげずにやれば問題は9割5分は解決します。Eclipse等のデバッガを使えば、変数がどのように変わっていくかが見えるようになるので、それらのデバッグツールを使うのも有効です。デバッガが使えないなら、ログ出力等を埋め込んで「本来ここではこうなっているべきという想定が正しいか」を検証しながら問題箇所を探します。とにかくデバッグは地道な作業です。基本的に「バグ」と呼ばれるものの殆どは「コーディングした自分がどこかで使い方を間違えている」ことに起因します。言語やライブラリを疑う前に、自分を疑う癖を付けましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問