您的位置:首页 > 编程语言 > Java开发

JavaFX表格控件TableView高级应用:自动添加ID列、删除操作列、单元格内容个性化渲染

2017-05-13 00:25 681 查看

问题描述

我们在用Javafx开发应用程序的时候,TableView是比较常用的用来展示数据的控件,但是它的灵活性确实没有WEB开发里面的控件好,比如,我遇到的问题就有:

数据库存储里面的ID列(序号)一般是自增性质的,不停的增加、删除操作后,这个序号列就会乱,数字 不连续,而我们要显示到GUI里面的序号列肯定需要按正常顺序显示的,本文提供构造顺序序号列的方法;

操作列(比如删除)的渲染问题,一种思路就是在表格控件之外加一个删除按钮,点击按钮的时候判断一下当前选中的行,然后执行删除操作。本文讨论另外一种思路,单独在表格里面添加一个删除列(每行都有一个删除按钮,单击则删除所在行数据);

很多时候,我们具有个性化显示表格数据的需求,比如,显示学生数学成绩的某列,我们希望把那些低于60分的分数标红,而及格分数则不做处理;

[b]TableView理解[/b]

JavaFX表格控件渲染数据主要有两种方法:

1. setCellValueFactory(new PropertyValueFactory<>(“字段名”)),适合表格列数已知,有对应实体的情况(比如,学生信息,我们假定它只有姓名、性别、学号、地址、联系方式等固定字段,则适合采用此种方式进行渲染);

2. setCellValueFactory(new MapValueFactory<>(“对应列的键值”)),适合表格列数在渲染之前未知,需要根据传入数据的维数确定的情况,此时因为没有固定列数,所以一般数据也没有对应的实体类,数据需要用Map进行构造,一行数据就是一个Map;

本文主要针对列数已知的情况,Map的情况同理。

[b]代码DEMO[/b]

工程目录如下图:



Main.java

/**
* 实现表格的序号列的计算填充,
* 实现按钮操作列的正常显示以及事件绑定
*/
package application;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application {

@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(this.getClass().getResource("FXTable.fxml"));
// 为表格设置控制器
loader.setController(new TableController());
AnchorPane rootPane = loader.load();
Scene scene = new Scene(rootPane,506,460);
primaryStage.sizeToScene();
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
launch(args);
}
}


Student.java

package application;

public class Student {
private String firstName;
private String lastName;
private int age;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Student(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}


TableController.java

package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.ImageView;

public class TableController implements Initializable {
@FXML
private Label fxLabel;
@FXML
private TableView<Student> stuTable;
@FXML
private TableColumn<Student, String> idCol, fNameCol, lNameCol, delCol;
@FXML
private TableColumn<Student, Integer> ageCol;
@FXML
private TableColumn<Student, Boolean> isAdultCol;

public ObservableList<Student> getStuData() {

Student stu1 = new Student("赵", "哈", 16);
Student stu2 = new Student("钱", "大", 26);
Student stu3 = new Student("孙", "阿", 23);
Student stu4 = new Student("李", "佛山", 17);
Student stu5 = new Student("周", "阿萨德", 23);
Student stu6 = new Student("吴", "更好", 12);
Student stu7 = new Student("郑", "和", 28);
Student stu8 = new Student("王", "费", 23);
Student stu9 = new Student("刘", "的", 15);
Student stu10 = new Student("关", "时是", 23);
Student stu11 = new Student("张", "良好", 19);
Student stu12 = new Student("诸葛", "列", 23);
Student stu13 = new Student("司马", "咯跑", 20);

ObservableList<Student> stuLists = FXCollections.observableArrayList(stu1, stu2, stu3, stu4, stu5, stu6, stu7,
stu8, stu9, stu10, stu11, stu12, stu13);
return stuLists;
}

/**
* 显示学生表格
*
* @param stuLists
*/
public void showStuTable(ObservableList<Student> stuLists) {
fNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
lNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
// ageCol.setCellValueFactory(new PropertyValueFactory<>("age"));
idCol.setCellFactory((col) -> {
TableCell<Student, String> cell = new TableCell<Student, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
this.setText(null);
this.setGraphic(null);

if (!empty) {
int rowIndex = this.getIndex() + 1;
this.setText(String.valueOf(rowIndex));
}
}
};
return cell;
});

ageCol.setCellFactory((col) -> {
TableCell<Student, Integer> cell = new TableCell<Student, Integer>() {

@Override
public void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
this.setText(null);
this.setGraphic(null);

if (!empty) {
int age = this.getTableView().getItems().get(this.getIndex()).getAge();
this.setText(String.valueOf(age));
if (age < 18) {
this.getStyleClass().add("mark");
}
}
}

};
return cell;
});

isAdultCol.setCellFactory((col) -> {
TableCell<Student, Boolean> cell = new TableCell<Student, Boolean>() {

@Override
public void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
this.setText(null);
this.setGraphic(null);

if (!empty) {
CheckBox checkBox = new CheckBox();
this.setGraphic(checkBox);
checkBox.selectedProperty().addListener((obVal, oldVal, newVal) -> {
if (newVal) {
// 添加选中时执行的代码
System.out.println("第" + this.getIndex() + "行被选中!");
// 获取当前单元格的对象
// this.getItem();
}

});
}
}

};
return cell;
});

delCol.setCellFactory((col) -> {
TableCell<Student, String> cell = new TableCell<Student, String>() {

@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
this.setText(null);
this.setGraphic(null);

if (!empty) {
ImageView delICON = new ImageView(getClass().getResource("delete.png").toString());
Button delBtn = new Button("删除", delICON);
this.setGraphic(delBtn);
delBtn.setOnMouseClicked((me) -> {
Student clickedStu = this.getTableView().getItems().get(this.getIndex());
System.out.println("删除 " + clickedStu.getFirstName() + clickedStu.getLastName() + " 的记录");
});
}
}

};
return cell;
});

stuTable.setItems(stuLists);
}

@Override
public void initialize(URL location, ResourceBundle resources) {

fxLabel.setWrapText(true);
fxLabel.setText("        javafx_Label标签的换行测试,用于弹出框的提示信息测试,Label控件也可以换行。");

this.showStuTable(this.getStuData());
}

}


FXTable.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="461.0" prefWidth="489.0" stylesheets="@Fxtable.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TableView fx:id="stuTable" layoutY="54.0" prefHeight="407.0" prefWidth="402.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="54.0">
<columns>
<TableColumn fx:id="idCol" prefWidth="75.0" text="序号" />
<TableColumn fx:id="fNameCol" prefWidth="87.0" text="姓氏" />
<TableColumn fx:id="lNameCol" prefWidth="79.0" text="名字" />
<TableColumn fx:id="ageCol" prefWidth="73.0" text="年龄" />
<TableColumn fx:id="delCol" prefWidth="86.0" text="删除列" />
<TableColumn fx:id="isAdultCol" prefWidth="88.0" text="成年?" />
</columns>
</TableView>
<Label fx:id="fxLabel" layoutY="-1.0" prefHeight="56.0" prefWidth="402.0" />
</
97e8
children>
</AnchorPane>


[b]运行截图:[/b]





[b]实现描述:[/b]

实体类里面无ID字段,表格做数据展示的时候临时构造顺序ID列数据;

删除操作列的渲染,并且添加单击事件,能够实时响应删除动作;

年龄一列的个性化显示,未成年年龄显示为红色字体;

另,DEMO源码可以向我索要。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