JavaFX:使用泛型类型创建动态表格视图 [英] JavaFX: Create a dynamic tableview with generic types
问题描述
原因在于javafx tableview的内置排序机制将所有数字排序为字符串,因为它们的类型在填充表时被转换为字符串。例如:
值
921,200,110,1,2011,1299
将被排序为(使用整数数据类型)1,
$ b对于泛型和java来说一般都是新的,希望这里的某个人能够帮助我。
基本上:每当我从数据库读取一个值时,我需要在tableview中将值插入其实际数据类型,而不是将其转换为字符串。 解决方案
您可以使用 ResultSet.getObject(index)
来填充选项卡乐。根据JDBC规范中定义的标准映射,JDBC驱动程序将返回适当的对象类型(例如,int列将映射到 java.lang.Integer
等)。
我不特别喜欢你链接的代码:它会产生很多关于类型安全的警告,你应该注意。我会使用类似的东西(警告:未测试):
数据包装类:
public class DataResult {
private final List< String> columnNames;
private final List< List< Object>>数据;
public DataResult(List< String> columnNames,List< List< Object>> data){
this.columnNames = columnNames;
this.data = data;
}
public int getNumColumns(){
return columnNames.size();
}
public String getColumnName(int index){
return columnNames.get(index);
public int getNumRows(){
return data.size();
public Object getData(int column,int row){
return data.get(row).get(column);
}
public List< List< Object>> getData(){
返回数据;
$ / code $ / pre
$ hr
数据库访问器类:
public class DAO {
private连接conn;
$ b $ public DAO(){
//初始化连接...
}
public DataResult getAllData()throws SQLException { b
$ b列表< List< Object>> data = new ArrayList<>();
列表< String> columnNames = new ArrayList<>();
$ b $ try(
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(select * from some_table)){
int columnCount = rs.getMetaData()。getColumnCount(); (int i = 1; i< = columnCount; i ++){
columnNames.add(rs.getMetaData()。getColumnName(i))的
;
}
while(rs.next()){
List< Object> row = new ArrayList<>();
for(int i = 1; i <= columnCount; i ++){
row.add(rs.getObject(i));
}
data.add(row);
}
}
返回新的DataResult(columnNames,data);
$ / code $ / pre
$ hr
GUI代码:
TableView< List< Object>> table = new TableView<>();
DAO dao =新的DAO();
DataResult data = dao.getAllData();
for(int i = 0; i< data.getNumColumns(); i ++){
TableColumn< List< Object> ;, Object> column = new TableColumn<>(data.getColumnName(i));
int columnIndex = i;
column.setCellValueFactory(cellData - >
new SimpleObjectProperty<>(cellData.getValue()。get(columnIndex)));
table.getColumns()。add(column);
}
table.getItems()。setAll(data.getData());
使用此版本时,提供给表格的数据包含列的相应类型的对象 - 不是一定是字符串因此,例如,如果数据库列是用(SQL)类型int定义的,那么表视图列将包含 java.lang.Integer
实例,排序将是根据 Integer.compareTo(...)
(即以正确的数字顺序)的实现。
So, first of all, my code is based on the accepted answer in this thread.
I'm trying to create a tableview from a database, and this tableview should be populated dynamically based on what data the user asks for. While that's working so far, my problem is that all values gathered from the database are interpreted as strings in java, but I need their actual values.
The reason for this is that the built-in sorting mechanism of the javafx tableview sorts all numbers as strings because their type is converted to string when populating the table.
Example:
Values
921, 200, 110, 1, 2011, 1299
would be sorted as (using integer datatype) 1, 110, 200, 921, 1299, 2011
while it would be sorted as 1, 110, 1299, 200, 2011, 921 using string datatype.
I'm quite new to generics and java in general, and hope someone here might be able to help me out.
Basically: whenever I read a value from the database, I need to insert the value in the tableview with its actual datatype, rather than it being converted to string.
解决方案 This should work if you use ResultSet.getObject(index)
to populate the table. The JDBC driver will return an appropriate object type, according to standard mappings defined in the JDBC specification (e.g. an int column will map to a java.lang.Integer
, etc).
I don't particularly like the code you linked: it produces a lot of warnings about type safety, to which you should pay attention. I would use something like this (caveat: not tested):
Data wrapper class:
public class DataResult {
private final List<String> columnNames ;
private final List<List<Object>> data ;
public DataResult(List<String> columnNames, List<List<Object>> data) {
this.columnNames = columnNames ;
this.data = data ;
}
public int getNumColumns() {
return columnNames.size();
}
public String getColumnName(int index) {
return columnNames.get(index);
}
public int getNumRows() {
return data.size();
}
public Object getData(int column, int row) {
return data.get(row).get(column);
}
public List<List<Object>> getData() {
return data ;
}
}
Database accessor class:
public class DAO {
private Connection conn ;
public DAO() {
// initialize connection...
}
public DataResult getAllData() throws SQLException {
List<List<Object>> data = new ArrayList<>();
List<String> columnNames = new ArrayList<>();
try (
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from some_table")) {
int columnCount = rs.getMetaData().getColumnCount();
for (int i = 1 ; i <= columnCount ; i++) {
columnNames.add(rs.getMetaData().getColumnName(i));
}
while (rs.next()) {
List<Object> row = new ArrayList<>();
for (int i = 1 ; i <= columnCount ; i++) {
row.add(rs.getObject(i));
}
data.add(row);
}
}
return new DataResult(columnNames, data);
}
}
GUI code:
TableView<List<Object>> table = new TableView<>();
DAO dao = new DAO();
DataResult data = dao.getAllData();
for (int i = 0 ; i < data.getNumColumns() ; i++) {
TableColumn<List<Object>, Object> column = new TableColumn<>(data.getColumnName(i));
int columnIndex = i ;
column.setCellValueFactory(cellData ->
new SimpleObjectProperty<>(cellData.getValue().get(columnIndex)));
table.getColumns().add(column);
}
table.getItems().setAll(data.getData());
Using this version, the data provided to the table contains objects of the appropriate type for the columns - not necessarily strings. So, for example, if a database column is defined with (SQL) type int, then the table view column will contain java.lang.Integer
instances, and the sorting will be according to the implementation of Integer.compareTo(...)
(i.e. in proper numeric order).
这篇关于JavaFX:使用泛型类型创建动态表格视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!