【问题标题】:JavaFX TableView with different cell types and unknown size具有不同单元类型和未知大小的 JavaFX TableView
【发布时间】:2017-07-06 18:15:27
【问题描述】:

我正在尝试从包含字符串和双精度数以及未知数量的列的各种 csv 文件创建一个 tableview。

通过一些小的改动,我可以使用这里的答案来创建动态表格视图:https://community.oracle.com/thread/2474328

除此之外,使用这里的教程,我能够创建一个包含字符串和按列双打的表格视图: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm

但是,由于我不知道有多少列,我无法创建一个类来定义我拥有的数据,而且我需要能够基于双精度和字符串进行排序,所以我不能使用第一个使用的解决方案一个 StringProperty 的 ObservableList 来定义数据。有没有人有这方面的经验或对我可以采取的路线有建议?谢谢

【问题讨论】:

    标签: java javafx-8


    【解决方案1】:

    这里唯一真正的策略是将所有数据读取为Strings,然后检查每一列中的数据以确定类型。

    然后你可以根据检测到的类型动态创建列。

    对于表的items,使用List<Object>作为每一行的表示,然后使用检测到的类型将正确类型的对象放入该行的每个槽中。

    这是一个简单的例子:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Pattern;
    
    import javafx.application.Application;
    import javafx.beans.property.SimpleDoubleProperty;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.scene.Scene;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.stage.Stage;
    
    public class DynamicTableWithTypes extends Application {
    
        private final Pattern intPattern = Pattern.compile("-?[0-9]+");
        // this could probably be improved: demo purposes only
        private final Pattern doublePattern = Pattern.compile("-?(([0-9]+)|([0-9]*\\.[0-9]+))");
    
        @Override
        public void start(Stage primaryStage) {
            TableView<List<Object>> table = new TableView<>();
            String[][] rawData = generateTestData();
            int numCols = computeMaxRowLength(rawData);
    
            Class<?>[] types = new Class<?>[numCols];
    
            for (int columnIndex = 0 ; columnIndex < numCols ; columnIndex++) {
                String[] column = extractColumn(rawData, columnIndex);
                types[columnIndex] = deduceColumnType(column);
                table.getColumns().add(createColumn(types[columnIndex], columnIndex));
            }
    
            for (int rowIndex = 0 ; rowIndex < rawData.length ; rowIndex++) {
                List<Object> row = new ArrayList<>();
                for (int columnIndex = 0 ; columnIndex < numCols ; columnIndex++) {
                    row.add(getDataAsType(rawData[rowIndex], types[columnIndex], columnIndex));
                }
                table.getItems().add(row);
            }
    
            Scene scene = new Scene(table, 600, 600);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        private Object getDataAsType(String[] row, Class<?> type, int columnIndex) {
            if (type == Integer.class) {
                if (columnIndex < row.length) {
                    return Integer.valueOf(row[columnIndex]);
                } else {
                    return new Integer(0);
                }
            } else if (type == Double.class) {
                if (columnIndex < row.length) {
                    return Double.valueOf(row[columnIndex]);
                } else {
                    return new Double(0.0);
                }
            } else {
                if (columnIndex < row.length) {
                    return row[columnIndex];
                } else {
                    return "" ;
                }
            }
        }
    
        private TableColumn<List<Object>, ?> createColumn(Class<?> type, int index) {
            String text = "Column "+(index+1);
            if (type==Integer.class) {
                TableColumn<List<Object>, Number> col = new TableColumn<>(text);
                col.setCellValueFactory(data -> new SimpleIntegerProperty((Integer)data.getValue().get(index)));
                return col ;
            } else if (type == Double.class) {
                TableColumn<List<Object>, Number> col = new TableColumn<>(text);
                col.setCellValueFactory(data -> new SimpleDoubleProperty((Double)data.getValue().get(index)));
                return col ;            
            } else {
                TableColumn<List<Object>, String> col = new TableColumn<>(text);
                col.setCellValueFactory(data -> new SimpleStringProperty(data.getValue().get(index).toString()));
                return col ;
            }
        }
    
        private Class<?> deduceColumnType(String[] column) {
            boolean allInts = true ;
            boolean allDoubles = true ;
            for (int i = 0 ; i < column.length ; i++) {
                allInts = allInts && intPattern.matcher(column[i]).matches() ;
                allDoubles = allDoubles && doublePattern.matcher(column[i]).matches() ;
            }
            if (allInts) {
                return Integer.class ;
            }
            if (allDoubles) {
                return Double.class ;
            }
            return String.class ;
        }
    
        private int computeMaxRowLength(Object[][] array) {
            int maxLength = Integer.MIN_VALUE ;
            for (int i = 0 ; i < array.length ; i++) {
                if (array[i].length > maxLength) {
                    maxLength = array[i].length ;
                }
            }
            return maxLength ;
        }
    
        private String[] extractColumn(String[][] data, int columnIndex) {
            String[] column = new String[data.length];
            for (int i = 0 ; i < data.length ; i++) {
                if (columnIndex < data[i].length) {
                    column[i]=data[i][columnIndex];
                } else {
                    column[i]="";
                }
            }
            return column ;
        }
    
        private String[][] generateTestData() {
    
            // in real life, read from CSV file/database, etc...
    
            return new String[][] {
                {"A1", "B2", "10", "-5.3"},
                {"A2", "B1", "15", "12.6"},
                {"A3", "B3", "5", "10.2"}
            };
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    如您所见,这是正确排序的:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      相关资源
      最近更新 更多