SWT/Jface(2): 表格的編輯

前言

上節說到, 創建和渲染表格需要如下幾個步驟:

  1. 接收源數據數組(也可以是單個對象或者其他集合類型): TableViewer.setInput(Object)
  2. 渲染接收的數據
    1. 渲染表頭: TableViewer.setLabelProvider(IBaseLabelProvider)
    2. 渲染內容: TableViewer.setContentProvider(IContentProvider)

在實際應用中我們往往需要編輯表格并實現雙向綁定, 本節內容主要集中講如何對表格單元格添加編輯支持.

需求

當雙擊單元格時進入編輯模式

步驟

添加編輯支持

Jface提供了EditingSupport抽象類, 可以很方便的實現, 不過需要配合TableViewerColumn使用, 上節我們根據表頭數組創建了列:

        String[] titles = {"ID", "姓名", "性別", "年齡"};// 創建列頭信息, 并最終綁定到tableArrays.stream(titles).forEach(title -> TableColumnFactory.newTableColumn(SWT.NONE).width(80).text(title).create(table));

如需添加編輯支持可以直接根據TableColumn創建TableViewerColumn并將每一列對應的EditingSupport實現賦值給TableViewerColumn即可.
實現EditingSupport需要覆寫的方法簡介:

  1. CellEditor getCellEditor(Object): 當前列對應的編輯器類型, 主要有:
    1. TextCellEditor: 文字編輯器, 非常通用
    2. CheckboxCellEditor: 復選編輯器
    3. ComboBoxCellEditor: 下拉列表編輯器
    4. ColorCellEditor: 顏色編輯器
    5. DialogCellEditor: 對話編輯器, 這是高級用法, 可以實現個性定制
  2. boolean canEdit(Object): 當前列是否支持編輯
  3. Object getValue(Object): 編輯初始狀態顯示的值
  4. void setValue(Object oldValue, Object newValue): 編輯結束時需要賦值的邏輯, 第一個參數為編輯前對應的值, 第二個為編輯后對應的新值, 值類型取決于編輯器, 比如TextCellEditor對應的就是String類型.

需要注意的是, 當我們接受新值后, 要刷新下當前表格, 否則界面展示依然是之前的值, 也就是說我們在setValue方法的最后需要加上一行

tableViewer.update(o, null);

此時我們豐富一下創建表頭的邏輯, 這里列出空實現:

// 創建列頭信息, 并最終綁定到table
Arrays.stream(titles).forEach(title -> {TableColumn tableColumn = TableColumnFactory.newTableColumn(SWT.NONE).width(80).text(title).create(table);// 創建TableViewerColumn關聯到當前列并添加編輯支持new TableViewerColumn(tableViewer, tableColumn).setEditingSupport(new EditingSupport(tableViewer) {@Overrideprotected CellEditor getCellEditor(Object o) {return null;}@Overrideprotected boolean canEdit(Object o) {return false;}@Overrideprotected Object getValue(Object o) {return null;}@Overrideprotected void setValue(Object o, Object o1) {// 賦值邏輯...tableViewer.update(o, null);}});
});

添加觸發條件

僅僅添加編輯支持是不夠的, 因為系統不知道什么時候切換為編輯狀態, 比如我們只希望在雙擊當前單元格時開啟編輯狀態, Jface提供了ColumnViewerEditorActivationStrategy來控制策略:

ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(tableViewer) {@Overrideprotected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {// 只有雙擊事件才激活編輯器return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION;}
};

此時打開界面發現單擊表格也進入了編輯狀態, 并且一次性就高亮顯示整行, 這和需求不符, 我們需要借助TableViewerEditor來強制激活此策略, 并集成TableViewerFocusCellManager來高亮顯示本單元格而不是整行:

TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer, new FocusCellOwnerDrawHighlighter(tableViewer));
TableViewerEditor.create(tableViewer, focusCellManager, activationStrategy, ColumnViewerEditor.DEFAULT);

