Как загрузить данные в таблицу из базы данных, используя javafx - PullRequest
0 голосов
/ 05 февраля 2020

Я новичок в javafx. Я просто использую способ java jtable, как загрузка данных, но я не могу загрузить данные в таблицу, то, что я пытался до сих пор, я прикрепил ниже. Как загрузить данные в таблицу

@FXML
private TableColumn<?, ?> table1;

public void table_load()
{
    int c;

    try {
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost/addressbook", "root","");
        pst = con.prepareStatement("select * from records");
        ResultSet rs = pst.executeQuery();
        ResultSetMetaData rd = rs.getMetaData();
        c = rd.getColumnCount();
        df = (DefaultTableModel)table1.getCellData(0);
        df.setRowCount(0);

        while (rs.next())
        {
            Vector v = new Vector();
            for (int i=1; i<=c; i++)
            {
                v.add(rs.getString("id"));
                v.add(rs.getString("name"));
                v.add(rs.getString("address"));
                v.add(rs.getString("phone"));
            }
            df.addRow(v);
        }
    } catch (SQLException ex) {

    } catch (ClassNotFoundException ex) {
       Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

В отличие от Swing, JavaFX TableView не использует отдельную модель. Вместо этого данные являются моделью. Вы передаете эти данные в TableView, используя метод setItems TableView.

Это означает, что вам нужно создать класс для хранения ваших данных. Поскольку ваша таблица называется records, я бы назвал класс данных Record.

Если вы посмотрите документацию классов JavaFX, вы должны заметить шаблон. Свойства бина являются инкапсулированными атрибутами, которые состоят из трех методов:

  • Метод чтения, который всегда начинается с get, за которым следует заглавная буква. ¹
  • Метод записи, который всегда начинается с set, за которым следует заглавная буква .²
  • Метод свойства, имя которого всегда заканчивается на Property.

Например, рассмотрим класс javafx.stage.Window . Он имеет свойство «непрозрачность», которое представлено следующими методами:

Ваш класс данных должен следовать той же схеме:

public class Record {
    private final StringProperty id;
    private final StringProperty name;
    private final StringProperty address;
    private final StringProperty phone;

    public Record() {
        id = new SimpleStringProperty(this, "id");
        name = new SimpleStringProperty(this, "name");
        address = new SimpleStringProperty(this, "address");
        phone = new SimpleStringProperty(this, "phone");
    }

    public StringProperty idProperty() { return id; }
    public String getId() { return id.get(); }
    public void setId(String newId) { id.set(newId); }

    public StringProperty nameProperty() { return name; }
    public String getName() { return name.get(); }
    public void setName(String newName) { name.set(newName); }

    public StringProperty addressProperty() { return address; }
    public String getAddress() { return address.get(); }
    public void setAddress(String newAddress) { address.set(newAddress); }

    public StringProperty phoneProperty() { return phone; }
    public String getPhone() { return phone.get(); }
    public void setPhone(String newPhone) { phone.set(newPhone); }

    @Override
    public String toString() {
        return String.format("%s[id=%s, name=%s]",
            getClass().getName(), getId(), getName());
    }
}

Создать эти объекты просто :

@FXML
private TableView<Record> table;

@FXML
private TableColumn<Record, String> idColumn;

@FXML
private TableColumn<Record, String> nameColumn;

@FXML
private TableColumn<Record, String> addressColumn;

@FXML
private TableColumn<Record, String> phoneColumn;

// ... 

    ObservableList<Record> records = FXCollections.observableArrayList();

    try (ResultSet rs = pst.executeQuery()) {
        while (rs.next())
        {
            Record record = new Record();
            record.setId(rs.getString("id"));
            record.setName(rs.getString("name"));
            record.setAddress(rs.getString("address"));
            record.setPhone(rs.getString("phone"));

            records.add(record);
        }
    }

    table.setItems(records);

Вместо табличной модели вы должны вместо каждого столбца таблицы указывать, какие данные должны отображаться:

idColumn.setCellValueFactory(f -> f.getValue().idProperty());
nameColumn.setCellValueFactory(f -> f.getValue().nameProperty());
addressColumn.setCellValueFactory(f -> f.getValue().addressProperty());
phoneColumn.setCellValueFactory(f -> f.getValue().phoneProperty());

¹ Чтение методов, тип возвращаемых данных которых является примитивным логическим значением может использовать is вместо get.
² Методы записи не нужны для свойств только для чтения.

1 голос
/ 05 февраля 2020

Обычно вы не добавляете данные непосредственно в TableColumn. Обычным способом было бы иметь объекты типа, который вы можете добавить. Давайте предположим, что ваш набор результатов будет содержать объекты типа Customer, и вы сможете извлечь один или несколько пользовательских объектов из вашего набора результатов. Тогда вам лучше поработать со следующим (необходимо определить в файле fxml:

  • Таблица вышестоящих элементов, например TableView <Customer> customerView
  • , например, количество столбцов таблицы:
    • TableColumn<Customer, String> idColumn
    • TableColumn<Customer, String> nameColumn
    • TableColumn<Customer, String> addressColumn
    • TableColumn<Customer, String> phoneColumn

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

  • idColumn.setCellValueFactory(new PropertyValueFactory<>("[ATTRIBUTE NAME IN CUSTOMER CLASS]"));

как

  • idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));

Последний шаг должен заполнить табличное представление данными:

customerView.setItems(observableCustomers);

, где observableCustomers - список типов ObservableList<Customer>. javafx.collections.FXCollections поможет вам создать соответствующий объект.

Это должно быть похоже на это:

@FXML
TableView <Customer> customerView;

@FXML
TableColumn<Customer, String> idColumn;
@FXML
TableColumn<Customer, String> nameColumn;
@FXML
TableColumn<Customer, String> addressColumn;
@FXML
TableColumn<Customer, String> phoneColumn;

ObservableList<Customer> observableCustomers;

// init method or constructor, whatever suits your needs
private void initTable() {

    observableCustomers = FXCollections.observableArrayList();
    idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
    nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
    addressColumn.setCellValueFactory(new PropertyValueFactory<>("address"));
    phoneColumn.setCellValueFactory(new PropertyValueFactory<>("phone"));
}

public void table_load()
{

    try {
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost/addressbook", "root","");
        pst = con.prepareStatement("select * from records");
        ResultSet rs = pst.executeQuery();
        ResultSetMetaData rd = rs.getMetaData();

        // CAST/TRANSFORMATION TO BE DONE BY YOU
        List<Customer> customerList = ((List<Customer>) rs.toList());

        // only if necessary
        observableCustomers.clear();
        // add customers
        observableCustomers.addAll(customerList);

    } catch (SQLException ex) {

    } catch (ClassNotFoundException ex) {
        Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
    }

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