SWT高级主题第二部分

2024-02-17 01:38
文章标签 高级 第二 部分 主题 swt

本文主要是介绍SWT高级主题第二部分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SWT高级主题(Standard Widget Toolkit)第二部分

SWT基础中,我们简要的了解了SWT的产生背景,开发SWT应用程序的基本要求以及基本的SWT组件以及部分事件监听器。本部分内容将介绍一些高级的组件,布局管理器等高级主题。

高级组件:

图形:SWT提供了丰富的图形功能。这些功能大部分以GC类为核心。

图形上下文(Graphics Context,或者GC)类用来进行绘图和显示图片。它提供了大量的基本的图形功能,包括如下的功能:

绘画或者填充矩形,圆形,线,多边形或者文本。

设置背景色或者前景色

设置clipping区域

    将某个区域拷贝到图片或者同一组件的其他区域

    显示图片

    设置或者获取文本/字体属性

注:几乎可以为所有的组件获取GC,然后在组件上面进行绘图。本文中以Canvas为例进行说明。

可以通过标准的构造方法创建Canvas对象,然后设置其大小和位置。

Canvas canvas = new Canvas(shell, SWT.BORDER);

canvas.setSize(300,300);

canvas.setLocation(20, 20);

接下来需要打开shell,这是很关键的一步,因为如果shell没有打开的话,那么在Canvas上绘制的图形不会被显示。

shell.open();

为特定的组件获取GC的方法如下:

GC gc = new GC(canvas);

此时GC只应用于Canvas对象,任何绘图操作都会反映到canvas上面。也就是说,如果绘制的图形超过了canvas的界限,那么不会被显示。最基本的任务就是绘制和填充矩形。可以通过drawRectanglefillRectangle来实现。drawRectangle使用当前的前景色(黑色)来绘制矩形,参数xy表示矩形的坐标,然后是矩形的宽和高。

gc.drawRectangle(3, 5, 20, 25);

fillRectangle方法和其类似,只是填充的颜色是当前的背景颜色(灰色)。由于没有设置背景颜色,所以绘制填充后的矩形不可见。

获取颜色的最简单的办法就是使用Display类的getSystemColor方法,以SWT的颜色常量作为参数。

Color blue = display.getSystemColor(SWT.COLOR_BLUE);

Color red = display.getSystemColor(SWT.COLOR_RED);

也可以手动创建Color对象。

获取颜色之后就可以设置GC的前景色和背景色了。注:fill方法还可以用于填充OvalPolygon。对于Oval来说,指定的参数是圆形的外切圆,对于多边形来说,int数组中的值是点的坐标。

gc.setForeground(blue);

gc.drawLine(80, 20, 100, 80);

gc.drawOval(40, 40, 10, 10);

gc.drawPolygon(new int[] {100, 100, 120, 120, 140, 100});//(100,100),(120,120),(140,100),是一个三角形

注:填充矩形和绘制矩形的大小是不一样的,填充矩形的大小要比绘制矩形小一行和一列。

另一个比较有用的功能就是绘制文本,通过drawString方法来完成,并且可以指定文本的坐标。另外,可以指定文本是否透明。

同时,还可以设置clipping区域,这样绘制操作就被限制在组件的特定的clipping window中。可以通过setClipping方法来完成。下面的代码clip园的特定的区域。

gc.setClipping(40, 60, 40, 40);

gc.fillOval(30, 50, 30, 25);

 

SWT库中提供了非常多的图形类使用在操作系统级分配的资源,所以需要程序员来进行显式的释放。所以在上面的代码中,当shell被关闭的时候,GC必须被释放:

gc.dispose();

这行代码可以放在绘制完成的最后一行。用完即释放图形对象是一个好的原则。以下的对象经常需要显式的释放:ColorImageFonts。在上例中,并没有显式释放Colors对象bluered,这是由于它们是预分配的系统颜色。一个通用的原则是如果是你创建的,那么你负责释放,否则的话,不需要进行释放。

GC类还有很多方法,例如设置线条的宽度,获取文本的字体,拷贝组件的区域等等,详细内容,请参考SWTjavadocs

