为什么 JavaFX TableView 不显示数据?

Why isnt JavaFX TableView displaying data?

我一直在做一个项目来尝试学习 Java,但我一直无法让 Tableview 正常工作。我已经查看了其他帖子,到目前为止我已经确定:

然而,尽管如此,我仍然无法填充我的数据。编译这个列表会创建一个带有占位符文本的空 TableView,尽管我的 println 显示列表和 tableview 都包含有效数据。

在此代码的真实版本中,用户可以向表视图添加内容,列表中的添加内容 "appear" 为空白但可选择的条目。

GUI class 是

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.ArrayList;

public class GUI extends Application {

    //Variable initialization
    @FXML
    TableView tvTest=new TableView ();
    @FXML
    TableColumn<TestObj, Integer> keyCol=new TableColumn<>("Key");
    @FXML
    TableColumn<TestObj, String> aCol=new TableColumn<>("A");
    @FXML
    TableColumn<TestObj, String> bCol=new TableColumn<>("B");
    @FXML
    TableColumn<TestObj, String> cCol=new TableColumn<>("C");

    ArrayList<TestObj> testObjs=new ArrayList<TestObj>();
    ObservableList<TestObj> testObjList;

    //Sets up window
    @Override
    public void start(Stage primaryStage)throws IOException {
        primaryStage.setTitle("Table View Test");
        Parent root = FXMLLoader.load(getClass().getResource("tvTest.fxml"));
        Scene scene = new Scene(root,800,500);
        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        setupTable();
        primaryStage.show();
    }

    //Creates cell factories and loads up lists
    private void setupTable(){

        //Test objects
        testObjs.add(new TestObj(1,"A1","B1","C1"));
        testObjs.add(new TestObj(2,"A2","B2","C2"));
        testObjs.add(new TestObj(3,"A3","B3","C3"));
        testObjList= FXCollections.observableList(testObjs);

        //Cell value factory creation
        keyCol.setCellValueFactory(new PropertyValueFactory<TestObj,Integer>("key"));
        aCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("A"));
        bCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("B"));
        cCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("C"));

        //Sets table data
        tvTest.setItems(testObjList);

        //Test to confirm
        System.out.println(testObjList.size());//Confirms 3 items in list
        System.out.println(tvTest.getItems().size());//Confirms 3 items in table

        //Make sure data is correct in list
        System.out.println("_____________________");
        for(int i = 0; i< testObjList.size(); i++){
            System.out.println(testObjList.get(i).getKey()+"|"+ testObjList.get(i).getA()+"|"+testObjList.get(i).getB()+"|"+ testObjList.get(i).getC());
        }
        System.out.println("_____________________");
    }
}

testObj class 是

public class TestObj {
    int key;
    String a;
    String b;
    String c;

    public int getKey() {
        return key;
    }

    public void setKey(int key) {
        this.key = key;
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    TestObj(int key, String A, String B, String C){
        this.key=key;
        this.a=A;
        this.b=B;
        this.c=C;
    }
}

FXML 文件是

<?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="GUI">
   <children>
      <TableView layoutX="14.0" layoutY="14.0" prefHeight="372.0" prefWidth="570.0" fx:id="tvTest">
        <columns>
          <TableColumn fx:id="keyCol" prefWidth="72.0" text="Key" />
          <TableColumn fx:id="aCol" prefWidth="166.0" text="A" />
            <TableColumn fx:id="bCol" prefWidth="166.0" text="B" />
            <TableColumn fx:id="cCol" prefWidth="166.0" text="C" />
        </columns>
      </TableView>
   </children>
</AnchorPane>

如果有帮助,主要 class 是

import javafx.application.Application;

public class Main {
    public static void main(String[] args) {
        Application.launch(GUI.class, args);
    }
}

我正在使用 maven 导入 o​​penJFX,它一直在使用此 TableView 除外。

同样,编译此列表会创建一个带有占位符文本的空 TableView,尽管我的 println 显示列表和 tableview 都包含有效数据。

如果有帮助:在此代码的真实版本中,用户可以向表视图添加内容,列表中的添加内容 "appear" 作为空白但可选择的条目。

非常感谢

您不需要初始化 @FXML 注释属性,因为它们将由 JavaFX 注入。

这样试试:



