SWT/Jface(3): 表格中添加超链接

背景

实际业务中经常需要展示某个网站, 并且希望在展示的时候单击网站可直接访问, 本节演示在表格中如何添加超链接支持.

需求

假设我需要渲染一个Study类, 它只有三个属性id,namewebsite, 其中id只支持展示, name只支持编辑, 而website只支持单击时跳转到相应的网站, 效果图如下:
在这里插入图片描述

方案

要在表格中添加超链接支持, 需要特殊的CellLableProvider, Jface提供了ColumnLabelProvider, 要想实现超链接, 只需要重新实现其中的updategetText方法.

方法名方法签名功能描述
getTextString getText(Object element)提供表格渲染后展示的文本的内容
updatevoid update(ViewerCell cell)提供表格对象的额外展示项, 比如背景颜色, 字体的设置等等

我们的超链接支持就可以放在update中来进行扩展实现:

  1. 创建Link对象, 并通过TableEditor将其与TableItem关联起来
  2. 添加Link对象的单击事件监听, 点击时进行跳转
Link link = new Link((Composite) cell.getControl(), SWT.NONE);
link.setText("<a>" + study.website + "</a>");
TableItem item = (TableItem) cell.getItem();
TableEditor editor = new TableEditor(item.getParent());
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(link, item, cell.getColumnIndex());
editor.layout();
link.addListener(SWT.Selection, e -> {try {Desktop.getDesktop().browse(new URI(study.website));} catch (IOException | URISyntaxException ex) {throw new RuntimeException(ex);}
});

注意实现

之前我们设置CellLabelProvider时是通过Tabel级别的对象进行的, 实际上我们往往是根据不同的Column来设置更为个性化的展示的, 因此, 在创建Column的同时设置CellLableProvider更为合理. 伪代码:

TableViewer tableViewer = ...;
Table table = tableViewer.getTable();
TableColumn tableColumn = TableColumnFactory.newTableColumn(SWT.NONE)....create(table);
TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, tableColumn);
// 每一列设置一个特定的cellLabelProvider
tableViewerColumn.setLabelProvider(cellLabelProvider);

源码

