【SWT】自定义数据表格

article/2025/9/14 4:26:37

目的

使用SWT技术自定义数据表格,本文抛砖引玉,给出了SWT构建数据表格的基本思路和简单实现。更多特殊需求即表格功能实现待续……
在这里插入图片描述

思路

数据表格由表格头与表格体两边部分组成。
表格头部分是固定的,其字段右侧包含一个简单的表格工具–排序;
表格体部分重要用来展示数据,它需要支持滚动,本示例只实现了纵向滚动(横向滚动可参考纵向滚动自行完成)

技术方面。滚动可以使用 ScrolledComposite 滚动组件,数据表格布局使用 GridLayout 完成。

实现

在本例中,依然在编辑器中展示效果,具体步骤如下:

  • plugin.xml 中定义编辑器
      <!-- 编辑器-SWT自定义表格 --><editorclass="com.xzbd.editors.CustomTableEditor"default="false"extensions="ctb"icon="icons/20220417/chenggongtishi.png"id="com.xzbd.editor.CustomTableEditor"name="编辑器-SWT自定义表格"></editor>
  • 编辑器实现类
package com.xzbd.editors;import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;import com.xzbd.views.CustomTableEditorViewer;public class CustomTableEditor extends EditorPart {public static String ID = "com.xzbd.editors.CustomTableEditor";public boolean isDirty = false;private CustomTableEditorViewer viewer;@Overridepublic void doSave(IProgressMonitor monitor) {clearDirty();}@Overridepublic void doSaveAs() {}@Overridepublic void init(IEditorSite site, IEditorInput input) throws PartInitException {this.setSite(site);this.setInput(input);}@Overridepublic boolean isDirty() {return isDirty;}@Overridepublic boolean isSaveAsAllowed() {return false;}@Overridepublic void createPartControl(Composite parent) {viewer = new CustomTableEditorViewer(parent, this);}@Overridepublic void setFocus() {}/*** 转换编辑器状态* * @param isDirty*/public void changeDirtyState(boolean isDirty) {this.isDirty = isDirty;firePropertyChange(PROP_DIRTY);}public void toDirty() {changeDirtyState(true);}public void clearDirty() {changeDirtyState(false);}
}
  • 视图实现类