repaint上面的例子中还有一个缺点,就是当窗口被最小化,或者拖动窗口,使图形被挡住之后,canvas的一部分就被挡住了,即原有的图形不能显示。这是由于只是在程序开始的时候进行了图形的绘制,而没有进行重画(repaint)

为了确定canvas什么时候需要被重画,必须追加PaintListener给它。下面的代码将重画矩形,无论是否被遮挡。

Canvas canvas = new Canvas(shell, SWT.BORDER);

canvas.setSize(150, 150);

canvas.setLocation(20, 20);

canvas.addPaintListener(new PaintListener() {

  public void paintControl(PaintEvent e) {

  GC gc =e.gc;

    gc.drawRectangle(3, 5, 20, 25);

 }

});

 

shell.open();

PaintListener会检测到canvas被重画,然后执行paintControl方法来绘制矩形。注:shell.open方法出现在监听器后面,因为初始的绘制是在shell打开的时候被完成的。如果将PaintListener添加在shell.open后面,那么除非canvas被挡住,或者被最小化,否则矩形不会被绘制。此时,我们从PaintEvent对象中获取gc对象,所以不需要释放它(没有使用new去创建就不需要去释放它)

 

文字和颜色SWT中两个重要的图形组件就是FontColor。同样,也是由操作系统分配的,使用完之后也需要释放,和GC以及Display是一样的。可以直接在shell上进行绘制,而不一定必须使用Canvas

shell.addPaintListener(new PaintListener() {

              public void paintControl(PaintEvent e) {

                            GC gc = e.gc;

                            Display d = e.widget.getDisplay();//从其他对象获取,不需要显示释放

                            Color color = new Color(d, 120, 42, 105);//手动创建Color对象,需要显式释放

                            gc.setForeground(color);

                            Font font = new Font(d, "Arial", 24, SWT.BOLD | SWT.ITALIC);//手动创建Font对象,需要显示释放

                            gc.setFont(font);

                            gc.drawString("Text", 20, 20);

                            color.dispose();

                            font.dispose();

              }

});

shell.open();

图像Image允许程序加载,绘制,显示图像。支持的图片包括BMPICOJPEGGIFPNG。下面的简单的例子中,将从文件中加载图片,然后将其绘制在shell上。将display对象作为Device参数传递给Image构造方法,以及image的全路径名作为第二个参数。然后必须打开shell以便显示图片。如果颠倒这两个顺序,那么将会有一个延迟显示,因为加载图片需要一定的时间。

Image img = new Image(display, "EclipseBannerPic.jpg");

shell.open();

现在需要使用GC对象,来绘制图像,通过GC实例的drawImage方法。

GC gc = new GC(shell);

gc.drawImage(img, 0, 0);

结束之后,需要释放图像资源。因为图像属于重量级对象,并且要求系统资源。有些操作系统限制同时可以访问的图片的数量。同样,如果最小化或者拖拽窗口,可能导致图片被部分挡住或者不能显示。

JAR文件:如果要将程序和图片放到JAR文件中,那么必须修改程序以确保图片能够正常加载。因为此时图片在JAR文件中,而Image的构造器无法通过文件系统来直接访问。

InputStream is = getClass().getResourceAsStream("EclipseBannerPic.jpg");

Image img = new Image(display, is);

如果image位于JAR文件中的目录中,那么应该使getResourceAsStream(“images/EclipseBannerPic.jpg”)来加载图片。

Image(Device device, int width, int height)创建一个指定宽度和高度的空白图片。

Image(Device device, Rectangle bounds)同上,只是宽度和高度是由Rectangle对象指定的。

使用空白图片的目的用途是在屏幕外绘制图片,然后使用GC.drawImage()方法来绘制整个图片到屏幕,这样可以防止闪烁,因为直接在屏幕上绘制会很慢。

Image img = new Image(display, 50,50);    

shell.open();

GC imgGC = new GC(img);

imgGC.drawLine(10, 20, 30, 40);

GC shellGC = new GC(shell);

shellGC.drawImage(img, 0, 0);

将图片应用于其他组件的方法是首先创建对象,然后调用组件的setImage方法。

