Динамическое назначение типов столбцов для TableView во время выполнения - PullRequest
0 голосов
/ 24 марта 2019

Я пишу программу, использующую JavaFX, чтобы сделать простой способ отправки произвольных операторов SQL в произвольные базы данных.Думайте об этом как о версии ScriptRunner с графическим интерфейсом.Запросы выполняются в фоновом потоке.

Я не знаю количество и тип столбцов, которые мне понадобятся во время компиляции.На самом деле, я не буду знать, что будет в ResultSet, пока не получу ResultSet обратно из базы данных.В этот момент я хочу обработать данные соответствующим образом для их типа данных JDBC.Например, я назначаю Comparator каждому столбцу, чтобы пользователи могли сортировать отображаемые данные по любому столбцу, и он будет вести себя должным образом.

Я нашел критический код в StackOverflow (хотя с тех пор я потерял ссылку наэтот пост).Я ОЧЕНЬ благодарен за этот пост.Код работает, но он не совсем удовлетворителен, прежде всего потому, что он использует «необработанные типы» и снимает флажок приведения.С тех пор я сделал несколько изменений, пытаясь улучшить их, но, возможно, это привело к обратным результатам.Я был бы очень признателен, если бы кто-нибудь помог мне распутать это.Конечно, есть более элегантный способ.Если это так хорошо, как получится, это тоже будет хорошей информацией.

Кстати, весь мой проект в файлах .java: я не использую FXML или .css.

main () в этом примере кода просто вызывает код в processRequest ().

В основном я хочу узнать, как лучше всего объявлять и манипулировать переменными: «data», «columns» и «tvResult»,И если есть какие-то особые соображения.tvResult: что должно отображаться в графическом интерфейсе.данные: данные, которые возвращаются в ResultSet (dah).
столбцы: метаданные о столбцах, которые получены из ResultSetMetaData.

То, что у меня есть:

ObservableList<ObservableList<?>> data = FXCollections.observableArrayList();
ArrayList<TableColumn<?,?>> columns = new ArrayList<>();
private TableView<ObservableList<?>> tvResult;

код - это то, что я собрал из различных учебных пособий, ответов StackOverflow, книг, блогов и т. д. (обратите внимание на «vogella.com» в данных).

Данные, которые находятся в таблице:

SQL: «выбрать * из example.comments».

Вывод: 1 ||Ларс ||myemail@gmail.com ||http: \ www.vogella.com ||2009-09-14 ||Резюме ||Мой первый комментарий ||2 ||Стивен ||youremail@gmail.com ||http: \ www.google.com ||2018-11-20 ||Ваше резюме идет здесь ||Ваш первый комментарий ||

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

Это все еще немного дольше, чем это строго необходимо, но это потому, что я хотелсделать как можно меньше изменений в processRequest ().Он получает SQL в объекте String и Connection и манипулирует тремя упомянутыми переменными.

public class MySQLAccess extends Application {
    ObservableList<ObservableList<?>> data = FXCollections.observableArrayList();
    ArrayList<TableColumn<?,?>> columns = new ArrayList<>();
    private TableView<ObservableList<?>> tvResult;
    static MySQLAccess pgm;

/* ********************************************************************** **
**  main()
** ********************************************************************** */
    public static void main(String[] args) {
        pgm = new MySQLAccess();
        pgm.tvResult = new TableView<>();
        Connection connection = null;
        MysqlDataSource mySqlDataSource = new MysqlDataSource();
        mySqlDataSource.setUrl("jdbc:mysql://" + "localhost" + ":3306/" + "StackOverflow");
        mySqlDataSource.setUser("root");
        mySqlDataSource.setPassword("");
        DataSource dataSource = mySqlDataSource;
        try {
            connection = dataSource.getConnection();
            pgm.processRequest("select * from example.comments", connection);
        } catch (Exception e) {
            System.out.println("error creating connection");
        }
        pgm.tvResult.getColumns().clear();
        for (int j = 0; j < pgm.columns.size(); j++) {
            TableColumn<?, ?> col = pgm.columns.get(j);
            pgm.tvResult.getColumns().add((TableColumn<ObservableList<?>, ?>) col);
        }
        pgm.tvResult.setItems(pgm.data);

        ObservableList<TableColumn<ObservableList<?>,?>> columns = pgm.tvResult.getColumns();
        for (Object row : pgm.tvResult.getItems()) {
            for (TableColumn column : columns) {
                System.out.print(column.getCellObservableValue(row).getValue().toString() + " || ");
            }
            System.out.println();
        }
    }

/* ********************************************************************** **
**  processRequest()
** ********************************************************************** */
    private void processRequest(String sql, Connection connection) throws SQLException {
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(sql);
        ResultSetMetaData rm = rs.getMetaData();

//  Process Columns (assign the proper type to each)
        int colCnt = rm.getColumnCount();
        pgm.columns.clear();
        for (int i = 0; i < colCnt; i++) {
            final int k = i;
            String columnName = rm.getColumnName(i + 1);
            int columnType = rm.getColumnType(i + 1);
            TableColumn col = new TableColumn(columnName);
            col.setComparator(getComparator(columnType));
            col.setCellValueFactory(
                    new Callback<CellDataFeatures<ObservableList<?>, String>, ObservableValue<String>>() {
                        @Override
                        public ObservableValue<String> call(
                                CellDataFeatures<ObservableList<?>, String> param) {
                            return new SimpleStringProperty(
                                    param.getValue().get(k).toString());
                        }
                    });
            pgm.columns.add(col);
        }

//  Process Rows
        pgm.data.clear();
        while (rs.next()) {
            ObservableList<String> row = FXCollections.observableArrayList();
            row.clear();
            for (int i = 0; i < colCnt; i++) {
                String str;
                String hold = rs.getString(i + 1);
                if ((hold == null) || (hold.isEmpty())) {
                    str = "";
                } else {
                    str = String.valueOf(rs.getString(i + 1));
                }
                row.add(str);
            }
            pgm.data.add(row);
        }
    }

/* ********************************************************************** **
** getComparator()
** ********************************************************************** */
            private Comparator<?> getComparator(int columnType) {
                Comparator<?> comparator = null;
                String objectType = DataTypeMapping.javaClass(columnType);

                if (objectType.equals("String")) {
                    comparator = ((str_1, str_2) -> {
                        String int_1 = (String) str_1;
                        String int_2 = (String) str_2;
                        return int_1.compareTo(int_2);
                    });
                } else if (objectType.equals("Integer")) {
                    comparator = ((str_1, str_2) -> {
                        Integer int_1 = Integer.parseInt((String) str_1);
                        Integer int_2 = Integer.parseInt((String) str_2);
                        return int_1.compareTo(int_2);
                    });
                } else if (objectType.equals("Date")) {
                    comparator = ((str_1, str_2) -> {
                        Long date_1 = Long.parseLong((String) str_1);
                        Long date_2 = Long.parseLong((String) str_2);
                        return date_1.compareTo(date_2);
                    });
//
//                  .
//                  .
//                  .
//
                } else {
                    comparator = null;
                }
                return comparator;
            }

/* ********************************************************************** **
**  start()
** *********************************************************************** */
    @Override
    public void start(Stage arg0) throws Exception {
    }

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...