package com.xzbd.views;import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;import com.xzbd.editors.CustomTableEditor;
import com.xzbd.utils.LayoutUtil;
import com.xzbd.utils.SWTResourceManager;/*** * SWT-自定义数据表编辑器视图**/
public class CustomTableEditorViewer {private CustomTableEditor editor;private Composite parent;public CustomTableEditorViewer(Composite parent, CustomTableEditor editor) {this.parent = parent;// 缓存 EditorsetEditor(editor);// 绘制UIbuildPageUI();}// 创建UIprivate void buildPageUI() {// 设置 parent 布局parent.setLayout(new FillLayout());Composite contaniner = new Composite(parent, SWT.NONE);contaniner.setLayout(new GridLayout());Label descLabel  = new Label(contaniner, SWT.NONE);descLabel.setText("这个表格是完全自定义的,虽然比较简单,但可以作为自定义表格原型");Label sepratorLine = new Label(contaniner, SWT.SEPARATOR | SWT.HORIZONTAL);sepratorLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));Composite header = new Composite(contaniner, SWT.NONE);header.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));header.setLayout(new GridLayout(4, false));for (int j = 0; j < 4; j++) {Composite col = new Composite(header, SWT.NONE);col.setLayout(new GridLayout(2, false));col.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));Label label = new Label(col, SWT.None);label.setText("列-00" + j + 1);Composite tools = new Composite(col, SWT.NONE);tools.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));tools.setLayout(LayoutUtil.clearMarin(new GridLayout()));Label asc = new Label(tools, SWT.NONE);asc.setImage(SWTResourceManager.getImage(CustomTableEditorViewer.class, "/icons/sort-up.png"));Boolean[] check = { false };Boolean[] line = { false };asc.addPaintListener(e -> {if (line[0] || check[0]) {GC gc = e.gc;Rectangle bounds = asc.getBounds();
//					gc.setForeground(ColorConstant.MAIN_BLUE);gc.drawRectangle(0, 0, bounds.width - 1, bounds.height - 1);gc.dispose();}});asc.addListener(SWT.MouseEnter, e -> {line[0] = true;asc.redraw();});asc.addListener(SWT.MouseExit, e -> {if (check[0]) {return;}line[0] = false;asc.redraw();});asc.addListener(SWT.MouseDown, e -> {check[0] = !check[0];asc.redraw();});Label desc = new Label(tools, SWT.PUSH);desc.setImage(SWTResourceManager.getImage(CustomTableEditorViewer.class, "/icons/sort-down.png"));}Label seprator = new Label(contaniner, SWT.SEPARATOR | SWT.HORIZONTAL);seprator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));Composite scContaniner = new Composite(contaniner, SWT.NONE);scContaniner.setLayoutData(new GridData(GridData.FILL_BOTH));scContaniner.setLayout(new FillLayout());// 滑动面板ScrolledComposite sc = new ScrolledComposite(scContaniner, SWT.H_SCROLL | SWT.V_SCROLL);Composite content = new Composite(sc, SWT.None);content.setLayout(new GridLayout());
//		content.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));Color activeColor = SWTResourceManager.getColor(SWT.COLOR_GRAY);Listener activeListener = e -> {Control widget = (Control) e.widget;widget.setBackground(activeColor);};Listener defaultListener = e -> {Control widget = (Control) e.widget;widget.setBackground(null);};for (int i = 0; i < 100; i++) {Composite row = new Composite(content, SWT.NONE);GridData gridData = new GridData(GridData.FILL_HORIZONTAL);row.setLayoutData(gridData);row.setLayout(new GridLayout(4, false));for (int j = 0; j < 4; j++) {Label label = new Label(row, SWT.None);label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));label.setText(i + "行" + j + "列 : " + i + " - " + j);// 事件绑定label.addListener(SWT.MouseEnter, activeListener);label.addListener(SWT.MouseExit, defaultListener);}Label rowSeprator = new Label(content, SWT.SEPARATOR | SWT.HORIZONTAL);rowSeprator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));// 事件绑定row.addListener(SWT.MouseEnter, activeListener);row.addListener(SWT.MouseExit, defaultListener);}sc.setExpandHorizontal(true);sc.setExpandVertical(true);sc.addControlListener(ControlListener.controlResizedAdapter(e -> {Rectangle r = sc.getClientArea();sc.setMinSize(content.computeSize(r.width, SWT.DEFAULT));}));// 设置滑动内容sc.setContent(content);content.setSize(content.computeSize(SWT.DEFAULT, SWT.DEFAULT));// sc 重新绘制,否则不显示 滑动内容sc.layout();}public CustomTableEditor getEditor() {return editor;}public void setEditor(CustomTableEditor editor) {this.editor = editor;}private void addDirtyListener(Widget com) {com.addListener(SWT.Modify, e->{editor.toDirty();});}}

其中使用到的工具类,请参考项目中相关源码,项目地址:https://gitee.com/xzbd/epx

效果

在这里插入图片描述

总结

本文使用 SWT 中的 ScrolledCompositeGridLayout 和 SWT 事件实现了一个简单的数据表格实现,表格功能相对比较简单,但有足够的启发性,读者可据此实现更复杂的表格。

  • 项目地址:https://gitee.com/xzbd/epx