Image(Device device, Image srcImage, int flag)用来创建重复的图片,通过flag来进行一些修改,flag可以是SWT.IMAGE_COPY, SWT.IMAGE_GRAY, and SWT.IMAGE_DISABLE

Image original = new Image(display, "EclipseBannerPic.jpg");

Image copy = new Image(display, original, SWT.IMAGE_COPY);

Image gray = new Image(display, original, SWT.IMAGE_GRAY);

Image disable = new Image(display, original, SWT.IMAGE_DISABLE);

copy图像是原始的图像的拷贝,gray图像是原始图像的灰色版本,disable图像是disabled样式的原始图像。

b1.setImage(copy);

b2.setImage(gray);

b3.setImage(disable);

当为按钮设置图片之后,如果再次调用setText方法,那么文本会取代图片。标准的按钮不能同时显示文本和图像。还可以为菜单项,工具栏按钮,CoolBar上的按钮,树结构上的节点,Table中的TableItem等添加图像。

Splash屏幕:创建简单的闪烁屏幕。基本的技术就是使用SWT.NO_TRIM来创建Shell对象。这将产生一个没有窗口边框的shell,然后为其添加一个图片,来创建启动图片。然后让后台线程停止几秒钟,然后释放所有的资源,然后再运行实际的程序。

首先还是创建DisplayShell,只是Shell的样式设置为SWT.NO_TRIM。然后加载要splash的图片。可以通过Image来获取ImageData对象,来获取图片的实际的宽和高。

Display display = new Display();

Shell shell = new Shell(display, SWT.NO_TRIM);

Image image = new Image(display, "splash.jpg");

ImageData imdata = image.getImageData();

shell.setSize(imdata.width, imdata.height);

然后splash的时候将图片放在屏幕中央。

Rectangle r = display.getBounds();

int shellX = (r.width - imdata.width) / 2;

int shellY = (r.height - imdata.height) / 2;

shell.setLocation(shellX, shellY);

然后打开shell,并绘制图片。

shell.open();

GC gc = new GC(shell);

gc.drawImage(image, 0, 0);

然后让程序停止几秒种:

final int SLEEP_TIME = 4000;  

try {

 Thread.sleep(SLEEP_TIME);

} catch (InterruptedException e) {

}

然后释放所有的资源。

image.dispose();

shell.dispose();

display.dispose();

此时运行程序,会发现在屏幕中央显示图片,然后停留4秒,然后程序退出。本例只是简要介绍splash屏幕,实际的splash屏幕的作用是进行加载工作时显示进度条之类的功能。

 

MessageBox: MessageBox用于提示或者警告用户。MessageBox可以显示消息,图标,以及提供可选的按钮。

MessageBox messageBox = new MessageBox(shell, SWT.ICON_QUESTION | 

       SWT.YES | SWT.NO | SWT.CANCEL);

messageBox.setMessage("Do you like apples?");

可以选择的类型样式包括:ICON_ERROR,ICON_INFORMATION,ICON_QUESTION,ICON_WARNING,ICON_WORKING.可选的响应样式包括:OK,OK|CANCEL,YES|NO,YES|NO|CANCEL,RETRY|CANCEL,ABORT|RETRY|CANCEL。还可以通过setText为消息对话框提供标题。通过open方法打开消息对话框。

open方法返回一个整数,表示用户的响应:

response = messageBox.open();

switch (response) {

case SWT.YES:

              System.out.println("Yes, the user likes apples.");

              break;

case SWT.NO:

              System.out.println("No, the user does not like apples.");

              break;

case SWT.CANCEL:

              System.out.println("The user cancelled.");

              break;

}

ColorDialogColorDialog提供了颜色选择器。

 ColorDialog colorDialog1 = new ColorDialog(shell);

 colorDialog1.setText("ColorDialog Demo");

 colorDialog1.setRGB(new RGB(255,0,0));

其中setRGB方法设置默认选中的颜色。

通过open方法显示对话框,open方法返回一个RGB对象,该对象为用户选择的颜色。

RGB selectedColor = colorDialog1.open();

