JavaFX【TableView使用详解】

简介: JavaFX【TableView使用详解】

概述

TableView是JavaFX的一个重要的组件,毕竟我们在实际工作中表格还是经常使用的东西,不管是存储数据还是展示数据。

组件

接下来我们以学生信息为例,把它放到JavaFX的TableView中去展示,并看一下如何来实现增删改的操作。下面是我们需要用到的类:

Student

在JavaFX中,每一行数据就是一个Bean对象,也就是我们一个Java的实体类(类必须是public的),需要我们自己定义,这里我们的类名就叫Student。

public class Student {
    private String name;
    private int age;
    private double score;
    private  boolean is;
    public Student(String name, int age, double score, boolean is) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.is = is;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
    public boolean isIs() {
        return is;
    }
    public void setIs(boolean is) {
        this.is = is;
    }
}

ObservableList<Student>

这是我们的数据源,泛型参数就是我们的Student对象,使用时只需要通过下面这句构造:

ObservableList<Student> list = FXCollections.observableArrayList();

显然,通过名字我们就可以看出来,它支持类似于我们List集合的一些操作,待会增删改的时候再详细介绍。

TableView<Student>

这个类负责我们表格的展示,构造方法如下:

//新建tableView并指定数据源
        TableView<Student> tableView = new TableView<>(list);

只指定数据源其实是不够的,我们知道,一个表格包括“表头”和“身体”,而且需要注意的是:我们的TableView是以一列为一个对象的,所以我们需要设置tableview的属性(表头和内容),数据的显示主要有两种方法:

setCellValueFactory()

TableColumn

       这是表头,它负责表头的展示,因为前面我们已经指定了数据源,所以这里我们可以通过它来指定每一个列对象的内容(其实就是指定每一列的数据类型),setCellValueFactory()需要传入参数,我们可以通过两种参数来指定:

1. Callback

//第一列 姓名
TableColumn<Student,String> col_name = new TableColumn<>("姓名");
tableView.getColumns().add(col_name);//添加到tableView中展示
//设置该列的数据类型-返回单元格内容
col_name.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Student, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getName());
                return name;
            }
        });
//第二列 年龄 -这里的泛型是Number不是Integer
TableColumn<Student,Number> col_age = new TableColumn<>("年龄");
tableView.getColumns().add(col_age);
//这里的泛型是Number不是Integer,因为SimpleIntegerProperty继承了Observable<Number>接口,泛型是Number不是Integer
        col_age.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Number>, ObservableValue<Number>>() {
            @Override
            public ObservableValue<Number> call(TableColumn.CellDataFeatures<Student, Number> param) {
                SimpleIntegerProperty age = new SimpleIntegerProperty(param.getValue().getAge());
                return age;
            }
        });
//第三列 战斗力 -这里的泛型是Number不是Boolean
TableColumn<Student,Number> col_score = new TableColumn<>("战斗力");
tableView.getColumns().add(col_score);
col_score.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Number>, ObservableValue<Number>>() {
            @Override
            public ObservableValue<Number> call(TableColumn.CellDataFeatures<Student, Number> param) {
                SimpleDoubleProperty score = new SimpleDoubleProperty(param.getValue().getScore());
                return score;
            }
        });
//第四列 是否无敌
TableColumn<Student,Boolean> col_is = new TableColumn<>("是否无敌");
tableView.getColumns().add(col_is);
        col_is.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Student, Boolean>, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Student, Boolean> param) {
                SimpleBooleanProperty is = new SimpleBooleanProperty(param.getValue().isIs());
                return is;
            }
        });

需要注意的是,我们JavaFX对普通Java支持的基本类型进行了抽象,我们需要使用JavaFX规定的数据类型,比如我们的 Integer 和 Double 都需要转为Number类型,但是String和Boolean不需要。

2. PropertyValueFactory

需要注意的是,如果使用这种方法来指定内容的数据类型,这里我们可以使用Java自己的数据类型不需要使用JavaFX的Number类型,因此这种也更加简便:

//第一列 姓名
        TableColumn<Student,String> col_name = new TableColumn<>("姓名");
        tableView.getColumns().add(col_name);
        //第二列 年龄 --这里不需要使用Number代替
        TableColumn<Student,Integer> col_age = new TableColumn<>("年龄");
        tableView.getColumns().add(col_age);
        //第三列 战斗力 -这里不需要使用Number代替
        TableColumn<Student,Double> col_score = new TableColumn<>("战斗力");
        tableView.getColumns().add(col_score);
        //第四列
        TableColumn<Student,Boolean> col_is = new TableColumn<>("是否无敌");
        tableView.getColumns().add(col_is);
col_name.setCellValueFactory(new PropertyValueFactory<Student,String>("name"));
col_age.setCellValueFactory(new PropertyValueFactory<Student,Integer>("age"));
col_age.setCellValueFactory(new PropertyValueFactory<Student,Double>("score"));
col_age.setCellValueFactory(new PropertyValueFactory<Student,Boolean>("is"));

增加到末行

       显然对数据进行增删改其实就是通过修改我们的数据源(ObservableList<Student>)的数据集合list来实现的,这里又是可以通过两种方法来实现:

1、tableView.getItems().add(Student s)

Button bu = new Button("增加一行数据");
bu.setOnAction(event->{
            //增加到最后一行
            tableView.getItems().add(new Student("石敢当",999,100.0,true));
        });

2、list.add(Student s)

bu.setOnAction(event->{
            list.add(new Student("石敢当",999,100.0,true));
            tableView.refresh();
        });

删除指定行

同样是两种方法(参数为0代表删除第一行,1代表第二行,以次类推...):

1、tableView.getItems().remove(int i)

//删除第一行
        bu_rm.setOnAction(event -> {
            tableView.getItems().remove(0);//0是第一行,1是第二行,以此类推
        });

2、list.remove(int i)

//删除第一行
        bu_rm.setOnAction(event -> {
            list.remove(0);
            tableView.refresh();
        });

修该指定行

同样两张方法:

1、tableView.getItems().set(int i,Student s)

表示将第 i+1 行的内容换为新的对象s

//修改第一行
        bu_update.setOnAction(event -> {
            //同样0是第一行,1是第二行,以此类推
            tableView.getItems().set(0,new Student("熊大",18,80.0,true));
        });

2、s.setX()

//数据源
ObservableList<Student> list = FXCollections.observableArrayList();
//一行内容对对应的对象
Student s1 = new Student("李大喜",15,75.0,false);
list.add(s1);
//对已经有的对象进行修该实现表格的内容更新
        bu_update.setOnAction(event -> {
            //只修改属性我们可以通过Bean对象的set方法来修改,减少对象的创建
            s1.setAge(20);
            tableView.refresh();//需要刷新才能修改成功
        });

注意:使用list的方法进行add、remove以及使用直接对对象进行修改的时候,我们需要刷新一下tableView才能重新展示数据。

完整代码

TableTest

import com.sun.org.apache.bcel.internal.generic.NEW;
import com.sun.org.apache.xpath.internal.operations.Bool;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class TableTest extends Application{
  public static void main(String[] args) {
    launch(args);
  }
  @Override
  public void start(Stage primaryStage) throws Exception {
    ObservableList<Student> list = FXCollections.observableArrayList();
    list.add(new Student("燕双鹰", 18, 90.0, true));
    TableView tableView = new TableView(list);
    TableColumn<Student,String> col_name = new TableColumn<>("姓名");
    tableView.getColumns().add(col_name);
    TableColumn<Student,Integer> col_age = new TableColumn<>("年龄");
    tableView.getColumns().add(col_age);
    TableColumn<Student,Double> col_score = new TableColumn<>("分数");
    tableView.getColumns().add(col_score);
    TableColumn<Student,Boolean> col_is = new TableColumn<>("无敌");
    tableView.getColumns().add(col_is);
    col_name.setCellValueFactory(new PropertyValueFactory<Student,String>("name"));
    col_age.setCellValueFactory(new PropertyValueFactory<Student,Integer>("age"));
    col_score.setCellValueFactory(new PropertyValueFactory<Student,Double>("score"));
    col_is.setCellValueFactory(new PropertyValueFactory<Student,Boolean>("is"));
    AnchorPane pane = new AnchorPane();
    pane.getChildren().addAll(tableView);
    AnchorPane.setLeftAnchor(tableView, 50.0);
    AnchorPane.setTopAnchor(tableView, 50.0);
    Button add = new Button("添加一行");
    add.setOnAction(event->{
      tableView.getItems().add(new Student("光头强", 20, 80.0, true));//不需要刷新
//      list.add(new Student("李大喜", 15, 50.0, true));
//      tableView.refresh();
    });
    pane.getChildren().add(add);
    AnchorPane.setLeftAnchor(add, 20.0);
    Button del = new Button("删除第一行");
    del.setOnAction(event->{
      tableView.getItems().remove(0);
//      list.remove(0);
//      tableView.refresh();
    });
    pane.getChildren().add(del);
    AnchorPane.setLeftAnchor(del, 80.0);
    Button change = new Button("修改第一行");
    change.setOnAction(event->{
      tableView.getItems().set(0, new Student("光头强", 20, 80.0, true));//不需要刷新
//      list.set(0,new Student("李大喜", 15, 50.0, true));
//      tableView.refresh();
    });
    pane.getChildren().add(change);
    AnchorPane.setLeftAnchor(change, 160.0);
    Scene scene = new Scene(pane);
    primaryStage.setTitle("Javafx");
    primaryStage.setScene(scene);
    primaryStage.setHeight(600);
    primaryStage.setWidth(600);
    primaryStage.show();
  }
}