  • SWT测试实现


import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;import com.xzbd.swt01.core.ColorConstant;
import com.xzbd.swt01.utils.LayoutUtil;
import com.xzbd.swt01.utils.SWTResourceManager;
import com.xzbd.swt01.utils.SWTTools;public class ScrolledCompositeTest {public static void main(String[] args) {final Display display = new Display();final Shell shell = new Shell(display);shell.setText("SWT 自定义数据表");shell.setLayout(new FillLayout());Composite contaniner = new Composite(shell, SWT.NONE);contaniner.setLayout(new GridLayout());Composite header = new Composite(contaniner, SWT.NONE);header.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));header.setLayout(new GridLayout(4, false));for (int j = 0; j < 4; j++) {Composite col = new Composite(header, SWT.NONE);col.setLayout(new GridLayout(2, false));col.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));Label label = new Label(col, SWT.None);label.setText("列-00" + j + 1);Composite tools = new Composite(col, SWT.NONE);tools.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));tools.setLayout(LayoutUtil.clearMarin(new GridLayout()));Label asc = new Label(tools, SWT.NONE);asc.setImage(SWTResourceManager.getImage(ScrolledCompositeTest.class, "/icons/sort-up.png"));Boolean[] check = { false };Boolean[] line = { false };asc.addPaintListener(e -> {if (line[0] || check[0]) {GC gc = e.gc;Rectangle bounds = asc.getBounds();
//					gc.setForeground(ColorConstant.MAIN_BLUE);gc.drawRectangle(0, 0, bounds.width - 1, bounds.height - 1);gc.dispose();}});asc.addListener(SWT.MouseEnter, e -> {line[0] = true;asc.redraw();});asc.addListener(SWT.MouseExit, e -> {if (check[0]) {return;}line[0] = false;asc.redraw();});asc.addListener(SWT.MouseDown, e -> {check[0] = !check[0];asc.redraw();});Label desc = new Label(tools, SWT.PUSH);desc.setImage(SWTResourceManager.getImage(ScrolledCompositeTest.class, "/icons/sort-down.png"));}Label seprator = new Label(contaniner, SWT.SEPARATOR | SWT.HORIZONTAL);seprator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));Composite scContaniner = new Composite(contaniner, SWT.NONE);scContaniner.setLayoutData(new GridData(GridData.FILL_BOTH));scContaniner.setLayout(new FillLayout());// 滑动面板ScrolledComposite sc = new ScrolledComposite(scContaniner, SWT.H_SCROLL | SWT.V_SCROLL);Composite content = new Composite(sc, SWT.None);content.setLayout(new GridLayout());
//		content.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));Color activeColor = SWTResourceManager.getColor(SWT.COLOR_GRAY);Listener activeListener = e -> {Control widget = (Control) e.widget;widget.setBackground(activeColor);};Listener defaultListener = e -> {Control widget = (Control) e.widget;widget.setBackground(null);};for (int i = 0; i < 100; i++) {Composite row = new Composite(content, SWT.NONE);GridData gridData = new GridData(GridData.FILL_HORIZONTAL);row.setLayoutData(gridData);row.setLayout(new GridLayout(4, false));for (int j = 0; j < 4; j++) {Label label = new Label(row, SWT.None);label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));label.setText(i + "行" + j + "列 : " + i + " - " + j);// 事件绑定label.addListener(SWT.MouseEnter, activeListener);label.addListener(SWT.MouseExit, defaultListener);}Label rowSeprator = new Label(content, SWT.SEPARATOR | SWT.HORIZONTAL);rowSeprator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));// 事件绑定row.addListener(SWT.MouseEnter, activeListener);row.addListener(SWT.MouseExit, defaultListener);}sc.setExpandHorizontal(true);sc.setExpandVertical(true);sc.addControlListener(ControlListener.controlResizedAdapter(e -> {Rectangle r = sc.getClientArea();sc.setMinSize(content.computeSize(r.width, SWT.DEFAULT));}));// 设置滑动内容sc.setContent(content);content.setSize(content.computeSize(SWT.DEFAULT, SWT.DEFAULT));// sc 重新绘制,否则不显示 滑动内容sc.layout();shell.setSize(800, 720);shell.open();while (!shell.isDisposed()) {if (!display.readAndDispatch())display.sleep();}display.dispose();}
}

http://chatgpt.dhexx.cn/article/1WEQGRGr.shtml

相关文章

【SWT】Lable 文字折行

目标 当Label 中的文字过多时&#xff0c;使得文字折行显示。 效果如图所示&#xff1a; 分析与实践 Label 自带样式是一行显示所有信息。当一行显示不下时&#xff0c;超出部分会被隐藏掉&#xff0c;当Label有足够长度时再将其展示出来。Label这种处理超出部分的方式很粗…

java swt 几种布局_实战SWT布局

fortune 阅读(577) 评论(0) 编辑 收藏 所属分类: java技术 标准的SWT布局类FillLayout&#xff1a;在容器中以相同的大小单行或单列的排列组件 RowLayout&#xff1a;以单行或多行的方式使用几个选项(fill,wrap,spacing,justify,type)定制组件的排列方式 GridLayout&#xff…

【SWT】内容分割线

目标 SWT 容器中画横向直线或竖向直线将容器中的内容分割开来。本文介绍了官方的两个示例&#xff0c;效果图见实践部分。 分析 SWT 中至少由两种方法画直线&#xff08;横向或纵向&#xff09; SWT 中的GC可以画直线 这种方法最容易想到&#xff0c;但实现起来比较麻烦&a…

SWT

strock width transform,全称笔画宽度变换&#xff0c;是一种局部的图像算子用于提取字符&#xff08;letter&#xff09;的笔画宽度作为图像特征。算法步骤如下&#xff1a; 分成三个部分&#xff1a; - 用canny算子计算梯度及方向 - SWT提取笔画宽度得到字符候选区域&am…

eclipse下搭建SWT图形界面开发环境

什么是SWT 参考&#xff1a;http://www.cppblog.com/baby-fly/archive/2009/10/20/99008.html 用java的人一定都知道AWT和Swing&#xff0c;而SWT(Standard Widget Toolkit)则是由Eclipse项目组织开发的一套完整的图形界面开发包&#xff0c;虽然当初仅仅是IBM为了编写Eclipse的…

SWT布局(Layouts)

每种类型操作系统对屏幕的定义不一样&#xff0c;在开发跨平台应用软件时&#xff0c;我们一般都会使用布局&#xff08;Layout&#xff09;来管理复合控件&#xff08;Composite&#xff09;中子控件的位置和大小。通过布局&#xff0c;程序员可以充分展示那些埋没已久的艺术细…

SWT简介

SWT简介 1. 为什么要使用SWT?  SWT是一个IBM开发的跨平台GUI开发工具包。在SWT之前&#xff0c;Sun已经提供了一个跨平台GUI开发工具包AWT (Abstract Windowing Toolkit)。虽然AWT框架也使用的是原生窗口部件(native widgets)&#xff0c;但是它一直未能突破LCD问题。LCD问…

[转]实时股票数据接口大全

from: http://www.21andy.com/blog/20090530/1313.html 实时股票数据接口大全 股票数据的获取目前有如下两种方法可以获取:1. http/javascript接口取数据2. web-service接口 1.http/javascript接口取数据 1.1Sina股票数据接口 以大秦铁路&#xff08;股票代码&#xff1a;…

股票数据在线获取

推荐&#xff1a;使用如下地址注册tushare并分享此链接。 https://tushare.pro/register?reg133232 分享此链接&#xff0c;注册tushare. 以前是使用tushare等下载保存到本地数据库后进行计算分析。 现在不想维护本地数据库&#xff0c;想使用时直接在线获取数据。经查找如…

获取股票实时交易数据的方法

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴! 获取股票实时交易数据的方法 注:本文为原创文章,转载时请注明转载地址。炒股有一段时间…

实时股票数据接口 (转,以防有用)

&#xfeff;&#xfeff; http://blog.sina.com.cn/s/blog_510844b70102wrvf.html 实时股票数据接口 股票数据的获取目前有如下两种方法可以获取: 1. http/javascript接口取数据 2. web-service接口 1.http/javascript接口取数据1.1Sina股票数据接口 以大秦铁路&#xff08;…

获取股票数据【实时更新股票数据、创建你的股票数据】、计算交易指标【买入、卖出信号、计算持仓收益、计算累计收益率】

在上一次获取股票数据【使用JQData查询行情数据、财务指标、估值指标】学习了使用JQData来查询股票相关数据&#xff0c; 这次则开始一点点构建咱们的量化交易系统了。 量化交易平台功能模块了解&#xff1a; 对于一个量化交易平台&#xff0c;它主要包含如下功能模块&#x…

使用Python获取股票实时数据和历史数据

决定新建一个专栏&#xff0c;专门研究股票数据的API接口。 由于不是混金融领域的人&#xff0c;百度调研了一会儿&#xff0c;没有找到合适的大公司维护的API接口。 yahoo-finance PyPI 这玩意架梯子都访问不到数据&#xff0c;不知道乍回事。许多大牛维护的pip包都是基于这…

Tushare免费获取股票数据:实时数据,历史数据,行情数据

一 操作手册 引导用户顺利开始使用Tushare Pro数据&#xff0c;以下步骤将带您开始Tushare数据之旅&#xff1a; 用户注册登录后可调用数据&#xff1a;https://tushare.pro/register?reg399205 二 如何获取TOKEN凭证 1、登录成功后&#xff0c;点击右上角->个人主页 2、…

如何用 Python 获取实时的股票数据?

这个我会&#xff01;先上图 这篇回答中&#xff0c;我将向你展示两种不同的代码版本&#xff08;加强版和一般版&#xff09; 代码运行环境说明&#xff08;非常重要&#xff09; Python版本要求 Python 3 需要安装的库 efinance 库的安装方法是&#xff1a;打开 cmd&#x…

怎么用Python获取股票的实时数据?

学习目标&#xff1a; 应用industry实现行业股票列表的获取应用history_bars实现股票合约历史行情数据获取应用get_fundamentals实现股票基本面数据获取使用query的过滤条件完成股票数据的过滤应用scheduler定时器实现股票数据定期获取 1、 数据接口种类 获取指定行业、板块…

SAP UI5 Focus related

tap, keydown, keypresssap.ui.core.FocusHandlersap.ca.scfld.md.app.CommonHeaderFooterHelperevent new jQuery.Event(originalEvent);focusin, activate, blur, focusout, sapfocusleaveoElement._handleEvent(oEvent); 要获取更多Jerry的原创…

Consider defining a bean of type ‘com.qf.user.consumer.feign.api.UserFeignAPI‘ in your configuration

Consider defining a bean of type ‘com.qf.user.consumer.feign.api.UserFeignAPI’ in your configuration… 引导类加注解EnableFeignClients

Prime算法 C++实现

Prime算法 算法介绍&#xff1a; 课本实现方法&#xff1a; 先从最小堆说起&#xff08;heap&#xff09;&#xff1a;任一结点的关键码均小于或等于它的左右子女的关键码&#xff0c;位于堆顶&#xff08;即完全二叉树的根结点的位置&#xff09;的结点的关键码是整个集合中最…

【数学】Prime-Factor Prime

Prime-Factor Prime 题目描述 A positive integer is called a "prime-factor prime" when the number of its prime factors is prime. For example, 12 is a prime-factor prime because the number of prime factors of 12223 is 3, which is prime. On the other…