DirectoryDialog:文件夹对话框用于浏览和选择文件夹。

DirectoryDialog directoryDialog = new DirectoryDialog(shell);

directoryDialog.setText("DirectoryDialog Demo");

directoryDialog.setFilterPath("C:/Program Files");

String selectedDirectory = directoryDialog.open();

DirectoryDialogColorDialog非常类似。

FileDialog:文件对话框用于选择文件。

String[] filterExtensions = { "*.txt", "*.doc", "*.*" };

FileDialog fileDialog = new FileDialog(shell, SWT.OPEN);//可选的样式有SAVE,OPEN,MULTI

fileDialog.setText("FileDialog Demo");

fileDialog.setFilterPath("C:/");//设置过滤的路径

fileDialog.setFilterExtensions(filterExtensions);//设置过滤的文件类型

String selectedFile = fileDialog.open();//返回选中的文件

FontDialog:字体选择对话框。

FontData defaultFontData = new FontData("Courier", 12, SWT.ITALIC);

FontDialog fontDialog = new FontDialog(shell, SWT.NONE);

fontDialog.setText("FontDialog Demo");

fontDialog.setRGB(new RGB(0, 0, 255));//设置文字颜色

FontData fontData = fontDialog.open();//获取选择的字体数据,字体名,样式(粗,斜...),颜色,字号等等。

PrintDialog:打印机对话框,允许用户选择打印机并进行打印操作。

Input对话框Input对话框在SWT中并没有提供,但是可以手动创建,首先继承Dialog类,然后在面板上放置文本框和对应的按钮,添加open方法,方法返回输入的值以及选择的按钮(可以通过封装成一个Data类来完成)

DnD(DragAndDrop):拖放功能允许用户快速的在应用程序之间传输数据。例如从桌面可以将文件拖放到我的文档中。首先必须导入所有与拖放有关的类:

import org.eclipse.swt.dnd.*;

* class org.eclipse.swt.dnd.Clipboard

* class org.eclipse.swt.dnd.DND

* class org.eclipse.swt.dnd.DragSourceAdapter (implements org.eclipse.swt.dnd.DragSourceListener)

      o class org.eclipse.swt.dnd.DragSourceEffect

            + class org.eclipse.swt.dnd.TableDragSourceEffect

            + class org.eclipse.swt.dnd.TreeDragSourceEffect

* class org.eclipse.swt.dnd.DropTargetAdapter (implements org.eclipse.swt.dnd.DropTargetListener)

      o class org.eclipse.swt.dnd.DropTargetEffect

            + class org.eclipse.swt.dnd.TableDropTargetEffect

            + class org.eclipse.swt.dnd.TreeDropTargetEffect

* class java.util.EventObject (implements java.io.Serializable)

      o class org.eclipse.swt.internal.SWTEventObject

            + class org.eclipse.swt.events.TypedEvent

                  # class org.eclipse.swt.dnd.DragSourceEvent

                  # class org.eclipse.swt.dnd.DropTargetEvent

* class org.eclipse.swt.dnd.Transfer

      o class org.eclipse.swt.dnd.ByteArrayTransfer

            + class org.eclipse.swt.dnd.FileTransfer

            + class org.eclipse.swt.dnd.HTMLTransfer

            + class org.eclipse.swt.dnd.ImageTransfer

            + class org.eclipse.swt.dnd.RTFTransfer

            + class org.eclipse.swt.dnd.TextTransfer

            + class org.eclipse.swt.dnd.URLTransfer

* class org.eclipse.swt.dnd.TransferData

* class org.eclipse.swt.widgets.Widget

      o class org.eclipse.swt.dnd.DragSource

      o class org.eclipse.swt.dnd.DropTarget

为了实现拖放功能,必须指定拖放源与拖放目标。下面的例子中使用标签作为拖放源

lblSource = new Label(shell, SWT.BORDER);

lblSource.setSize(200, 50);

lblSource.setLocation(50, 50);

lblSource.setText("This is the source label");

然后定义传输类型,可用的类型包括TextTransfer,RTFTransfer,FileTransfer,本例只用来传输纯文本,所以只适用TextTransfer