import org.eclipse.jface.viewers.*;
import org.eclipse.jface.widgets.TableColumnFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.*;import java.awt.*;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;public class Study {@Column(value = "ID", labelProviderClass = StudyLabelProvider.class)public int id;@Column(value = "名称", labelProviderClass = StudyLabelProvider.class, width = 200)@TextEditorpublic String name;@Column(value = "网站", labelProviderClass = StudyLabelProvider.class, width = 300)public String website;public Study(int id, String name, String website) {this.id = id;this.name = name;this.website = website;}private static Study[] studies() {return new Study[]{new Study(1, "github", "https://github.com"), new Study(2, "死磕Java", "https://skjava.com")};}public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {Display display = new Display();Shell shell = new Shell(display);shell.setLayout(new FillLayout());var tableViewer = new TableViewer(shell, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);Table table = tableViewer.getTable();table.setHeaderVisible(true);table.setLinesVisible(true);Field[] fields = Study.class.getFields();for (Field field : fields) {Column column = field.getAnnotation(Column.class);String columnText = column.value();Class<? extends CellLabelProvider> labelProviderClass = column.labelProviderClass();CellLabelProvider cellLabelProvider;if (!(CellLabelProvider.class == labelProviderClass)) {Constructor<? extends CellLabelProvider> constructor = labelProviderClass.getConstructor(String.class);cellLabelProvider = constructor.newInstance(columnText);} else {cellLabelProvider = new StudyLabelProvider(columnText);}TableColumn tableColumn = TableColumnFactory.newTableColumn(SWT.NONE).width(column.width()).text(columnText).align(SWT.CENTER).create(table);TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, tableColumn);tableViewerColumn.setLabelProvider(cellLabelProvider);EditingSupport editingSupport = null;TextEditor textEditor = field.getAnnotation(TextEditor.class);if (textEditor != null) {Class<? extends EditingSupport> editingSupportClass = textEditor.editingSupportClass();Constructor<? extends EditingSupport> constructor = editingSupportClass.getConstructor(TableViewerColumn.class);editingSupport = constructor.newInstance(tableViewerColumn);}Optional.ofNullable(editingSupport).ifPresent(tableViewerColumn::setEditingSupport);}ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(tableViewer) {@Overrideprotected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {// 只有双击事件才激活编辑器return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC || event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL;}};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.setInput(Study.studies());shell.open();while (!shell.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}}public static class StudyEditingSupport extends EditingSupport {private final TableViewerColumn tableViewerColumn;private final String title;public StudyEditingSupport(TableViewerColumn tableViewerColumn) {super(tableViewerColumn.getViewer());this.tableViewerColumn = tableViewerColumn;TableColumn tableColumn = tableViewerColumn.getColumn();this.title = tableColumn.getText();}@Overrideprotected CellEditor getCellEditor(Object o) {return new TextCellEditor(tableViewerColumn.getColumn().getParent());}@Overrideprotected boolean canEdit(Object o) {return true;}@Overrideprotected Object getValue(Object o) {if (!(o instanceof Study study)) {return "";}return switch (title) {case "名称" -> study.name;default -> study.website;};}@Overrideprotected void setValue(Object o, Object o1) {if (!(o instanceof Study study)) {return;}switch (title) {case "名称" -> study.name = String.valueOf(o1);default -> study.website = String.valueOf(o1);}getViewer().refresh(o);}}public static class StudyLabelProvider extends ColumnLabelProvider {private final String title;public StudyLabelProvider(String title) {super();this.title = title;}@Overridepublic void update(ViewerCell cell) {if (!(cell.getElement() instanceof Study study)) {return;}var text = switch (title) {case "ID" -> String.valueOf(study.id);case "名称" -> study.name;default -> {Link link = new Link((Composite) cell.getControl(), SWT.NONE);link.setText("<a>" + study.website + "</a>");TableItem item = (TableItem) cell.getItem();TableEditor editor = new TableEditor(item.getParent());editor.grabHorizontal = true;editor.grabVertical = true;editor.setEditor(link, item, cell.getColumnIndex());editor.layout();link.addListener(SWT.Selection, e -> {try {Desktop.getDesktop().browse(new URI(study.website));} catch (IOException | URISyntaxException ex) {throw new RuntimeException(ex);}});yield "";}};cell.setText(text);}@Overridepublic String getText(Object element) {if (!(element instanceof Study study)) {return "";}return switch (title) {case "ID" -> String.valueOf(study.id);case "名称" -> study.name;default -> study.website;};}}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface Column {String value();Class<? extends CellLabelProvider> labelProviderClass() default CellLabelProvider.class;int width() default 100;}@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface TextEditor {Class<? extends EditingSupport> editingSupportClass() default StudyEditingSupport.class;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试准备

计算密集型&#xff1a;这一类主要是在线程中&#xff0c;按照数学公式&#xff0c;大量求和、求平均、求平方等等操作&#xff0c;这样的任务&#xff0c;大部分需要依赖CPU的计算能力来处理&#xff0c;我们设置线程数一般是&#xff1a;计算机核数n1。 IO密集型&#xff1a;…

Linux7设置ssh秘钥登录并关闭密码登录

说明&#xff1a;场景为windows使用WinScp远程登录linux服务 winscp安装教程&#xff1a;winscp安装及关联putty使用_putty.exe没有找到_cherishSpring的博客-CSDN博客 1.在window上生成公钥和秘钥&#xff0c;操作方式参考以下文章第3点&#xff1a; git关联云效使用教程_云…

【Excel导入】- EasyExcel读取Excel空数据行问题

EasyExcel读取Excel空数据行问题 原因解决写在最后 原因 项目Excel导入使用的EasyExcel工具&#xff0c;为什么会出现空白行的问题呢&#xff1b;在进行Excel导入时都会提前设定一个Excel模版&#xff0c;Excel导入时在Excel模版中设置了单元的样式&#xff0c;但没有给单元格…

Ps:使用钢笔工具绘制自由路径的技巧

只有熟练掌握使用钢笔工具绘制自由路径的技巧&#xff0c;才能快速完成复杂形状的创建以及精准抠图等工作。 钢笔工具是 Photoshop 中绘制路径的主要工具。无论是直线路径还是曲线路径&#xff0c;钢笔工具都能够提供高度的控制和精确度。 ◆ ◆ ◆ 绘制直线路径 绘制直线路径…

下载网页内容成HTML文件

今天遇到了一个非常好用的、开源的网页下载插件: SingleFile&#xff0c;它可以将当前网页里的文字、图片、超链接等&#xff0c;合并成单一的.html文件&#xff0c;便于保存和浏览查看。下面介绍SingleFile的安装和使用。 1、下载SingleFile插件 SingleFile官网地址&#xff…

高并发系统:它的通用设计方法是什么?

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 我们知道&#xff0c;高并发代表着大流量&#xff0c;高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的方案&#xff0c;从而抵抗巨大流量的冲击&#xff0c;带给用户更好的使用体验。这些方案好似能…

Mybatis-Plus 租户使用

Mybatis-Plus 租户使用 文章目录 Mybatis-Plus 租户使用一. 前言1.1 租户存在的意义1.2 租户框架 二. Mybatis-plus 租户2.1 租户处理器2.2 前置准备1. 依赖2. 表及数据准备3. 代码生成器 2.3 使用 三. 深入使用3.1 前言3.2 租户主体设值&#xff0c;取值3.3 部分表全量db操作3…

大数据-之LibrA数据库系统告警处理(ALM-37004 Datanode主备不同步或者断连)

告警解释 当DN主实例与DN备实例连接异常时&#xff0c;产生该告警。 告警属性 告警ID 告警级别 可自动清除 37004 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称 RoleName 产生告警的角色名称 HostName 产生告警的主机名 Instance 产生…

【古诗生成AI实战】之三——任务加载器与预处理器

本章内容属于数据处理阶段&#xff0c;将分别介绍任务加载器task和预处理器processor。 [1] 数据集 在深入探讨数据处理的具体步骤之前&#xff0c;让我们先了解一下我们将要使用的数据集的形式。 本项目采用的是七绝数据集&#xff0c;总计83072条古诗&#xff0c;其形式如下&…

大语言模型损失函数详解

我们可以把语言模型分为两类&#xff1a; 自动回归式语言模型&#xff1a;自动回归式语言模型在本质上是单向的&#xff0c;也就是说&#xff0c;它只沿着一个方向阅读句子。正向&#xff08;从左到右&#xff09;预测&#xff1b;反向&#xff08;从右到左&#xff09;预测。…

linux复习笔记04(小滴课堂)

软件安装rpm方式介绍&#xff1a; 先去挂载光盘&#xff1a; 要确保这是已连接状态。 我们查看到已经挂载成功了。 进到这个目录下。 我们可以看到这有很多rpm软件包。 man rpm: 可以看到很多参数&#xff0c;但是我们不需要全部掌握。 举例&#xff1a; 这就是告诉我们需要安…

2017年五一杯数学建模C题宜居城市问题值解题全过程文档及程序

2017年五一杯数学建模 C题 宜居城市问题 原题再现 城市宜居性是当前城市科学研究领域的热点议题之一&#xff0c;也是政府和城市居民密切关注的焦点。建设宜居城市已成为现阶段我国城市发展的重要目标,对提升城市居民生活质量、完善城市功能和提高城市运行效率具有重要意义。…

深信服超融合一体机提示:内存ECC

PS&#xff1a;此事件分享主要来源于季度巡检时发现的超融合一体机红灯闪烁异常&#xff0c;接入IPMI端口查看日志发现持续提示内存ECC&#xff1b; 因为是只有3.05这一天发现了有这个告警的提示&#xff0c;所以当时清除了日志以后重启了BMC服务就解决了&#xff1b;但是如果清…

bootstrap v5模板

bootstrap5模板代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Bootstrap 5 Templa…

【虚拟机】在VM中安装 CentOS 7

1.2.创建虚拟机 Centos7是比较常用的一个Linux发行版本&#xff0c;在国内的使用比例还是比较高的。 大家首先要下载一个Centos7的iso文件&#xff0c;我在资料中给大家准备了一个mini的版本&#xff0c;体积不到1G&#xff0c;推荐大家使用&#xff1a; 我们在VMware《主页》…

ctfshow刷题web入门--1--ljcsd

文章目录 ctf.show。信息搜集web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20。爆破。知识1.1 播种随机数生成器-mt_srand。参考web21--重点web22--做不出来web23web24web25web26web27web28。。。命令执行。知识1 绕过正则表达式…

Windows安装Python环境(V3.6)

文章目录 一&#xff1a;进入网址&#xff1a;https://www.python.org/downloads/ 二&#xff1a;执行安装包 默认C盘&#xff0c;选择自定义安装目录 记得勾选add python path 下面文件夹最好不要有 . 等特殊符号 可以创建 python36 如果安装失败Option可以选默认的&#x…

考研数据结构大题(要求能手写出对应代码)

1.栈的顺序存储定义 2.栈的链式存储定义&#xff1b;栈的单向链定义 栈的双向链定义 3.栈的增删改查操作。 4.队列的顺序存储定义 5.队列的链式存储定义&#xff1a;队列的单向链定义 队列的双向链定义 6.栈&#xff0c;队列&#xff0c;数组&#xff0c;图&#xff0c;树的增删…

Element-Plus 表格 el-table 如何支持分页多选

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

PCIE链路训练-状态机描述4

Recovery Recovery.RcvrLock &#xff08;1&#xff09;如果link是在8.0GT/s或以上的速率工作&#xff0c;那么rx只会认为当前lane获得Block alignment之后收到的TS0&#xff0c;TS1&#xff0c;TS2是有效的。如果进入当前状态是从L1或recovery.speed或L0s&#xff0c;获取Blo…