JavaFX – список столбцов таблицы разного типа

Мне нужно создать таблицу с редактируемыми ячейками и столбцами разных типов.

Например, таблица с двумя строковыми столбцами, столбцом типа int и столбцом типа даты. Столбец с датой, например, должен отображать средство выбора даты. Строковый столбец должен отображать текстовое поле, а другой строковый столбец должен отображать список вариантов.

Однако столбцов в будущем может стать много, поэтому я решил создать метод, который берет тип и имя столбца из базы данных, содержащей данные, и динамически создает столбцы.

Это код.

private String tableName;
private ObservableList<TableColumn<Model, T>> cols = FXCollections.observableArrayList();

public Colonne(String tableName) {
    this.tableName = tableName;
}

public ObservableList<TableColumn<Model, T>> Apply() {
    try {
        Connection conn = Driver.connection();
        conn = DriverManager.getConnection("jdbc:mysql://"+Driver.getIP()+":"+Driver.getPort()+"/"+Driver.getDatabase()+"?autoReconnect="+Driver.getAutoReconnect()+"&useSSL="+Driver.getUseSSL()+"", 
                Driver.getUser(), Driver.getPassword());

        conn.createStatement();
        ResultSet rs = conn.getMetaData().getColumns(null, null, tableName, null);

        while(rs.next()) {
            if(!rs.getString("COLUMN_NAME").equals("NUMERO_AZIENDALE") && !rs.getString("COLUMN_NAME").equals("BOLO") && !rs.getString("COLUMN_NAME").equals("MARCHIO"))
                switch (rs.getString("TYPE_NAME")) {
                case "VARCHAR": 
                    cols.add((TableColumn<Model, T>) new TableColumn<Model, String>(rs.getString("COLUMN_NAME").replaceAll("_", " "))); 
                    break;
                case "DATE": 
                    cols.add((TableColumn<Model, T>) new TableColumn<Model, LocalDate>(rs.getString("COLUMN_NAME").replaceAll("_", " "))); 
                    break;
                case "INT":
                    cols.add((TableColumn<Model, T>) new TableColumn<Model, Number>(rs.getString("COLUMN_NAME").replaceAll("_", " "))); 
                    break;
            }
        }

        conn.close();        

    } catch (SQLException e) {
        new FxDialogs().showException("Impossibile Verificare i Dati", getClass().getSimpleName(), "2", e);
    }

    return cols;
}

Но теперь я не могу, вернее, я не знаю, как использовать два метода: setCellFactory и setCellValueFactory для того, чтобы просмотреть данные и для того, чтобы редактировать ячейки, потому что очевидно, что тип данных ячейки не определен (просто посмотрите в приведенном выше коде).

Фактически, попробовав table.getColumns().get(index).setCellValueFactory(...); метод, java не распознает тип.

Как наиболее интуитивно понятное и простое решение, которое я придумал, это использовать столбцы одного типа, например строку, и по-прежнему просматривать средство выбора даты и т. д. Возможно ли?

Есть ли лучшее решение? или мне нужно объявить какой-либо столбец?

Надеюсь, я ясно выразился, извините за мой плохой английский.


person V_Martusciello    schedule 07.11.2016    source источник


Ответы (1)


Решается таким образом

private String tableName;
private TableView<Model> table;

public Colonne(String tableName, TableView<Model> table) {
    this.tableName = tableName;
    this.table = table;
}

public void Apply() {
    try {
        Connection conn = Driver.connection();
        conn = DriverManager.getConnection("jdbc:mysql://"+Driver.getIP()+":"+Driver.getPort()+"/"+Driver.getDatabase()+"?autoReconnect="+Driver.getAutoReconnect()+"&useSSL="+Driver.getUseSSL()+"", 
                Driver.getUser(), Driver.getPassword());

        conn.createStatement();
        ResultSet rs = conn.getMetaData().getColumns(null, null, tableName, null);

        while(rs.next()) {
            if(!rs.getString("COLUMN_NAME").equals("NUMERO_AZIENDALE") && !rs.getString("COLUMN_NAME").equals("BOLO") && !rs.getString("COLUMN_NAME").equals("MARCHIO"))
                switch (rs.getString("TYPE_NAME")) {
                case "VARCHAR": 
                    TableColumn<Model, String> columnS = new TableColumn<Model, String>(rs.getString("COLUMN_NAME").replaceAll("_", " "));
                    if(!rs.getString("COLUMN_NAME").equalsIgnoreCase("STATO VISITA"))
                        columnS.setCellFactory(col -> new StringCell());
                    else
                        columnS.setCellFactory(col -> new ComboBoxCell());
                    table.getColumns().add(columnS); 
                    break;
                case "DATE": 
                    TableColumn<Model, LocalDate> columnD = new TableColumn<Model, LocalDate>(rs.getString("COLUMN_NAME").replaceAll("_", " "));
                    if(rs.getString("COLUMN_NAME").equalsIgnoreCase("DATA PREVISTA PARTO"))
                        columnD.setCellFactory(col -> new LocalDateDataPrevistaCell());
                    else 
                        columnD.setCellFactory(col -> new LocalDateCell());
                    table.getColumns().add(columnD); 
                    break;
                case "INT":
                    TableColumn<Model, Number> columnN = new TableColumn<Model, Number>(rs.getString("COLUMN_NAME").replaceAll("_", " "));
                    if(!rs.getString("COLUMN_NAME").contains("ID"))
                        columnN.setCellFactory(col -> new NumberCell());
                    table.getColumns().add(columnN);
                    break;
            }
        }

        conn.close();        

    } catch (SQLException e) {
        new FxDialogs().showException("Impossibile Trovare le Colonne", getClass().getSimpleName(), "1", e);
    }
}
person V_Martusciello    schedule 08.11.2016