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

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

ただいまの
回答率

90.35%

  • Java

    14373questions

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

  • JavaFX

    408questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 967

hositaka

score 4

前提・実現したいこと

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

<?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>  
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • masaya_ohashi

    2017/12/19 10:08

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

    キャンセル

  • hositaka

    2017/12/19 13:32

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

    キャンセル

回答 1

checkベストアンサー

+1

 エラー箇所

stage2.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

public class Original extends Application {
    private static Original instance;
    private Stage stage;
    @Override
    public void start(Stage primaryStage) throws Exception {
        // インスタンス
        instance = this;
        stage = primaryStage;
        try {
            // replaceSceneContentを改善してFXMLLoaderの処理の内包、
            // ウィンドウタイトルの変更も同時に行うよう修正。
            replaceSceneContent("hello.fxml", "Hello");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void replaceSceneContent(String fxmlFile, String windowTitle) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlFile));
        Parent root = loader.load(); // fxmlに定義したノードの一番根っこの部分(hello.fxml、Main.fxmlで言えばAnchorPane)が得られる

        Scene scene = stage.getScene();
        if (scene == null) {
            scene = new Scene(root); // シーンの初期化に必要なのはノード
            stage.setScene(scene);//このステージで使用されるシーンを指定
                        stage.show();  
            System.out.println("a");//確認用文字出力
        } else {
            stage.getScene().setRoot(root);
        }

        // タイトルセット
        stage.setTitle(windowTitle);
    }

    public void MainController() throws IOException {
        this.replaceSceneContent("Main.fxml", "Main");
    }

    public static Original getInstance() {
        return instance;
    }
}

MainController.java

package fx;

import <略>

public class MainController implements Initializable { // extends AnchorPaneをやめる。コントローラとノードは別であるべき。
    @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("ボタンを押しました。");
    }
}

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 implements Initializable {// extends AnchorPaneをやめる。コントローラとノードは別であるべき。コントローラクラスにはInitializableインタフェースを実装しておくべき。
    @FXML
    private Button helloButton;
    @FXML
    private Label  helloLabel;
    private int cnt;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // 何もしない
    }

    @FXML
    public void onHelloButtonClicked(ActionEvent event) throws IOException {
        /*this.helloLabel.setText("clicked! : " + cnt);
        cnt++;*/
        Original.getInstance().MainController();
    }
}

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/19 13: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();をしても意味がないというのは何となく分かってはいるのですが、どのようにしたらよいのでしょうか?

    キャンセル

  • 2017/12/19 13:42

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

    キャンセル

  • 2017/12/19 14: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を最初から理解しようと奮闘中でございます。付き合っていただき本当にありがとうございます

    キャンセル

  • 2017/12/19 15:03

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

    キャンセル

  • 2017/12/19 15:18

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

    キャンセル

  • 2017/12/19 15: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をつけていた自分のミスです。困惑させて申し訳ございません

    キャンセル

  • 2017/12/19 15:29

    fxmlのfx:controllerを設定しているのであれば、new MainController()のように直接コントローラのインスタンスを作成してはいけません。また、コンストラクタの中でfxmlを読み込む処理をすると https://teratail.com/questions/97665 と同じようにコンストラクタが無限ループしてしまいます。
    MainControllerのコンストラクタ内でfxmlを読み込むのはやめましょう。

    質問文に「追記」する形で、現在のMainControllerのコード、Main.fxmlの内容、MainControllerへ画面を切り替える処理の部分を書き加えてください。質問文に元々書かれていたそれぞれのコードを編集してはいけません。質問のやりとりの時系列が追えなくなります。

    キャンセル

  • 2017/12/19 15:50 編集

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

    キャンセル

  • 2017/12/19 16:15

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

    キャンセル

  • 2017/12/19 16: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);

    }

    キャンセル

  • 2017/12/19 16:34

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

    キャンセル

  • 2017/12/19 16:40

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

    キャンセル

  • 2017/12/19 16:41

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

    キャンセル

  • 2017/12/19 17:09

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

    キャンセル

  • 2017/12/19 17:10

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

    キャンセル

  • 2017/12/19 17:31

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

    キャンセル

  • 2017/12/19 17:35

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

    キャンセル

  • 2017/12/19 18:10 編集

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

    長々と大変失礼いたしました。感謝してもしきれないです。ありがとうございました。

    キャンセル

  • 2017/12/19 18: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のほうをやっていたほうがいいでしょう。
    ⑤関連ワードをとにかく拾い上げて検索します。エラーメッセージで検索するのはもちろん、使おうとしている技術の「入門」の資料を読み漁ります。

    キャンセル

  • 2017/12/19 18:41

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

    キャンセル

  • 2017/12/20 09:06

    javafxとpostgresqlに直接的な関係はありません。JavaFXはデータを画面に表示するもの、PostgreSQLはDBからデータを引き出すもの、JDBCはJavaでDBにアクセスするためのもの、と役割が一つずつ分離しています。なので、個々の勉強をすれば自ずと組み立て方はわかるものです。ゆっくり一つずつ使いこなせるようになりましょう。

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

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    14373questions

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

  • JavaFX

    408questions

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