JavaFX + Hibernate: динамическое изменение привязки Model-GUI - PullRequest
0 голосов
/ 23 сентября 2018

Я только начал работать с Hibernate и JavaFX.В моем тестовом приложении пользователь может ввести контактные данные Person (имя, адрес, улица, почтовый индекс, город) и сохранить их в базе данных.TableView под TextFields должен отображать существующие данные:

Снимок экрана тестовой программы

В настоящее время я застрял при подключении полей ввода текста к классу модели.Само сопоставление с объектами StringProperty и IntegerProperty JavaFX работает, но я думаю, что делаю это неправильно.

После сохранения объекта Person в базе данных я хотел бы очистить поля ввода, чтобы пользователь мог создать новый Person.Чтобы сделать это, я должен удалить все отображения Model-GUI, создать новый объект и затем переназначить все.Кроме того, если пользователь выбирает одну из существующих записей в табличном представлении, я хотел бы заполнить поля ввода выбранным объектом, чтобы пользователь мог обновить запись.Это также потребует повторного выполнения всех сопоставлений свойств.Это звучит неправильно, поэтому я думаю, что должно быть лучшее решение.

Я думал о создании объекта Person, только если пользователь нажимает кнопку сохранения и затем выполняет все сопоставления StringProperty, но это такжемного накладных расходов.Я мог бы также использовать обычные строки и пропустить Property-классы тогда.

У вас есть какие-либо предложения или ресурсы для меня?

Это класс контроллера:

package test.gui;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.util.converter.NumberStringConverter;
import org.hibernate.Session;
import test.models.Person;

import javax.persistence.TypedQuery;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

import static test.Database.getFactory;

public class MainWindowController implements Initializable {

    @FXML
    private TextField firstName;

    @FXML
    private TextField lastName;

    @FXML
    private TextField street;

    @FXML
    private TextField zip;

    @FXML
    private TextField city;

    @FXML
    private TableView<Person> tableView;

    @FXML
    private TableColumn<Person, String> tblFirstName;

    @FXML
    private TableColumn<Person, String> tblLastName;

    @FXML
    private TableColumn<Person, String> tblStreet;

    @FXML
    private TableColumn<Person, Integer> tblZip;

    @FXML
    private TableColumn<Person, String> tblCity;

    private Person currentPerson = null;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        // Map table columns to Person model
        tblFirstName.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
        tblLastName.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
        tblStreet.setCellValueFactory(cellData -> cellData.getValue().streetProperty());
        tblZip.setCellValueFactory(cellData -> cellData.getValue().zipProperty().asObject());
        tblCity.setCellValueFactory(cellData -> cellData.getValue().cityProperty());

        // Read values from database to TableView
        Session s = getFactory().openSession();
        TypedQuery<Person> query = s.createQuery("from Person", Person.class);
        List<Person> persons = query.getResultList();
        s.close();

        tableView.getItems().addAll(persons);

        // Bind TextFields to Model
        currentPerson = new Person();
        firstName.textProperty().bindBidirectional(currentPerson.firstNameProperty());
        lastName.textProperty().bindBidirectional(currentPerson.lastNameProperty());
        street.textProperty().bindBidirectional(currentPerson.streetProperty());
        zip.textProperty().bindBidirectional(currentPerson.zipProperty(), new NumberStringConverter());
        city.textProperty().bindBidirectional(currentPerson.cityProperty());


        // This does not work because apparently, newValue is read-only
        tableView.getSelectionModel().selectedItemProperty().addListener((v, oldValue, newValue) -> {
            currentPerson = newValue;
        });
    }

    public void savePerson() {
        Session s = getFactory().openSession();
        s.getTransaction().begin();
        s.persist(currentPerson);
        s.getTransaction().commit();
        s.close();
        tableView.getItems().add(currentPerson);

        // Todo: Create new, empty Person object and map it to TextFields
        // Better solution?
    }
}

Это FXML-файл:

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" spacing="5.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.gui.MainWindowController">
   <children>
      <GridPane hgap="5.0" vgap="5.0">
        <columnConstraints>
          <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label text="First Name" />
            <Label text="Last Name" GridPane.rowIndex="1" />
            <Label text="Street" GridPane.rowIndex="2" />
            <Label text="ZIP" GridPane.columnIndex="2" />
            <Label text="City" GridPane.columnIndex="2" GridPane.rowIndex="1" />
            <TextField fx:id="firstName" GridPane.columnIndex="1" />
            <TextField fx:id="lastName" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <TextField fx:id="street" GridPane.columnIndex="1" GridPane.rowIndex="2" />
            <TextField fx:id="zip" GridPane.columnIndex="3" />
            <TextField fx:id="city" GridPane.columnIndex="3" GridPane.rowIndex="1" />
            <Button fx:id="saveButton" mnemonicParsing="false" onAction="#savePerson" text="Save" GridPane.columnIndex="3" GridPane.rowIndex="2" />
         </children>
      </GridPane>
      <TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0">
        <columns>
          <TableColumn fx:id="tblFirstName" prefWidth="75.0" text="First Name" />
          <TableColumn fx:id="tblLastName" prefWidth="75.0" text="Last Name" />
            <TableColumn fx:id="tblStreet" prefWidth="75.0" text="Street" />
            <TableColumn fx:id="tblZip" prefWidth="75.0" text="Zip" />
            <TableColumn fx:id="tblCity" prefWidth="75.0" text="City" />
        </columns>
      </TableView>
   </children>
   <padding>
      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
   </padding>
</VBox>

Заранее большое спасибо.

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