Transfer[] types = new Transfer[] { TextTransfer.getInstance() };

接下来需要定义在拖放源上可以执行的操作:DROP_MOVE,DROP_COPY,DROP_LINK.

DROP_COPY: a copy of the data in the drag source is added to the drop target.

DROP_,MOVE:a copy of the data is added to the drop target and the original data is removed from the drag source.

DROP_LINK:the drop target makes a link to the data in the drag source.

int operations = DND.DROP_MOVE | DND.DROP_COPY;

然后创建DragSource对象:

DragSource source = new DragSource (lblSource, operations);

source.setTransfer(types);

接下来指定目标控件,这里也使用一个标签,然后创建DragTarget类,并指定操作和传输类型。

lblTarget = new Label(shell, SWT.BORDER);

lblTarget.setSize(200,50);

lblTarget.setLocation(50,150);

lblTarget.setText("This is the destination label");

 

DropTarget target = new DropTarget(lblTarget, operations);

target.setTransfer(types);

为了在用户开始拖拽文本时获取该事件,必须为source追加DragSourceListener,这里使用DragSourceAdapter

source.addDragListener(new DragSourceAdapter() {

              public void dragStart(DragSourceEvent event) {

                            if (lblSource.getText().length() == 0) {

                                          event.doit = false;

                            }

              };

 

              public void dragSetData(DragSourceEvent event) {

                            if (TextTransfer.getInstance().isSupportedType(event.dataType)) {

                                          event.data = lblSource.getText();

                            }

              }

 

              public void dragFinished(DragSourceEvent event) {

                            if (event.detail == DND.DROP_MOVE)

                                          lblSource.setText("");

              }

});

dragStart方法在用户开始拖拽组件时被触发,应用程序可以决定是否执行拖放操作,本例中,如果lable的文字为空,则不执行该操作。dragSetData方法当用户将数据放在目标上时被触发,并且必须提供被放置的数据。这个方法必须支持由setTransfer指定的所有的数据传输类型。dragFinished方法在拖放完成或者放弃时执行。用于执行清理工作。

为了确保目标接受到拖放事件,也需要追加DropTargetListener

target.addDropListener(new DropTargetAdapter() {

              public void drop(DropTargetEvent event) {

                            if (event.data == null) {

                                          event.detail = DND.DROP_NONE;

                                          return;

                            }

                            lblTarget.setText((String) event.data);

              }

});

ClipboardClipboard提供了从一个应用程序向另一个程序或者同一个程序中传输数据的机制。

参考资料:

SWT主页:http://www.eclipse.org/swt

SWT小例子:http://www.eclipse.org/swt/snippets/

SWT例子:http://www.eclipse.org/swt/examples.php

SWT文档:http://www.eclipse.org/swt/docs.php

Getting Started with Eclipse 2.1 and the SWThttp://www.cs.umanitoba.ca/~eclipse/

SWT Javadocshttp://help.eclipse.org/ganymede/index.jsp -> Platform Plug-in Developer Guide - > Reference -> API Reference -> org.eclipse.swt.*

这篇关于SWT高级主题第二部分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/716307

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

项目实战系列三: 家居购项目 第四部分

购物车 🌳购物车🍆显示购物车🍆更改商品数量🍆清空购物车&&删除商品 🌳生成订单 🌳购物车 需求分析 1.会员登陆后, 可以添加家居到购物车 2.完成购物车的设计和实现 3.每添加一个家居,购物车的数量+1, 并显示 程序框架图 1.新建src/com/zzw/furns/entity/CartItem.java, CartItem-家居项模型 /***

Mysql高级篇(中)——索引介绍

Mysql高级篇(中)——索引介绍 一、索引本质二、索引优缺点三、索引分类(1)按数据结构分类(2)按功能分类(3) 按存储引擎分类(4) 按存储方式分类(5) 按使用方式分类 四、 索引基本语法(1)创建索引(2)查看索引(3)删除索引(4)ALTER 关键字创建/删除索引 五、适合创建索引的情况思考题 六、不适合创建索引的情况 一、索引本质 索引本质 是 一种数据结构,它用