JavaFX TableView 自定义可编辑状态的切换和监听

网上的可查到的关于Java FX的表格内的编辑多是以在设置setEditable(true)后,再通过添加各种方法进行可编辑操作和编辑后的提交。但这些均存在一个操作逻辑的问题,均需要双击行列才能进入切换TextField进行编辑,因此在UI界面中若没有添加提示内容,用户将无法直观感知进入编辑操作的方法,会大大提高了用户的使用成本。因此从交互的角度,想到以各种方案

问题描述

最近在写图书馆系统用到了大量表格,也需要对表格内容进行直接编辑,但是经过搜索得到的JavaFX的表格内的编辑是以在设置setEditable(true)后,再通过添加各种方法进行可编辑操作和编辑后的提交。这种存在一个操作逻辑的问题,需要双击行列才能进入切换TextField进行编辑,因此在UI界面中若没有添加提示内容,用户将无法直观感知进入编辑操作的方法,会大大提高了用户的使用成本。因此从交互的角度,想到了各种方案,通过按钮点击、直接显示、点击表格自动切换的思路,实现易于用户使用的对表格操作的UI交互。

PS: 后想到部分博客的内容也用到自定义表格方案,但思路并不清晰,甚至有毫无解释的直接抛代码的,所以没啥心情去认真看。

思路分析

不能通过setCellFactory(TextFieldTableCell.forTableColumn())这样最简单的内置方法实现编辑,需要自己的自定义实现,虽略显麻烦,但十分好用。

自定义表格样式思路:

  • JavaFX中的TableView均是对Column进行操作,因此修改会直接修改整列的样式
  • 若不想将整列变化,可以通过定位聚焦当行的位置,行列的交点则为修改样式的单表格
  • 自定义样式内最好使用布局(HBox, VBox)填充,一是方便其随表格的变化而变化,二是更好设置所需的内容
  • 此次演示均以TextField实现,包含但不限于CheckBox / ChoiceBox / ComboBox / ProgressBar
  • 此次演示数据类型均为String,其他类型需自行调整

交互逻辑思路

  1. 直接显示TextField(不建议)
  2. 通过点击按钮在默认与TextField状态切换
  3. 通过直接点击表格显示TextField

思路实现

直接显示TextField(基础)

column.setCellFactory(new Callback<TableColumn<BookManageRecord, String>, TableCell<BookManageRecord, String>>() {//column为更改样式的目标列名 @Overridepublic TableCell<BookManageRecord, String> call(TableColumn<BookManageRecord, String> param) {//设置工厂方法并覆盖实现Callback其中的TableCell定义TableCell<BookManageRecord, String> cell = new TableCell<BookManageRecord, String>(){//通过覆盖其TableCell的定义实现自定义样式@Overrideprotected void updateItem(String item, boolean empty) {//覆盖TableCell的样式更新super.updateItem(item, empty);if(!empty && item != null){//核心内容HBox hbox = new HBox();                         //通过HBox布局填充表格便于管理hbox.setAlignment(Pos.CENTER);                  //内容居中TextField tf = new TextField(item);             //用获取到的item初始化TextFieldhbox.getChildren().add(tf);                     //将TextField加入HBox布局this.setGraphic(hbox);                          //将表格样式设置为HBox}}};return cell;        //返回该表格样式与内容}
)};

该方法缺点在于直接显示TextField无法切换回初始状态,但依旧可以实现当焦点不在该Textfield时提交内容,视情况而定吧!

通过Button点击切换

