You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX TableView单元格无内容:Cell Factory与Value Factory加载异常排查

JavaFX TableView 单元格无内容显示

我正在开发一个从数据库加载文本到TableView的项目,已经精简出最小复现示例。核心问题是TableView的单元格未显示任何内容,无法确定是TableCell还是TableColumn导致的问题。我查过相关解决方案和官方文档,但都没解决。


代码文件

HelloController.java

public class HelloController implements Initializable {

    @FXML private TableView<myModel> tableView;
    @FXML private Button insertData;

    TableColumn<myModel, String> firstNameCol = new TableColumn<>("FirstName");
    TableColumn<myModel, String> lastNameCol = new TableColumn<>("LastName");
    TableColumn<myModel, Button> buttonCol = new TableColumn<>("");

    static ObservableList<myModel> creds = FXCollections.observableArrayList();

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        try {
            myModel.createTable(connectToDB(), "mytable");
        }
        catch (SQLException | ClassNotFoundException e) {
            System.out.println("Table Exists");
            try{
                myModel.showTable(connectToDB(), "mytable");
            }
            catch(SQLException | ClassNotFoundException ex) {
                ex.printStackTrace();
            }
            //e.printStackTrace();
        }

        tableView.setItems(creds);

        insertData.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                try {
                    myModel.insertTable(connectToDB(), "Hrthik", "Bhowmik");
                } catch (SQLException | ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        });

        tableView.getColumns().addAll(firstNameCol, lastNameCol, buttonCol);

    }

    public void loadDBToTable() {

        creds.add(new myModel(myModel.getFirstName(), myModel.getLastName()));

        System.out.println(myModel.getFirstName() +"\t"+ myModel.getLastName());

//        Tried but not working
//        firstNameCol.setCellValueFactory(data -> myModel.firstNameProperty());
//        lastNameCol.setCellValueFactory(data -> myModel.lastNameProperty());
        firstNameCol.setCellValueFactory(new PropertyValueFactory<>(myModel.firstNameProperty().getName()));
        lastNameCol.setCellValueFactory(new PropertyValueFactory<>(myModel.lastNameProperty().getName()));
        buttonCol.setCellFactory(new Callback<TableColumn<myModel, Button>, TableCell<myModel, Button>>() {
            @Override
            public TableCell<myModel, Button> call(TableColumn<myModel, Button> myModelStringTableColumn) {
                final TableCell<myModel, Button> cell = new TableCell<myModel, Button>() {
                    private final Button button = new Button("Remove");
                    {
                        button.setOnAction((ActionEvent event) -> {
                            System.out.println("Remove this row from TableView and Database");
                        });
                    }

                    @Override
                    public void updateItem(Button item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(button);
                        }
                    }
                };
                return cell;
            }
        });
    }

    private Connection connectToDB() throws SQLException, ClassNotFoundException {
        Class.forName("org.sqlite.JDBC");
        Connection con = DriverManager.getConnection("jdbc:sqlite:MY_DATA.db");
        System.out.println("Database connection success");
        return con;
    }
}

myModel.java

public class myModel {

    static HelloController controller = new HelloController();

    private static StringProperty firstName;
    private static StringProperty lastName;

    public myModel(String firstName, String lastName) {
        setFirstName(firstName);
        setLastName(lastName);
    }

    public static StringProperty firstNameProperty() {
        if (firstName == null) firstName = new SimpleStringProperty("firstname");
        return firstName;
    }
    public static String getFirstName() {
        return firstNameProperty().get();
    }
    public static void setFirstName(String firstName) {
        firstNameProperty().set(firstName);
    }

    public static StringProperty lastNameProperty() {
        if (lastName == null) lastName = new SimpleStringProperty("lastname");
        return myModel.lastName;
    }
    public static String getLastName() {
        return lastNameProperty().get();
    }
    public static void setLastName(String lastName) {
        lastNameProperty().set(lastName);
    }

    //Sql part
    public static void createTable(Connection con, String tableName) throws SQLException {
        PreparedStatement command = con.prepareStatement(
                "CREATE TABLE "+ tableName + "( FirstName varchar(50), LastName varchar(50));");
        command.execute();
        command.close();
        System.out.println("Table created successfully");
    }

    public static void insertTable(Connection con, String firstName, String lastName) throws SQLException {
        PreparedStatement insert = con.prepareStatement("INSERT INTO mytable (FirstName, LastName) VALUES (?,?);");
        insert.setString(1, firstName);
        insert.setString(2, lastName);
        insert.execute();
        insert.close();
        System.out.println("Insertion complete");
    }

    public static void showTable(Connection con, String tableName) throws SQLException {
        Statement cmd = con.createStatement();
        ResultSet show = cmd.executeQuery("SELECT * FROM "+tableName+";");
        while(show.next()) {
            System.out.println(show.getString("FirstName") +"\t"+ show.getString("LastName"));

            myModel.setFirstName(show.getString("FirstName"));
            myModel.setLastName(show.getString("LastName"));

            controller.loadDBToTable();
        }
        cmd.close();
    }
}

hello-view.fxml

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="250.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.minumal_.HelloController">
   <children>
      <TableView fx:id="tableView" layoutX="3.0" layoutY="7.0" prefHeight="240.0" prefWidth="294.0" />
      <Button fx:id="insertData" layoutX="309.0" layoutY="27.0" mnemonicParsing="false" text="Insert" />
   </children>
</AnchorPane>

当前效果截图

当前效果截图


内容的提问来源于stack exchange,提问作者Hrithik_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:18:11