在没有中间类的情况下将数据插入JavaFX TableView

时间:2021-12-18 17:04:21

I'm newbie Java programmer. I would like to insert ResultSet data to JavaFX TableView, but i wouldn't use intermediate class. Can i insert ResultSet rows to TableView rows as objects?

我是新手Java程序员。我想将ResultSet数据插入JavaFX TableView,但我不会使用中间类。我可以将ResultSet行作为对象插入TableView行吗?

Here is my code with using intermediate class Unit

这是我使用中间类Unit的代码

 public static ObservableList<Unit> getUnits() {

    final ObservableList<Unit> data = FXCollections.observableArrayList();
    if (openConnection()) {
        try {
            rs = st.executeQuery("SELECT * FROM units");
            while (rs.next()) {

                data.add(new Unit(rs.getString("id_unit"),
                        rs.getString("short_name"),
                        rs.getString("name")));
            }
        } catch (Exception ex) {
            Logger.getLogger(SQLConnect.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    closeConnection();
    return data;
}

Controller

调节器

idUnit.setCellValueFactory(new PropertyValueFactory<Unit, String>("idUnit"));
shortNameUnit.setCellValueFactory(new PropertyValueFactory<Unit, String>("shortName"));
nameUnit.setCellValueFactory(new PropertyValueFactory<Unit, String>("name"));

unitsTableView.setItems(SQLConnect.getUnits());

2 个解决方案

#1


4  

You need something to hold the data; that something (which you call the "intermediate class") is going to be the data type for your TableView.

你需要一些东西来保存数据;某些东西(你称之为“中间类”)将成为TableView的数据类型。

It doesn't necessarily have to be a class you create, but if you just use something general, your code is going to be much harder to understand. For example, you could just use a List<String> to hold each row:

它不一定必须是你创建的类,但如果你只是使用一般的东西,你的代码将更难理解。例如,您可以使用List 来保存每一行:

TableView<List<String>> unitsTableView = new TableView<>();
idUnit = new TableColumn<List<String>, String>("Id");
idUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(0)) ;
    }
});
shortNameUnit = new TableColumn<List<String>, String>("Short Name");
shortNameUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(1)) ;
    }
});
nameUnit = new TableColumn<List<String>, String>("Name");
nameUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(2)) ;
    }
});

and then

接着

public static ObservableList<List<String>> getUnits() {

    final ObservableList<List<String>> data = FXCollections.observableArrayList();
    if (openConnection()) {
        try {
            rs = st.executeQuery("SELECT * FROM units");
            while (rs.next()) {
                List<String> unit = new ArrayList<>();
                unit.add(rs.getString("id_unit"));
                unit.add(rs.getString("short_name"));
                unit.add(rs.getString("name"));
                data.add(unit);
            }
        } catch (Exception ex) {
            Logger.getLogger(SQLConnect.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    closeConnection();
    return data;
}

But now your code is almost completely devoid of the semantics of the data you are representing.

但是现在你的代码几乎完全没有你所代表的数据的语义。

Note that you can't use a ResultSet directly, for a number of reasons. One is that the data in the TableView are represented by a random-access list. While you can think of ResultSet as representing a list of rows of data, it doesn't implement the List interface, and doesn't have any random-access functionality (there's no guaranteed way to get row number 5, etc.). Another reason is that a ResultSet requires (or at least may require, depending on the JDBC driver implementation) a live database resource. So you would risk locking your database table for the entire time the TableView is in scope.

请注意,由于多种原因,您无法直接使用ResultSet。一个是TableView中的数据由随机访问列表表示。虽然您可以将ResultSet视为表示数​​据行列表,但它不实现List接口,并且没有任何随机访问功能(没有保证获得第5行的方法等)。另一个原因是ResultSet需要(或至少可能需要,具体取决于JDBC驱动程序实现)实时数据库资源。因此,您可能会在TableView在范围内的整个时间内锁定数据库表。

Why do you want to avoid creating the data representation class?

为什么要避免创建数据表示类?

#2


0  

A workaround could be to create your custom component that extends TableView and then do the magic inside your own CustomTableView class

解决方法可能是创建扩展TableView的自定义组件,然后在您自己的CustomTableView类中执行魔术

#1


4  

You need something to hold the data; that something (which you call the "intermediate class") is going to be the data type for your TableView.

你需要一些东西来保存数据;某些东西(你称之为“中间类”)将成为TableView的数据类型。

It doesn't necessarily have to be a class you create, but if you just use something general, your code is going to be much harder to understand. For example, you could just use a List<String> to hold each row:

它不一定必须是你创建的类,但如果你只是使用一般的东西,你的代码将更难理解。例如,您可以使用List 来保存每一行:

TableView<List<String>> unitsTableView = new TableView<>();
idUnit = new TableColumn<List<String>, String>("Id");
idUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(0)) ;
    }
});
shortNameUnit = new TableColumn<List<String>, String>("Short Name");
shortNameUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(1)) ;
    }
});
nameUnit = new TableColumn<List<String>, String>("Name");
nameUnit.setCellValueFactory(new Callback<CellDataFeatures<List<String>, String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<List<String>, String>> data) {
        return new ReadOnlyStringWrapper(data.getValue().get(2)) ;
    }
});

and then

接着

public static ObservableList<List<String>> getUnits() {

    final ObservableList<List<String>> data = FXCollections.observableArrayList();
    if (openConnection()) {
        try {
            rs = st.executeQuery("SELECT * FROM units");
            while (rs.next()) {
                List<String> unit = new ArrayList<>();
                unit.add(rs.getString("id_unit"));
                unit.add(rs.getString("short_name"));
                unit.add(rs.getString("name"));
                data.add(unit);
            }
        } catch (Exception ex) {
            Logger.getLogger(SQLConnect.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    closeConnection();
    return data;
}

But now your code is almost completely devoid of the semantics of the data you are representing.

但是现在你的代码几乎完全没有你所代表的数据的语义。

Note that you can't use a ResultSet directly, for a number of reasons. One is that the data in the TableView are represented by a random-access list. While you can think of ResultSet as representing a list of rows of data, it doesn't implement the List interface, and doesn't have any random-access functionality (there's no guaranteed way to get row number 5, etc.). Another reason is that a ResultSet requires (or at least may require, depending on the JDBC driver implementation) a live database resource. So you would risk locking your database table for the entire time the TableView is in scope.

请注意,由于多种原因,您无法直接使用ResultSet。一个是TableView中的数据由随机访问列表表示。虽然您可以将ResultSet视为表示数​​据行列表,但它不实现List接口,并且没有任何随机访问功能(没有保证获得第5行的方法等)。另一个原因是ResultSet需要(或至少可能需要,具体取决于JDBC驱动程序实现)实时数据库资源。因此,您可能会在TableView在范围内的整个时间内锁定数据库表。

Why do you want to avoid creating the data representation class?

为什么要避免创建数据表示类?

#2


0  

A workaround could be to create your custom component that extends TableView and then do the magic inside your own CustomTableView class

解决方法可能是创建扩展TableView的自定义组件,然后在您自己的CustomTableView类中执行魔术