    @FXML
    TableView tvTest;
    @FXML
    TableColumn keyCol;
    @FXML
    TableColumn aCol;
    @FXML
    TableColumn bCol;
    @FXML
    TableColumn cCol;

</pre>

<p>

感谢所有回复的人,即使您删除了回复。他们帮助我走上了正确的轨道,我刚刚解决了这个问题。

对于通过本文修复自己的代码的任何人来说,问题是:

  • setupTable() 应该是 initialize()
  • 初始化设置为私有
  • 控制器 class 与应用程序相同 class
  • 列已初始化
  • 拆分成controller和application后,不小心把tableView重命名为controllerclass名称

initialize()setupTable() 总的来说是最大的问题,感谢@mrmcwolf 帮助我调查这个问题。将此设置为私有不允许 FXML 正确注入。这两个问题是我的代码无法正常工作的主要原因。如果您遇到问题,请尝试检查这些。

控制器 class 更像是一种不好的做法,但它有助于提高代码的可读性,并让我看到我的问题出在哪里

初始化列是另一个不好的做法。测试表明即使没有这个它也能工作,但这是不必要的并且使代码混乱

最后一个很愚蠢,但它确实发生了。这表现为 NullPointerException,因为没有要注入的表视图

下面是最终的源代码,如果你想自己构建它来玩和开始工作的话

主要class:

import javafx.application.Application;

public class Main {
    public static void main(String[] args) {
        Application.launch(GUI.class, args);
    }
}

图形界面 class:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;

public class GUI extends Application {
    //Sets up window
    @Override
    public void start(Stage primaryStage)throws IOException {
        primaryStage.setTitle("Table View Test");
        Parent root = FXMLLoader.load(getClass().getResource("tvTest.fxml"));
        Scene scene = new Scene(root);
        primaryStage.setResizable(true);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

测试控制器class:

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;

public class testController {

    //Variable initialization
    @FXML
    TableView<TestObj> tvTest;
    @FXML
    TableColumn<TestObj, Integer> keyCol;
    @FXML
    TableColumn<TestObj, String> aCol;
    @FXML
    TableColumn<TestObj, String> bCol;
    @FXML
    TableColumn<TestObj, String> cCol;

    ObservableList<TestObj> testObjs= FXCollections.observableArrayList();

    //Creates cell factories and loads up lists
    public void initialize(){
        //Cell value factory creation
        keyCol.setCellValueFactory(new PropertyValueFactory<TestObj,Integer>("key"));
        aCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("A"));
        bCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("B"));
        cCol.setCellValueFactory(new PropertyValueFactory<TestObj,String>("C"));

        //Test objects
        testObjs.add(new TestObj(1,"A1","B1","C1"));
        testObjs.add(new TestObj(2,"A2","B2","C2"));
        testObjs.add(new TestObj(3,"A3","B3","C3"));

        tvTest.setItems(testObjs);
    }
}

测试对象 class:

public class TestObj {
    int key;
    String a;
    String b;
    String c;

    public int getKey() {
        return key;
    }

    public void setKey(int key) {
        this.key = key;
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    TestObj(int key, String A, String B, String C){
        this.key=key;
        this.a=A;
        this.b=B;
        this.c=C;
    }
}

tvTest.fxml:

<?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="testController">
   <children>
      <TableView layoutX="14.0" layoutY="14.0" prefHeight="372.0" prefWidth="570.0" fx:id="tvTest">
        <columns>
          <TableColumn fx:id="keyCol" prefWidth="72.0" text="Key" />
          <TableColumn fx:id="aCol" prefWidth="166.0" text="A" />
            <TableColumn fx:id="bCol" prefWidth="166.0" text="B" />
            <TableColumn fx:id="cCol" prefWidth="166.0" text="C" />
        </columns>
      </TableView>
   </children>
</AnchorPane>

希望这对偶然发现它的人有所帮助