咱們須要一個模型類來保存聯繫人信息到咱們的通信錄中。在模型包中 (ch.makery.address.model
) 添加一個叫 Person
的類。Person
類將會有一些變量,名字,地址和生日。將如下代碼添加到類。在代碼後,我將解釋一些 JavaFX 的細節。html
Person.javajava
package ch.makery.address.model; import java.time.LocalDate; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; /** * Model class for a Person. * * @author Marco Jakob */ public class Person { private final StringProperty firstName; private final StringProperty lastName; private final StringProperty street; private final IntegerProperty postalCode; private final StringProperty city; private final ObjectProperty<LocalDate> birthday; /** * Default constructor. */ public Person() { this(null, null); } /** * Constructor with some initial data. * * @param firstName * @param lastName */ public Person(String firstName, String lastName) { this.firstName = new SimpleStringProperty(firstName); this.lastName = new SimpleStringProperty(lastName); // Some initial dummy data, just for convenient testing. this.street = new SimpleStringProperty("some street"); this.postalCode = new SimpleIntegerProperty(1234); this.city = new SimpleStringProperty("some city"); this.birthday = new SimpleObjectProperty<LocalDate>(LocalDate.of(1999, 2, 21)); } public String getFirstName() { return firstName.get(); } public void setFirstName(String firstName) { this.firstName.set(firstName); } public StringProperty firstNameProperty() { return firstName; } public String getLastName() { return lastName.get(); } public void setLastName(String lastName) { this.lastName.set(lastName); } public StringProperty lastNameProperty() { return lastName; } public String getStreet() { return street.get(); } public void setStreet(String street) { this.street.set(street); } public StringProperty streetProperty() { return street; } public int getPostalCode() { return postalCode.get(); } public void setPostalCode(int postalCode) { this.postalCode.set(postalCode); } public IntegerProperty postalCodeProperty() { return postalCode; } public String getCity() { return city.get(); } public void setCity(String city) { this.city.set(city); } public StringProperty cityProperty() { return city; } public LocalDate getBirthday() { return birthday.get(); } public void setBirthday(LocalDate birthday) { this.birthday.set(birthday); } public ObjectProperty<LocalDate> birthdayProperty() { return birthday; } }
Properties
是很常見的. 一個 Property
容許咱們, 打個比方, 當 lastName
或其餘屬性被改變時自動收到通知, 這有助於咱們保持視圖與數據的同步,閱讀 Using JavaFX Properties and Binding 學習更多關於 Properties
的內容。birthday
, 咱們使用了 LocalDate
類型, 這在 Date and Time API for JDK 8 中是一個新的部分.咱們的應用主要管理的數據是一羣人的信息.讓咱們在 MainApp
類裏面建立一個 Person
對象的列表。稍後其餘全部的控制器類將存取 MainApp
的核心列表。api
咱們處理JavaFX的view classes須要在人員列表發生任何改變時都被通知. 這是很重要的,否則視圖就會和數據不一樣步.爲了達到這個目的,JavaFX引入了一些新的集合類.安全
在這些集合中, 咱們須要的是ObservableList
. 將如下代碼增長到MainApp
類的開頭去建立一個新的ObservableList
. 咱們也會增長一個構造器去建立一些樣本數據和一個公共的getter方法:oracle
MainApp.javaapp
// ... AFTER THE OTHER VARIABLES ... /** * The data as an observable list of Persons. */ private ObservableList<Person> personData = FXCollections.observableArrayList(); /** * Constructor */ public MainApp() { // Add some sample data personData.add(new Person("Hans", "Muster")); personData.add(new Person("Ruth", "Mueller")); personData.add(new Person("Heinz", "Kurz")); personData.add(new Person("Cornelia", "Meier")); personData.add(new Person("Werner", "Meyer")); personData.add(new Person("Lydia", "Kunz")); personData.add(new Person("Anna", "Best")); personData.add(new Person("Stefan", "Meier")); personData.add(new Person("Martin", "Mueller")); } /** * Returns the data as an observable list of Persons. * @return */ public ObservableList<Person> getPersonData() { return personData; } // ... THE REST OF THE CLASS ...
如今咱們終於要將數據加入到表格中了,咱們須要一個控制器爲了PersonOverview.fxml
,.eclipse
PersonOverviewController.java
的普通java類(咱們須要將這個類放在和PersonOverview.fxml
相同的包下, 否則SceneBuilder會找不到它 - 至少在當前的版本).@FXML
註解. 這對於fxml文件訪問私有屬性和私有方法來講是必需的. 當將一切都在fxml文件中設置好以後, 應用程序會在fxml文件被載入時自動地填充這些變量. 讓咱們添加如下的代碼:Note: 記住要使用 javafx imports, 而不是awt和swing!ide
PersonOverviewController.javapost
package ch.makery.address.view; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import ch.makery.address.MainApp; import ch.makery.address.model.Person; public class PersonOverviewController { @FXML private TableView<Person> personTable; @FXML private TableColumn<Person, String> firstNameColumn; @FXML private TableColumn<Person, String> lastNameColumn; @FXML private Label firstNameLabel; @FXML private Label lastNameLabel; @FXML private Label streetLabel; @FXML private Label postalCodeLabel; @FXML private Label cityLabel; @FXML private Label birthdayLabel; // Reference to the main application. private MainApp mainApp; /** * The constructor. * The constructor is called before the initialize() method. */ public PersonOverviewController() { } /** * Initializes the controller class. This method is automatically called * after the fxml file has been loaded. */ @FXML private void initialize() { // Initialize the person table with the two columns. firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty()); lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty()); } /** * Is called by the main application to give a reference back to itself. * * @param mainApp */ public void setMainApp(MainApp mainApp) { this.mainApp = mainApp; // Add observable list data to the table personTable.setItems(mainApp.getPersonData()); } }
可能須要解釋一下這段代碼:學習
@FXML
註解.實際上,只有在私有的狀況下才須要, 可是讓它們保持私有而且用註解標記的方式更好!initialize()
方法在fxml文件完成載入時被自動調用. 那時, 全部的FXML屬性都應已被初始化.setCellValueFactory(...)
來肯定爲特定列使用Person
對象的某個屬性. 箭頭 ->
表示咱們在使用Java 8的 Lambdas 特性. (另外一個選擇是使用 PropertyValueFactory, 但它不是類型安全的).setMainApp(...)
必須被 MainApp
類調用. 這讓咱們能夠訪問MainApp
對象並獲得Persons
的列表和其餘東西. 用如下代碼替換showPersonOverview()
方法. 它包含了新增的兩行:
MainApp.java - new showPersonOverview() method
/** * Shows the person overview inside the root layout. */ public void showPersonOverview() { try { // Load person overview. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml")); AnchorPane personOverview = (AnchorPane) loader.load(); // Set person overview into the center of root layout. rootLayout.setCenter(personOverview); // Give the controller access to the main app. PersonOverviewController controller = loader.getController(); controller.setMainApp(this); } catch (IOException e) { e.printStackTrace(); } }
咱們快要完成了! 可是有件小事被遺漏了: 至今沒有告訴 PersonOverview.fxml
使用的是哪一個控制器以及元素與控制器中的屬性的對應關係.
使用SceneBuilder 打開 PersonOverview.fxml
.
打開左邊的 Controller 組選擇PersonOverviewController
做爲 controller class.
在 Hierarchy 組選擇TableView
並選擇 Code 組將 personTable
做爲 fx:id.
對列作相同的事而且將 firstNameColumn
and lastNameColumn
分別做爲 fx:id .
對在第二列的 each label , 選擇對應的 fx:id.
重要事項: 回到eclipse而且 refresh the entire AddressApp project (F5). 這是必要的由於有時候eclipse並不知道在Scene Builder中做出的改變.
當你如今啓動了你的應用,你應該看到了相似這篇博客開頭的截圖的程序界面.
恭喜!
--------------------- 本文來自 jobbible 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/moshenglv/article/details/82869454?utm_source=copy