相关文章
|
12月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
11142 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
Java 开发者
Java一分钟之-JavaFX布局管理:GridPane, VBox, HBox
本文介绍了JavaFX的三种常用布局管理器:GridPane、VBox和HBox。GridPane用于创建二维网格布局,需设置行和列约束以防止控件重叠。VBox按垂直方向堆叠控件,记得设置间距。HBox水平排列控件,可能需要分配额外空间以避免水平滚动条。示例代码展示了这三种布局的使用。理解并运用这些布局管理器能提升JavaFX应用的界面设计。
668 0
|
前端开发 Java 容器
Java一分钟之-JavaFX控件:Button, TextField, Label等
JavaFX教程概述了构建UI的基本控件:Button用于用户操作,TextField提供文本输入,Label显示静态文本。文章讨论了样式、事件处理和布局管理常见问题及其解决方案,并提供了一个使用这些控件创建简单应用的代码示例,强调实践中提升GUI开发技能的重要性。
508 1
idea+javafx的真正打包方式
本文介绍了使用IntelliJ IDEA进行JavaFX项目打包的正确方法,包括编写一个调用主类的类、引入JavaFX的DLL文件、执行打包操作以及运行打包后的项目的步骤。
1205 0
idea+javafx的真正打包方式
|
Java 开发者
javafx jlink 遇到的非模块化的依赖打包报错“模块异常”的问题和处理
【9月更文挑战第18天】在使用JavaFX的jlink进行应用打包时,非模块化依赖可能导致“模块异常”报错。此文档详细分析了该问题的原因,并提供了四种解决方案:模块化依赖、自动模块转换、手动创建模块描述符及检查模块依赖关系。通过这些方法,可以有效解决此类问题,提高项目的可维护性和扩展性。建议开发者优先选用模块化设计。
1128 1
|
Java
IDEA的fxml打开Scene Builder后空白! Scene Builder下载依赖后还是空白不显示 无论如何都不显示,网上的教程试过来了遍还是不显示
本文提供了三种方法来解决IDEA中fxml文件在Scene Builder中打开后显示空白的问题:检查JavaFX是否安装、切换IDEA版本、下载Scene Builder插件。
936 1
|
Java
把javafx项目打包成exe文件详细过程
本文简化了将JavaFX项目打包成exe文件的过程,首先通过Idea将项目打包成jar包,然后使用GraalVM的native-image工具将jar包编译成exe文件,并展示了执行命令和运行结果。
881 0
把javafx项目打包成exe文件详细过程
|
Java Apache
Apache POI java对excel表格进行操作(读、写) 有代码!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
1705 0
|
XML IDE Java
JavaFX 教程
JavaFX 教程
1103 1
|
前端开发 Java API
使用JavaFX进行跨平台桌面应用开发的技术指南
【5月更文挑战第29天】JavaFX是Oracle的开源GUI工具包,用于跨平台桌面应用开发。它提供丰富的API、UI控件、图形动画支持及媒体集成。通过设置JDK和JavaFX SDK环境,使用IDE创建项目,编写并运行JavaFX代码,开发者可构建富客户端应用。遵循MVC模式、使用FXML和CSS,以及测试兼容性,能提升应用质量和用户体验。