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

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

ただいまの
回答率

88.81%

JavaFXのTableViewを利用して表を作成したい

受付中

回答 1

投稿

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

_tamy

score 10

初めての質問投稿・プログラミング初心者ですので間違った表現などありましたら申し訳ないです。

前提・実現したいこと

JavaFXで、読書記録をつけるプログラムを作成しています。
メインクラス(OneHundredReading.java)のほかにコントローラークラス(OneHundredReadingController2.java)と本のインスタンスを作成するクラス(BookProperty.java)をつくりました。fxmlはそれ用のファイルを作成して記述しています。

本のインスタンスデータを、javaFXのTableViewを利用して表にしたいです。

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

コントローラークラス内で
TableView<BookProperty>型のtable,
TableColumn<BookProperty, StringProperty>型のdateColumn, titleColumn, authorColumn,
ObservableList<BookProperty>型のtableRecordを用意しました。

initializeメソッド内で
table.itemsProperty().setValue(tableRecord);
table.setItems(tableRecord);
table.getItems().add(BookProperty型インスタンス)
など、tableにインスタンスの情報を流し込もうとすると、コンパイルは通るのですが実行時にエラーが出てしまいます。

Exception in Application start method
java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javafx.fxml.LoadException:
(今回利用するファイルを入れたフォルダ)/OneHundredReading.fxml

        at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3237)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
        at OneHundredReading.start(OneHundredReading.java:18)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
        ... 1 more
Caused by: java.lang.NullPointerException
        at OneHundredReadingController2.initialize(OneHundredReadingController2.java:34)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
        ... 17 more

該当のソースコード

もっとも怪しそうなコントローラークラス

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class OneHundredReadingController2 implements Initializable {

    @FXML
    private TableView<BookProperty> table;
    @FXML
    private TableColumn<BookProperty, StringProperty> dateColumn;
    @FXML
    private TableColumn<BookProperty, StringProperty> titleColumn;
    @FXML
    private TableColumn<BookProperty, StringProperty> authorColumn;
    private ObservableList<BookProperty> tableRecord;


    @Override
    public void initialize(URL url, ResourceBundle rb) {
        tableRecord = FXCollections.observableArrayList();
        table.itemsProperty().setValue(tableRecord);//エラーが出ます
        table.setItems(tableRecord);//エラーが出ます

        dateColumn.setCellValueFactory(new PropertyValueFactory<BookProperty, StringProperty>("title"));
        titleColumn.setCellValueFactory(new PropertyValueFactory<BookProperty, StringProperty>("author"));
        authorColumn.setCellValueFactory(new PropertyValueFactory<BookProperty, StringProperty>("date"));

        tableRecord.add(new BookProperty("title", "author", "date"));
        tableRecord.add(new BookProperty("title2", "author2", "date2"));

        System.err.println("initialize");

        for (Object o : tableRecord) {
        System.err.println(o.toString());            
        }

        //こちらも有効化するとエラーになります
        //table.getItems().add(new BookProperty("testtitle", "testauthor", "testdate"));

        tableRecord.addAll(new BookProperty("title3", "author3", "date3"));

    }
}


本のインスタンスクラス
※Propertyの特例の扱いがいまいちつかめなかったので、通常のセッタ・ゲッタとPropertyメソッド両方作ってあります。

import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;

public class BookProperty {
    private final SimpleStringProperty title;
    private final SimpleStringProperty author;
    private final SimpleStringProperty date;

    public BookProperty(String title, String author, String date) {
        this.title = new SimpleStringProperty(title);
        this.author = new SimpleStringProperty(author);
        this.date = new SimpleStringProperty(date);
    }

    public StringProperty titleProperty() {
        return title;
    }

    public StringProperty authorProperty() {
        return author;
    }

    public StringProperty dateProperty() {
        return date;
    }


    public String getTitle() {
        return title.get();
    }

    public void setTitle(String buf) {
        title.set(buf);
    }

    public String getAuthor() {
        return author.get();
    }

    public void setAuthor(String buf) {
        author.set(buf);
    }

    public String getDate() {
        return date.get();
    }

    public void setDate(String buf) {
        date.set(buf);
    }

}

メインクラス

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.fxml.FXMLLoader;

public class OneHundredReading extends Application {
    Stage stage;

    @Override
    public void start(Stage primaryStage) throws Exception {
        stage = primaryStage;
        primaryStage.setTitle("100Reading");
        Pane myPane_top = (Pane)
    FXMLLoader.load(getClass().getResource("OneHundredReading.fxml"));
        Scene myScene = new Scene(myPane_top);
        primaryStage.setScene(myScene);
        primaryStage.show();

    }

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

字数オーバーしてしまったのでfxmlは省略します

試したこと

コントローラークラスの該当コードをコメントアウトした状態であれば実行できますし、ウィンドウも表示されます。
(もちろん表は空のままです)
指示された行数としてもNullPointerExeptionが最も怪しいと思っていて、TableColumnの指定型を変えたりしてみたのですが解決には至りませんでした。

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

OpenJDK11.0.1
OpenJFX11.0.2
をマージして利用しています。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • wwbQzhMkhhgEmhU

    2019/02/20 19:59

    TableColumnとか使ったことないですが、ドキュメントと他の事例を見る限り、StringPropertyを使っている例を見かけませんでした。スタックトレース上の行番号がどうなっているのかよく分からず、例外のカラクリまでは理解できていませんが、StringPropertyだとbindingに支障があるような気もするので、Stringにしてみては?
    (更新用にStringProperty自体を使用している例はあったのですが、I/FはあくまでもStringのようでした)

    キャンセル

回答 1

0

自作したFXMLファイルで実行したところエラーが発生せず表が表示されました。
イメージ説明
期待通りの見た目かは分かりませんがFXMLファイルになにか間違いがあるのではないかと思います(例えばfx:idが指定されていない)。

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

<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0"
            prefWidth="600.0"
            xmlns="http://javafx.com/javafx/8.0.172-ea"
            xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="OneHundredReadingController2">
   <children>
      <TableView fx:id="table" prefHeight="400.0" prefWidth="600.0">
        <columns>
          <TableColumn fx:id="dateColumn" prefWidth="200.0" text="日付" />
          <TableColumn fx:id="titleColumn" prefWidth="200.0" text="タイトル" />
          <TableColumn fx:id="authorColumn" prefWidth="200.0" text="作者" />
        </columns>
      </TableView>
   </children>
</AnchorPane>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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