private int flag = 1;button.setOnAction(new EventHandler<ActionEvent>() {//button添加监听@Overridepublic void handle(ActionEvent event) {if(flag == 1){setToTextField();flag--;}else{setToLabel();flag++;}}
});private void setToTextField(){cat.setCellFactory(new Callback<TableColumn<BookManageRecord, String>, TableCell<BookManageRecord, String>>() {@Overridepublic TableCell<BookManageRecord, String> call(TableColumn<BookManageRecord, String> param) {TableCell<BookManageRecord, String> cell = new TableCell<BookManageRecord, String>(){@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);if(!empty && item != null){TextField tf = new TextField(item);HBox hbox = new HBox();hbox.setAlignment(Pos.CENTER);hbox.getChildren().add(tf);this.setGraphic(hbox);}}};return cell;}});
}
private void setToLabel(){cat.setCellFactory(new Callback<TableColumn<BookManageRecord, String>, TableCell<BookManageRecord, String>>() {@Overridepublic TableCell<BookManageRecord, String> call(TableColumn<BookManageRecord, String> param) {TableCell<BookManageRecord, String> cell = new TableCell<BookManageRecord, String>(){@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);if(!empty && item != null){Label label = new Label(item);                  //此处唯一不同便是使用了Label//这样一来和默认的样式区别不大HBox hbox = new HBox();hbox.setAlignment(Pos.CENTER);hbox.getChildren().add(label);this.setGraphic(hbox);}}};return cell;}});
}

updateItem()是在一列表格中,依次从上到下对每一个表格进行一次update操作,因此只要在setCellFactory()工厂方法中去进行判断全局的状态是该TextField还是Label的话,都会出现TextField和Label间隔出现的问题。
由于是自定义样式,因此在切换回Label的时候是无法监听到TextField内部的修改的,因此需要自定义添加监听,此处只是样式修改,不过多追加描述。

通过点击表格进行修改

table.setRowFactory( tv -> {TableRow<BookManageRecord> row = new TableRow<BookManageRecord>();row.setOnMouseClicked(event -> {//通过对单行的监听,再加单列样式的修改,实现点击坐标位的样式切换if (event.getClickCount() == 1 && (! row.isEmpty()) ) {cat.setCellFactory(new Callback<TableColumn<BookManageRecord, String>, TableCell<BookManageRecord, String>>() {@Overridepublic TableCell<BookManageRecord, String> call(TableColumn<BookManageRecord, String> param) {TableCell<BookManageRecord, String> cell = new TableCell<BookManageRecord, String>(){@Overrideprotected void updateItem(String item, boolean empty) {super.updateItem(item, empty);if(!empty && item != null){HBox hbox = new HBox();hbox.setAlignment(Pos.CENTER);TextField tf = new TextField(item);Label label = new Label(item);if(this.getTableRow().getIndex() == table.getSelectionModel().getSelectedIndex()){hbox.getChildren().add(tf);this.setGraphic(hbox);}else {hbox.getChildren().add(label);this.setGraphic(hbox);}}}};return cell;}});}});return row ;
});

用类似方法一样能实现用button控制的单表格样式切换,只要确定选中的行Index与需要刷新的行Index是否一致就可以实现了。

方法延伸

该方法下,通过判断item内容,可以实现单列表格内不同内容的不同样式。

参考借鉴

  1. Bilibili:JavaFX视频教程第98课,TableView,自定义单元格TableCell
  2. CSDN:使用javafx tableview控件时彻底解决单元格可编辑且可监听
    ——虽然没有认真看,但是写完回头发现这个的方案不错且适用于ComboBox的。

JavaFX TableView 自定义可编辑状态的切换和监听相关推荐

  1. 自定义下拉列表(使用原始的事件监听机制),在搜索框中使用

    目录 背景: 效果: 注意事项: 完整代码: 背景: 搜索框中需要使用到动态获取热点搜索历史的功能,此时需要自定义下拉列表.select组件不能完全满足要求. 搜索框下拉列表支持键盘上下键及回车选择, ...

  2. 初识广播机制(监听网络状态的改变,监听网络是否可以使用)

    Android系统中的广播机制比较灵活,因为Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应 ...

  3. Android 听筒扬声器切换 并且监听音量变化

    记录一下. 在activity 监听按键: @Override public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode = ...

  4. 对手机网络状态改变时的监听

    我们做app的时候可能会经常遇到这样的需求,当客户端的网络状态更改的时候进行一系列的操作.比如客户端网络断了,或者恢复了网络进行一些友好提示之类的. 其实做这个非常简单,仅仅需要做俩个监听即可: // ...

  5. Android 监听通话状态(挂断 监听 来电)实现自动外呼 按顺序拨出电话 间隔5秒

    最近项目也是添加一个小功能 监听通话状态实现一个自动外呼的功能 我在这里简单的实现了一下转了几天的博客可各大网站找出了一个最简单也好理解的一个方法(至今为止) 其实就用到了我们Android源生自带的 ...

  6. oracle 查看tns状态,oracle for windows 监听问题之TNS-12545

    操作系统版本:windows server 2012R2 数据库版本:oracle 11.2.0.1 问题描述:在一vmware虚拟机上搭建的windows server 2012R2,然后在wind ...

  7. 小程序自定义导航封装成组件后如何监听滚动距离

    我获取滚动的距离,主要是想做自定义导航吸顶效果之后对样式进行改变的效果 思路:根据滚动距离的临界值,改变isActive的值 第一步:曲线救国的方式,因为onPageScroll方法在组件中不生效(目 ...

  8. oracle手动切换scan监听,scan listener 重启

    srvctl status scan_listener (查询出listener_scan name) srvctl stop listener_scan1 srvctl stop listener_ ...

  9. android tableview实现多选功能,iOS开发UI篇-tableView在编辑状态下的批量操作(多选)...

    先看下效果图 直接上代码 #import "MyController.h" @interface MyController () { UIButton *button; } @pr ...

  10. 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本。该案例支持处理 js 的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异常 error 状态、支持视频播放

    YCWebView 项目地址:yangchong211/YCWebView 简介: 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本.该案例支持处理 js 的交 ...

最新文章

  1. ghost一键还原如何使用
  2. shell脚本——注释(单行注释 多行注释)
  3. poj1236/luogu2746 Network of Schools (tarjan)
  4. 嵌入式linux屏幕录制,在MAC系统上进行屏幕录制
  5. 谈谈Web Workers
  6. Google docs支持上传任何文档包括pdf...Cool!
  7. 《番茄工作法图解》一次只做一件事
  8. 一步步学习SPD2010--第八章节--理解工作流(8)--使用Visio映射工作流
  9. 怎么利用matlab求导,利用Matlab求导的几个命令
  10. 算法复杂度-渐进分析 (Asymptotic Analysis)
  11. HTML+CSS期末大作业:家乡旅游网站设计——山东菏泽(6页) 简单个人网页设计作业 静态HTML旅行主题网页作业 DW个人网站模板下载 大学生简单个人网页作品代码
  12. 论文笔记| 后门攻击|Composite Backdoor Attack for Deep Neural Network byMixing Existing Benign Features
  13. 二、11【FPGA】时序逻辑电路——计数器
  14. 论文阅读笔记之Replacing Mobile Camera ISP with a Single Deep Learning Model
  15. windows11应用商店错误:0x800704cf
  16. 腾讯游戏深度定制 ROG游戏手机3天生高能释放
  17. starlink星座近状
  18. 索尼(SONY)笔记本装系统蓝屏问题解决方案
  19. 一个月提升口语听力n个level
  20. 计算机万金油专业,为什么说自动化专业是万金油专业

热门文章

  1. sort和sorted的区别
  2. gitlab内网部署clone push速度快,网页反应慢
  3. PS-第十一天-通道抠图及剪贴蒙版
  4. Drilldown饼状图
  5. 全球知名开源项目与组织齐聚!——峰会【开源开放 生态共建】论坛来啦
  6. echarts中国及世界经纬度坐标
  7. 深蓝-视觉slam-第三节习题
  8. python设置休眠时间_如何在Python中实现时间睡眠?
  9. POI设置导出的EXCEL锁定指定的单元格
  10. 计算机里边的单位换算:b、KB、MB、GB、TB等