Я только начал работать с 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>
Заранее большое спасибо.