第二部分的主题

  • 创建一个 模型 类。
  • 在 ObservableList 使用模型类。
  • 使用 Controllers 在 TableView 上显示数据。

创建 模型 类。

我们需要一个模型类来保存联系人信息到我们的通讯录中。在模型包中 (ch.makery.address.model) 添加一个叫 Person的类。Person 类将会有一些变量,名字,地址和生日。将以下代码添加到类。在代码后,我将解释一些 JavaFX 的细节。

Person.java

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;
}
}

解释

  • 在JavaFX中,对一个模型类的所有属性使用 Properties是很常见的. 一个 Property 允许我们, 打个比方, 当 lastName 或其他属性被改变时自动收到通知, 这有助于我们保持视图与数据的同步,阅读 Using JavaFX Properties and Binding 学习更多关于 Properties 的内容。
  • birthday, 我们使用了 LocalDate 类型, 这在 Date and Time API for JDK 8 中是一个新的部分.

人员列表

我们的应用主要管理的数据是一群人的信息.让我们在 MainApp 类里面创建一个 Person 对象的列表。稍后其他所有的控制器类将存取 MainApp 的核心列表。

ObservableList

我们处理JavaFX的view classes需要在人员列表发生任何改变时都被通知. 这是很重要的,不然视图就会和数据不同步.为了达到这个目的,JavaFX引入了一些新的集合类.

在这些集合中, 我们需要的是ObservableList. 将以下代码增加到MainApp类的开头去创建一个新的ObservableList. 我们也会增加一个构造器去创建一些样本数据和一个公共的getter方法:

MainApp.java

    // ... 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 ...

The PersonOverviewController

现在我们终于要将数据加入到表格中了,我们需要一个控制器为了PersonOverview.fxml,.

  1. view包下创建一个名为 PersonOverviewController.java的普通java类(我们需要将这个类放在和PersonOverview.fxml相同的包下, 不然SceneBuilder会找不到它 - 至少在当前的版本).
  2. 我们需要增加一些实例变量来访问表格和在视图中的标签.这些属性和一些方法有一个特殊的 @FXML 注解. 这对于fxml文件访问私有属性和私有方法来说是必需的. 当将一切都在fxml文件中设置好之后, 应用程序会在fxml文件被载入时自动地填充这些变量. 让我们添加以下的代码:

Note: 记住要使用 javafx imports, 而不是awt和swing!

PersonOverviewController.java

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文件需要访问的属性和方法必须加上 @FXML 注解.实际上,只有在私有的情况下才需要, 但是让它们保持私有并且用注解标记的方式更好!
  • initialize() 方法在fxml文件完成载入时被自动调用. 那时, 所有的FXML属性都应已被初始化.
  • 我们在表格列上使用setCellValueFactory(...) 来确定为特定列使用Person对象的某个属性. 箭头 -> 表示我们在使用Java 8的 Lambdas 特性. (另一个选择是使用 PropertyValueFactory, 但它不是类型安全的).

连接 MainApp 和 PersonOverviewController

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();
}
}

将View与Controller挂钩

我们快要完成了! 但是有件小事被遗漏了: 至今没有告诉 PersonOverview.fxml使用的是哪个控制器以及元素与控制器中的属性的对应关系.

  1. 使用SceneBuilder 打开 PersonOverview.fxml.

  2. 打开左边的 Controller 组选择PersonOverviewController 作为 controller class.

  3. 在 Hierarchy 组选择TableView 并选择 Code 组将 personTable 作为 fx:id.

  4. 对列做相同的事并且将 firstNameColumn and lastNameColumn分别作为 fx:id .

  5. 对在第二列的 each label , 选择对应的 fx:id.

  6. 重要事项: 回到eclipse并且 refresh the entire AddressApp project (F5). 这是必要的因为有时候eclipse并不知道在Scene Builder中作出的改变.


启动应用程序

当你现在启动了你的应用,你应该看到了类似这篇博客开头的截图的程序界面.

恭喜!

---------------------

本文来自 jobbible 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/moshenglv/article/details/82869454?utm_source=copy

【JavaFx教程】第二部分:Model 和 TableView的更多相关文章

  1. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...

  2. [ABP教程]第二章 图书列表页面

    Web应用程序开发教程 - 第二章: 图书列表页面 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开 ...

  3. Qt model和tableview的使用

    QT中的model和tableview都是采用index索引   index含有两个成员变量一个是row   一个是column  对应该索引的行号.列号 model提供数据    view提供视图  ...

  4. 学习opencv中文版教程——第二章

    学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...

  5. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...

  6. javascript进阶教程第二章对象案例实战

    javascript进阶教程第二章对象案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过案例练习补充几个之前没有见到或者虽然讲过单是讲的不仔细的知识点. 二.具体实例 温馨提示 面向对象的知 ...

  7. EnjoyingSoft之Mule ESB开发教程第二篇:Mule ESB基本概念

    目录 1. 使用Anypoint Studio开发 2. Mule ESB Application Structure - Mule ESB应用程序结构 3. Mule ESB Application ...

  8. javafx将数据库内容输出到tableview表格

    一 .创建Fxml文件,用Javafx Scene Builder 编辑页面,创建tableview(表格)和tablecolum(表格中的列),并为其设置fxid: 二.生成fxml文件的控制类: ...

  9. Spring cloud系列教程第二篇:支付项目父工程图文搭建

    Spring cloud系列教程第二篇:支付项目父工程图文搭建 在讲解spring cloud相关的技术的时候,咱们就模拟订单支付这个流程来讲讲 在这个支付模块微服务搭建过程中,上面的这些技术,都会融 ...

随机推荐

  1. AngularJs创建自定义Service

    AngularJs可以创建自定义的service.下面的自定义service实现一个double倍数的服务: 参考下面语法: app.service('double', function () { t ...

  2. js怎么样根据select的name取到值

    先看一下ASP.NET MVC的html: 在jQuery中,可以写:

  3. 手机app有了短信验证码还有没必要有图片验证码?

    当然有必要,这里我们来聊一个恶意短信验证的案例,通过这个案例我们就能更好理解短信验证码和图片验证码这两者的关系了. 讨论防止恶意短信验证之前,我们先来看看什么是恶意短信验证及出现的原因. 恶意短信验证 ...

  4. form表单组件

    1.sweetalert 组件地址 form组件 form表单完成的事情,:   提供input可以提交数据, 对提交的数据进行校验,提供错误提示 定义form组件 from django impor ...

  5. Linux - 针对用户账号的常用操作

    用户目录 除root用户外,其他默认的用户目录一般为/home/<user name>. 可以通过如下步骤修改默认用户目录 修改/etc/passwd文件中相应用户的路径信息 停止此用户的 ...

  6. 原子操作--sync/atomic的用法

    golang 通过sync/atomic库来支持cpu和操作系统级别的原子操作.但是对要操作类型有如下要求 int32, int64,uint32, uint64,uintptr,unsafe包中的P ...

  7. html头部标签大全

    http://www.css88.com/archives/8052#table-index

  8. JS常用工具函数(持续记录)

    1.设置获取cookie //方式1 //设置cookie function SetCookie(name, value)//两个参数,一个是cookie的名字,一个是值 { var Days = 3 ...

  9. ElasticSearch 6.x 父子文档[join]分析

    ES6.0以后,索引的type只能有一个,使得父子结构变的不那么清晰,毕竟对于java开发者来说,index->db,type->table的结构比较容易理解. 按照官方的说明,之前一个索 ...

  10. python _、__、__xx__之间的差别

    默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类public,private等关键词来修饰成员函数和成员变量.其实,Python并没有真正的私有化支持, ...