JavaFX-TableView详解

前言

最近在着手一个学生管理系统的编写,涉及到TableView的使用,这前前后后的也有了些经验和想法想要记录和分享一下(事实上我正在想要用html网页代替界面),更多的是学习之用。

先看看TableView中有些什么

在IDEA中,按住Ctrl然后点中TableView关键字会自动跟进到它定义的地方,我们可以先看看这里面到底都有些什么东西。

你会比较先的看到它的两个构造函数:

// 第一个构造函数
public TableView() {
    this(FXCollections.<S>observableArrayList());
}

// 第二个构造函数
public TableView(ObservableList<S> items) {
    getStyleClass().setAll(DEFAULT_STYLE_CLASS);
    setAccessibleRole(AccessibleRole.TABLE_VIEW);

    // we quite happily accept items to be null here
    setItems(items);

    // install default selection and focus models
    // it's unlikely this will be changed by many users.
    setSelectionModel(new TableViewArrayListSelectionModel<S>(this));
    setFocusModel(new TableViewFocusModel<S>(this));

    // we watch the columns list, such that when it changes we can update
    // the leaf columns and visible leaf columns lists (which are read-only).
    getColumns().addListener(weakColumnsObserver);

    // watch for changes to the sort order list - and when it changes run
    // the sort method.
    getSortOrder().addListener((ListChangeListener<TableColumn<S, ?>>) c -> {
        doSort(TableUtil.SortEventType.SORT_ORDER_CHANGE, c);
    });

    // We're watching for changes to the content width such
    // that the resize policy can be run if necessary. This comes from
    // TreeViewSkin.
    getProperties().addListener(new MapChangeListener<Object, Object>() {
        @Override
        public void onChanged(Change<? extends Object, ? extends Object> c) {
            if (c.wasAdded() && SET_CONTENT_WIDTH.equals(c.getKey())) {
                if (c.getValueAdded() instanceof Number) {
                    setContentWidth((Double) c.getValueAdded());
                }
                getProperties().remove(SET_CONTENT_WIDTH);
            }
        }
    });

    isInited = true;
}

可以大致的看一下,不过最重要的是清楚了一点:TableView内部是维护了一个类型为FXCollections.< S >observableArrayList的集合。其中< S >代表用户自己定义的类型。

也可以看到如何给Table添加监听者:

getProperties().addListener(new MapChangeListener<Object, Object>() {
    @Override
    public void onChanged(Change<? extends Object, ? extends Object> c) {
        if (c.wasAdded() && SET_CONTENT_WIDTH.equals(c.getKey())) {
            if (c.getValueAdded() instanceof Number) {
                setContentWidth((Double) c.getValueAdded());
            }
            getProperties().remove(SET_CONTENT_WIDTH);
        }
    }
});

总之你会看到许多非常有意思的东西,这里就不细说了,有兴趣的可以去自己读一下,对于理解TableView控件有着非常好的帮助,你能顾更加理解它运行的原理还有机制。

实际的运用

我们就来看看实际的运用吧,官方给出了非常详细的文档,有幸找到了把它翻译成较好版本中文的网站,直接给链接,里面就有一些简单的应用:

简单的应用:http://www.javafxchina.net/blog/2015/04/doc03_tableview/ 官方的文档:http://docs.oracle.com/javafx/2/ui_controls/table-view.htm

TableView列的两种数据形式:

一种是维护类的TableColumn<Person,String>类型,列的每一个数据都是一个类(这里是一个Person类),而String类型对应列名。映射需要这样设置:

col.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));    // firstName对应列名

另一种是维护Map的TableColumn<Map,String>类型,列的每一个数据都是Map。设置映射时需要这样:

col.setCellValueFactory(new MapValueFactory(colName));        // colName对应字符类型列名```

表格可编辑:

可以向官方文档中那样,也可以先增加一个TextFieldTableCell,然后再添加响应函数:

// 设置CellFactory,填充一个TextField进列
col.setCellFactory(TextFieldTableCell.<Map>forTableColumn());
// 设置编辑响应的函数
col.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Map, String>>() {
    @Override public void handle(TableColumn.CellEditEvent<Map, String> t) {
    System.out.println("检测到改变"); 
    // 这里修改维护的对应的设置进TableView的ObservableList集合
    }
});

添加行删除行也是同样的操作,可以直接修改TableView维护的集合来完成。

增加列,删除列

这就不仅仅要删除集合中的数据,还要从表格里面的Columns集合中删除相应的数据才可以,或许你还会在删除和增加中加入一定的判断来保证操作的正确性:

table.getColumns().add(tempCol);        // 列表中显示新增的列
table.getColumns().remove(index);          // 删除index位置的列

监听列的变化

你大可以选择向源文件中的那样,通过getProperties().addListener来完成监听,同样也可以添加进一个ListChangeListener:

// 给table设置监听器监听列的变化
table.getColumns().addListener(new ListChangeListener() {
    @Override
    public void onChanged(Change c) {
        c.next();                   // 接受变化,否则报错

        // 处理列拖动后的事件
        if (c.wasRemoved()) {
            // 定义一个保存了现在列排序的集合
            List<TableColumn<ObservableList<Map>, String>> newList =
                    new ArrayList<>(table.getColumns());
            // 定义一个保存了原来列排序的集合
            List<TableColumn<ObservableList<Map>, String>> oldList =
                    new ArrayList<>(c.getList());
            // 相关操作
        }   // end if:拖动事件处理完毕
    }
});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏jeremy的技术点滴

Java监听目录文件变更

41770
来自专栏cmazxiaoma的架构师之路

通用Mapper和PageHelper插件 学习笔记

1.1K30
来自专栏Flutter入门

Weex是如何在Android客户端上跑起来的

Weex可以通过自己设计的DSL,书写.we文件或者.vue文件来开发界面,整个页面书写分成了3段,template、style、script,借鉴了成熟的MV...

49750
来自专栏Java架构沉思录

深入理解-Spring-之源码剖析IOC(一)

作为Java程序员,Spirng我们再熟悉不过,可以说比自己的女朋友还要亲密,每天都会和他在一起,然而我们真的了解spring吗?

11230
来自专栏大内老A

ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】

到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性。这些特性包括如何针对IServiceP...

20370
来自专栏技术专栏

深入理解Spring源码(一)-IOC容器的定位,载入,注册

前言:Spring源码继承,嵌套层次非常多,读起来非常容易晕,小伙伴们在看文章的时候一定要跟着文章的思路自己去源码里点一点,看一看,并且多看几次。就会越来越清晰...

39510
来自专栏爱撒谎的男孩

地址管理之省市区三级联动菜单

1.1K30
来自专栏瓜大三哥

Yaffs_guts(三)

1.垃圾回收 1.static int yaffs_InitialiseBlocks(yaffs_Device *dev,int nBlocks)//块初始化 ...

23150
来自专栏开发技术

flying-saucer + iText + Freemarker实现pdf的导出, 支持中文、css以及图片

      项目中有个需求,需要将合同内容导出成pdf。上网查阅到了 iText , iText 是一个生成PDF文档的开源Java库,能够动态的从XML或者数...

45410
来自专栏编码小白

tomcat请求处理分析(六)servlet的处理过程

1.1.1.1  servlet的解析过程 servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这...

74570

扫码关注云+社区

领取腾讯云代金券