此時我們只需要將之前的EditingSupport根據實際業務完善下基本就OK了, 整體源碼見下一小節, 先看下效果.

在這里插入圖片描述

數據校驗

實際業務中可能對某些數據有特殊要求, 此時就要對輸入的數據進行校驗, 并給出提示, 我們可以借助MessageBox來實現提示, 將校驗邏輯放在EdittingSupport.setValue方法中.
比如對年齡的校驗可以這樣寫:

@Override
protected void setValue(Object o, Object o1) {String newValue = String.valueOf(o1);if (o instanceof People people) {switch (title) {case "年齡" -> {try {people.setAge(Integer.parseInt(newValue));} catch (Exception e) {MessageBox messageBox = new MessageBox(shell);messageBox.setText("輸入不合法");messageBox.setMessage("必須是數字");messageBox.open();}}// 其他邏輯}}tableViewer.update(o, null);
}

看下效果:
在這里插入圖片描述

源碼

import org.eclipse.jface.viewers.*;
import org.eclipse.jface.widgets.TableColumnFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;import java.util.Arrays;public class Main {public static void main(String[] args) {final Display display = Display.getDefault();final Shell shell = new Shell();shell.setLayout(new FillLayout());shell.setSize(500, 375);shell.setText("SWT Application");//注意這里,SWT.MULTI代表可以選擇多行,SWT.FULL_SELECTION代表可以整行選擇,SWT.BORDER邊框,SWT.V_SCROLL ,SWT.H_SCROLL滾動條TableViewer tableViewer = new TableViewer(shell, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);Table table = tableViewer.getTable();// 表格邊框線是否可見table.setLinesVisible(true);// 表頭是否可見table.setHeaderVisible(true);// 設置表格大小table.setBounds(97, 79, 373, 154);String[] titles = {"ID", "姓名", "性別", "年齡"};// 創建列頭信息, 并最終綁定到tableArrays.stream(titles).forEach(title -> {TableColumn tableColumn = TableColumnFactory.newTableColumn(SWT.NONE).width(80).text(title).create(table);new TableViewerColumn(tableViewer, tableColumn).setEditingSupport(new EditingSupport(tableViewer) {@Overrideprotected CellEditor getCellEditor(Object o) {return new TextCellEditor(tableViewer.getTable());}@Overrideprotected boolean canEdit(Object o) {return !"ID".equalsIgnoreCase(title);}@Overrideprotected Object getValue(Object o) {if (o instanceof People people) {return switch (title) {case "ID" -> String.valueOf(people.getId());case "姓名" -> people.getName();case "性別" -> people.getSex();case "年齡" -> String.valueOf(people.getAge());default -> "";};}return "";}@Overrideprotected void setValue(Object o, Object o1) {String newValue = String.valueOf(o1);if (o instanceof People people) {switch (title) {case "年齡" -> {try {people.setAge(Integer.parseInt(newValue));} catch (Exception e) {MessageBox messageBox = new MessageBox(shell);messageBox.setText("輸入不合法");messageBox.setMessage("必須是數字");messageBox.open();}}case "姓名" -> people.setName(newValue);case "性別" -> people.setSex(newValue);}}tableViewer.update(o, null);}});});ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(tableViewer) {@Overrideprotected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {// 只有雙擊事件才激活編輯器return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION;}};table.setHeaderBackground(display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND));table.setHeaderForeground(display.getSystemColor(SWT.COLOR_TITLE_FOREGROUND));TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer, new FocusCellOwnerDrawHighlighter(tableViewer));TableViewerEditor.create(tableViewer, focusCellManager, activationStrategy, ColumnViewerEditor.DEFAULT);tableViewer.setContentProvider(ArrayContentProvider.getInstance());tableViewer.setLabelProvider(PeopleLabelProvider.getInstance());People people = new People();people.setId(1);people.setName("張三");people.setSex("男");people.setAge(10);tableViewer.setInput(new People[]{people});shell.open();while (!shell.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}}
}

其他方案

實現編輯支持還有其他方式, 比如實現ICellModifier, 不過這種方式需要額外指定properties用來指定和列名的對應關系, 個人不是很喜歡這種, 有興趣可以參考: Swt/Jface tableViewer入門教程三(加入在表格上直接編輯數據)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164421.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164421.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164421.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java.lang.IllegalArgumentException: java.net.UnknownHostException: xxx

windows系統下連接hdfs進行操作時,上來就出現java.lang.IllegalArgumentException: java.net.UnknownHostException: xxx java.lang.IllegalArgumentException: java.net.UnknownHostException: liujianat org.apache.hadoop.security.SecurityUtil.buildTokenServ…

Keil Vision5—新建工程project

注意:創建的工程目錄必須是純英文目錄 目錄 1.開始配置 2.為該路徑下新建個文件夾 3.選擇器件 4.工程配置 4.右擊魔術棒,設置參數 ?編輯 (1)target配置 (2)output配置 (3)c…

字符串結尾空格比較相關參數BLANK_PAD_MODE(DM8:達夢數據庫)

DM8:達夢數據庫 字符串結尾空格比較相關參數BLANK_PAD_MODE 環境介紹1 BLANK_PAD_MODE01.1 初始化數據庫1.2 創建測試表 T0 2 BLANK_PAD_MODE12.1 初始化數據庫2.2 創建測試表 T1 3 BLANK_PAD_MODE只對字段varchar類型生效3.1 BLANK_PAD_MODE 對char 類型對比無效3.2 在兩個數據…

計算機中了halo勒索病毒怎么清除,halo勒索病毒解密數據恢復

科技的進步加快了企業發展的步伐,網絡技術的不斷應用為企業的生產運營提供了極大幫助,但隨之而來的網絡安全威脅也不斷增加,近期,云天數據恢復中心接到很多企業的求助,企業的計算機服務器遭到了halo勒索病毒攻擊&#…

Jmeter快速入門

文章目錄 1.安裝Jmeter1.1.下載1.2.解壓1.3.運行 2.快速入門2.1.設置中文語言2.2.基本用法 1.安裝Jmeter Jmeter依賴于JDK,所以必須確保當前計算機上已經安裝了JDK,并且配置了環境變量。 1.1.下載 可以Apache Jmeter官網下載,地址&#xf…

uni-app打包后,打開軟件時使其橫屏顯示

找到page.json文件,在global加入以下代碼: 這樣就可以橫屏顯示了。

CANdelaStudio 使用教程 1

文章目錄 CANdelaStudio 軟件下載CANdelaStudio 軟件的權限View Edition 和 Admin Edition 區別:打開文件 CDD / CDDT 文件新建 CDD 文件新建 CDDT 文件CDD 和 CDDT 文件的區別 CANdelaStudio 軟件下載 1、 來到 Vector 官網下載中心 https://www.vector.com/cn/zh…

[shader] 光照入門(未完結。。。

反射 漫反射:而當物體表面粗糙時,我們把物體表面看作無數不同方向的微小鏡面,則這些鏡面反射出的光方向均不相同,這就是漫反射。 高光反射:我們假定物體表面光滑,只有一個鏡面,那么所有的光都…

報錯For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

.報錯For debugging consider passing CUDA_LAUNCH_BLOCKING1. /aten/src/ATen/native/cuda/NLLLoss2d.cu:103: nll_loss2d_forward_kernel: block: [29,0,0], thread: [707,0,0] Assertion t > 0 && t < n_classes failed. 報錯信息如下&#xff1a; ./aten/…

力扣labuladong——一刷day46

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、力扣971. 翻轉二叉樹以匹配先序遍歷二、力扣987. 二叉樹的垂序遍歷三、力扣666. 路徑總和 IV 前言 二叉樹的遞歸分為「遍歷」和「分解問題」兩種思維模式&a…

面試:RocketMQ相關問題

文章目錄 什么是 RocketMQ&#xff0c;有哪些使用場景&#xff1f;RocketMQ 由哪些?色組成&#xff0c;每個?色作用和特點是什么&#xff1f;RocketMQ 中的 Topic 和 JMS 的 queue 有什么區別&#xff1f;RocketMQ 消費模式有幾種&#xff1f;RocketMQ 的 Consumer 是如何消費…

【深度學習】Python快捷調用InsightFace人臉檢測,純ONNX推理

pypi資料&#xff1a; https://pypi.org/project/insightface/ 模型選擇&#xff1a; https://github.com/deepinsight/insightface/tree/master/python-package#model-zoo onnxruntime的GPU對應CUDA &#xff1a; https://onnxruntime.ai/docs/reference/compatibility …

1999-2021年地級市城鎮居民人均消費性支出數據

1999-2021年地級市城鎮居民人均消費性支出數據 1、時間&#xff1a;1999-2021年 2、指標&#xff1a;城鎮居民人均消費性支出 3、范圍&#xff1a;290個地級市 4、來源&#xff1a;城市年鑒、地級市統計公報 5、指標解釋&#xff1a; 城鎮居民人均消費性支出&#xff1a;指…

kubesphere安裝依賴文件

yum install socat -y yum install conntrack -y

GAMES101-Homework2

目錄 普通作業&#xff1a;提高作業&#xff1a;參考博客博客一博客二博客三 附代碼框架的個人一些注釋和理解&#xff1a;rasterizer.cppTriangle.cpp 普通作業&#xff1a; // 判斷點是否在三角形內的輔助函數 static bool insideTriangle(float x, float y, const Vector3f…

再添千萬級罰單,某銀行年內罰款過億!金融行業合規問題亟待解決

11月17日晚間&#xff0c;國家金融監管總局上海監管局披露行政處罰信息顯示&#xff0c;某銀行因32項違法違規事實收到兩張690萬元的大額罰單&#xff0c;合計罰款金額達1380萬元。但這并不是銀行該今年收到的第一張大額罰單。今年4月28日&#xff0c;該行因在結售匯、外幣理財…

k8s-pod生命周期 4

容器環境初始化 pod 由pod 鏡像來提供&#xff0c;在pod 生命周期里容器主要分為兩種&#xff1a;初始化容器和主容器 初始化容器一定要成功運行并退出&#xff0c;當初始化容器運行退出完了之后主容器開始和運行 主容器開始運行的時候&#xff0c;有兩個探針&#xff1a;存…

什么是arguments對象?

arguments 對象是 JavaScript 中的一個特殊對象&#xff0c;它包含了函數被調用時傳入的所有參數。arguments 對象是一個類數組對象&#xff0c;它有一個 length 屬性和按數字索引的元素。 每個函數在執行時都會自動創建一個 arguments 對象。我們可以通過arguments去訪問參數…

網絡圖簡單計算規則

單代號進度網絡圖&#xff08;節點法&#xff09; 概念 計算規則 &#xff08;順時針計算法&#xff09; &#xff08;TF取之差&#xff09; &#xff08;T&#xff1a;持續時間&#xff09; ES → EF (ES取大EF加T) ↑ T ↑ &#xff08;TF&#xff1a;總時差&…

NOIP2003提高組第二輪T3:加分二叉樹

題目鏈接 [NOIP2003 提高組] 加分二叉樹 題目描述 設一個 n n n 個節點的二叉樹 tree \text{tree} tree 的中序遍歷為 ( 1 , 2 , 3 , … , n ) (1,2,3,\ldots,n) (1,2,3,…,n)&#xff0c;其中數字 1 , 2 , 3 , … , n 1,2,3,\ldots,n 1,2,3,…,n 為節點編號。每個節點都…