javafx之tableview
tableview是一个非常常用的显示模式,我们可以对其加以改造,这样以便适应更多不同的需求。同时,因为javafx可以使用css,这样我们对tableview的显示就更得心应手了。
一、 tableview创建及数据加载:
当然,这是已经加入数据的tablew,来源于oracle http:// docs.oracle.com/javase/ 8/javase-clienttechnologies.htm
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Michael", "Brown", "michael.brown@example.com")
public static void main(String[] args) {
launch(args);
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<>("email"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
public String getFirstName() {
return firstName.get();
public void setFirstName(String fName) {
firstName.set(fName);
public String getLastName() {
return lastName.get();
public void setLastName(String fName) {
lastName.set(fName);
public String getEmail() {
return email.get();
public void setEmail(String fName) {
email.set(fName);
}
这段代码可以显示上图。
这里注意,bean中字段的类型是SimpleStringProperty,而不是普通的String。
显示控制文件中 firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));就是数据绑定,“firstName”对应你bean中创建的字段。
填充数据所用的private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Michael", "Brown", "michael.brown@example.com")
);
是javafx独特的ObservableList,如字面所述,是一个观察者的list,和ui绑定,一旦更改就直接改变ui,相当方便。当然,也要注意,不要对其进行频繁的操作,如果需要进行一些数据的调整,可以创建一个普通的arraylist,进行调整后,用ObservableList的addall方法加载。
二,tableview的标题头
如果想要取消的话:
tableview.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Pane header = (Pane) tableview.lookup("TableHeaderRow");
if (header != null && header.isVisible()) {
header.setVisible(false);
// header.setBackground(new Background(new BackgroundFill(Color.RED,CornerRadii.EMPTY,Insets.EMPTY)));
header.setManaged(false);
});
想要更改显示字体,背景等均可以通过css实现,下面是我实现的一个实例:
.table-view .column-header .label{
-fx-text-fill:white;
-fx-font-weight:bold;
-fx-background-color:black;
-fx-font-size:24px;
-fx-alignment:baseline-left;
.table-view .column-header{
-fx-background-color:black;
-fx-label-paddding:-20,0,0,0;
-fx-pref-height:36px;
}
基本就是操作了标题头和标题头中的文字。
三,表格可编辑
首先调用tableview的setEditable(true),使其可编辑。然后有两种方式:
Callback<TableColumn<Map, String>, TableCell<Map, String>>
cellFactoryForMap = (TableColumn<Map, String> p) ->
new TextFieldTableCell(new StringConverter() {
@Override
public String toString(Object t) {
return t.toString();
@Override
public Object fromString(String string) {
return string;
firstDataColumn.setCellFactory(cellFactoryForMap);
和
firstDataColumn.setCellFactory(TextFieldTableCell.<>forTableColumn());
同样可以让表格可编辑。然后调用对象的setOnEditCommit方法处理编写后的处理,其中event.getnewvalue方法可以获得你输入的值。这里注意,javafx对tableview输入的默认方式是双击单元格可以输入,键盘回车键提交。
四、tableview中的cell
css:
.table-cell{
-fx-padding: -6 0 0 0;
设定单元格覆盖:
tableview.setFixedCellSize(35.0);
五、tableview拖拽
private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object");
tableview.setRowFactory(tv1->{
TableRow<T> row=new TableRow<>();
row.setOnDragDetected(event -> {
if (! row.isEmpty()) {
Integer index = row.getIndex();
Dragboard db = row.startDragAndDrop(TransferMode.MOVE);
db.setDragView(row.snapshot(null, null));
ClipboardContent cc = new ClipboardContent();
cc.put(SERIALIZED_MIME_TYPE, index);
db.setContent(cc);
event.consume();
row.setOnDragOver(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(SERIALIZED_MIME_TYPE)) {
if (row.getIndex() != ((Integer)db.getContent(SERIALIZED_MIME_TYPE)).intValue()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
event.consume();
row.setOnDragDropped(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(SERIALIZED_MIME_TYPE)) {
int draggedIndex = (Integer) db.getContent(SERIALIZED_MIME_TYPE);
T t = tableview.getItems().remove(draggedIndex);
int dropIndex ;
if (row.isEmpty()) {
dropIndex = tableview.getItems().size() ;
} else {
dropIndex = row.getIndex();
tableview.getItems().add(dropIndex, t);
event.setDropCompleted(true);