`

SWT/JFace一些经典技术与算法

阅读更多
转自:http://blog.csdn.net/jackkp_Catus/archive/2007/09/17/1787698.aspx
1。图形拖动

图形的拖动就是图形选中的图形跟着鼠标的移动而不断的相应改变位置,这是在图形界面中是经常见的一个操作,但是在SWT/JFace中来实现却不是意见容易的事。在这里底板是一个Canvas,图形也是建立在一个Canvas上,当然位置的改变是建立在鼠标移动的监听下.

1、首先建立几个变量:

Int oldx = -1;// 拖动前的x

Int oldy = -1;//拖动前的y

Int xoffset = 0; //拖动后的偏移量x

Int yoffset =0 ;// 拖动后的偏移量y;

Int x,y;// 拖动后图形应该在的位置

2、 在第一次拖动时,取得oldx和oldy

if(oldX==-1&&oldY==-1){

       oldX=e.x;

       oldY=e.y;

}

3、 获得偏移量

xoffset=e.x-oldX;

yoffset=e.y-oldY;

4、得到新的图形位置

x=ca.getBounds().x+xoffset;

y=ca.getBounds().y+yoffset;

5、 重新设置图形的位置

ca.setBounds(x,y,ca.getSize.x,ca.getSize.y)

   这样就实现了图形的拖动,不仅算法简洁,而且效果也很好。当然为了更好的效果,还可以加上边界控制,以保证图形不超出边界
2。图形连线与画线
2.1 图形的连线

整个SWT中只有一个类GC与之有关,就是在一个画板上画线,这样简单的线根本无法满足复杂连线的要求,要实现比较复杂的图形间的连线,我们使用了eclipse的另一个插件——draw2D,在draw2D的图形中比较容易实现连线,但是draw2D中连线的图形都是IFigure类的图形,否则就无法实现draw2D内的连线,然而我们的图形使用SWT设计的,因此出现了两者的兼容问题。因此我们自行设计了综合使用两者来实现图形连线的方案,就是图形是用SWT设计的,而线是用draw2D来设计的。这样设计表面看起来能够达到draw2D的两线的完美效果,而又不改变我们需要是用的SWT设计的图形。

1、 连线的简化流程

获得起始图形,计算出连线的起点

获得指向图形,计算出连线的终点

根据起点和终点来建立连线

2、 解决Canvas与Panel之间的兼容问题

因为我们的建立在一个画布(Canvas)上的,而连线则要建立在一个(Panel)上。因此我们要将两者联系起来,才能实现图形间的连线。这里需要用到轻量级系统(LightweightSystem)

lws=new LightweightSystem(editPlace);

图形所在的面板

然后就可以新建Panel,并将他设为轻量级系统的内容

panel=new Figure();

lws.setContents(panel);

这样我们就可以在panel上添加我们的连线了
2.2 在面板上画曲线

1、 这个曲线也同样要建立在Panel之上,因此也要像上面一样建立Panle,这里不再重复

2、要创建曲线则要用到PolylineConnection(),我们先创建一个PolylineConnection的对象pc.

3、 如果要显示箭头,则可以给pc添加修饰,

    p2.setTargetDecoration(new PolygonDecoration());

4、接下来就是设置pc上的关键点,包括起点,终点,拐点。确定这些点后,从起点到终点依次排列即可



p2.setPoints(new PointList(new int[]{p1, p2,p3,…}));

5、 这样就可以建立了曲线,不过线上的个关键点的确定是一个难点,根据不同的情况会有不同的确定方法,这里不能一一列出了
3。图像常用处理与Canvas
3.1 如何在Canvas上添加图像

要在一个画布Canvas上添加,需要注册画布的画图事件,代码如下:

canvas.addPainListener(new PaintListener(){

    public void paintControl(PaintEvent e){

         e.gc.drawImage(image,10,10);

    }

}
3.2 图像的创建

1. Image(display, “eclipse.gif”)

2. Image (display , “eclipse.gif”,SWT.IMAGE_FRAY)

3. ImageData data = new ImageData(“eclipse.gif);

    Image image = new Image(display, data)
3.3 图像的放大或缩小

   通过ImageData的scaledTo可意见图像放大或缩小,在这里是新建另一个图像,而不是直接改变原来的图像。

ImageData data = image.getImageData();

ImageDate newData = data.scaledTo(newWidth,newHeight);

Image newImage = new Image(display, newData);

3.4 图像的保存

因为一个动态的图片可能有多个图片组成,所以用数组
4文件的过滤

这里所说的文件的过滤不是上面说的文件对话框中的文件的过滤,在这里我们设置了一个树,让它来显示工程下已有的文件,在这里我们只希望看到(.grh)的文件,因此需要给它设置过滤器。先来看看我们怎么实现显示文件的;



在这里使用的是TreeViewer,TreeViewer的构建步骤如下:

1、  创建新对象,例如TreeViewer tv=new TreeViewer(fileComposite,SWT.NONE);

2、 设置内容管理器,如tv.setContentProvider( new FileTreeContentProvider());

3、设置标签提供器,如tv.setLabelProvider(new FileTreeLabelProvider());

4、设定TreeViewer的输入数据,如tv.setInput(new File("e:\"));

其中FileTreeContentProvide,FileTreeLabelProvider分别是implements了ItreeContentProvider和ILabelProvider两个接口的。

FileTreeContentProvide中有几个重要的方法。

① getElements();"public Object[] getElements(Object inputElement)",当程序开始构建树时,首先调用它返回一个数组,此数组对象表示树的根节点,

② hasChildren();"public boolean hasChildren(Object element)",当TreeViewer显示一个节点(element)后会调用该函数判断当前节点是否有子节点,若有则显示“+”;

③ getChildren();"public Object[] getChildren(Object parentElement)",当用户选择节点打开子节点时,会调用此函数返回下一层子节点,parentElement参数为选择的节点;

④ getparent();"public Object getParent(Object element)"

还有几个方法就不在此叙述,

在程序里不需要显示根目录的位置,只要显示在工程目录下有用的文件,在getElements()方法中,我们返回getChildren()中的值,这样,我们就可以不得到输入的路径这个根节点,而把该路径下的符合条件的文件作为根节点;



public Object[] getElements(Object element) {   

         return getChildren(element);    

  }



在getChildren方法中,我们通过一个数组列出给定路径下的文件,然后通过一个ArrayList来存储符合条件的文件对象:



  Object[] kids = ((File) element).listFiles();  

ArrayList<Object> outs = new ArrayList<Object>();



  当kids不是空的时候,我们就看kids中的文件后缀是不是符合我们的要求,如果是,就添加到outs中

for(int i = 0;i<kids.length;i++){

                  if(((File)kids[i]).getName().endsWith(".wsdl")||

                                ((File)kids[i]).getName().endsWith(".bpel")||

                                ((File)kids[i]).getName().endsWith(".grh")){

                         int j = 0;

                      outs.add(j,kids[i]);

                      j++;

                  }

           }



现在我们已经得到了我们需要得到的所有的对象,因为这个函数的返回值是个数组,再把outs中的元素复制到一个数组中即可;

f(outs.size()!=0){

                  Object[] out = new Object[outs.size()];

                  for(int i= 0;i<outs.size();i++){           

                      out[i] = outs.get(i);

               }

               return out;

           }   




5。关于序列化保存

1)        关于保存

序列化的问题是由保存引起的,要保存一个对象就必须为相关的类实现序列化,这本没有什么问题,只需要把相关的类继承并实现Serializable接口就可以了,但是,在工程里用到了一些类。例如org.eclipse.swt.widgets.graphics.Image这个类,它是一个final类,不可以被继承,但是他是节点的一部分,必须要显示出来;我们可以把它作为一个参数传到节点的setNodeLocation函数中,它是初始化节点时负责显示的函数。每创建一个新的节点时就需要先创建一个Image实例。

2)        关于恢复

保存成功了还需要恢复图像,恢复图像是个比较复杂的过程,我们要保证图像的位置和数据等许多东西保持不变;首先找到开始节点,从开始节点开始逐个恢复,如没有开始节点,那么这个图是不完整的,就没有办法完整的恢复它;恢复时,不能用原来的对象,因为原有的对象都已经被dispose();了,并且不可以用到任何有关显示的方法,否则就会出现促发异常;所以要得到节点的大小和位置就要另想办法;

为了得到node原来的位置,在node中设置了一个point变量来记载node的位置,并在node的位置更改后更改point的值,这样就可以得到node原来的位置;同理,我们可以得到保存时node的大小了;

我们可以从保存的图中找到与开始节点相关联的下一个节点,回复这个节点后再找下一个节点,这样可以通过一个循环一直找到结束节点,并把这些节点加到一个新建的graph中,然后把相关的信息都通过已有的set和get方法添加的节点中去,这样,整个图的所有的节点都恢复出了;

因为每个节点的下一个节点有不同的可能,用一个if else组合来判断到底是哪一个节点,然后不同的节点有不同的代码;简单的节点如taskNode的恢复比较简单,基本的过程和创建一个新的节点相同,只是注意把原节点的信息传递给新的节点即可。
   具体的过程可以简化为

获得要复制的节点的引用

点击粘贴,新建一个与要复制节点类型相同的节点

把要复制节点的信息传递到新的节点中去

判断节点是不是容器节点,是继续,不是结束

新建容器节点中的子节点,给子节点传递信息

以下是粘贴后初始化一个工作节点的例子;

wfNode = new TaskNode(node.getName(), gra, web);

wfNode.setId(node.getId());

wfNode.setNodeInView(c, workspace.getPanel(), attr,workspace,web);         BaseWFNodeText.setCanvasText(wfNode);                    

wfNode.setNodeLocation(node.getPoint().x, node.getPoint().y, image1);

gra.addNode(wfNode);





若下一个节点是复杂节点,首先恢复复杂节点本身,然后判断该节点是否有子节点,若存在子节点,则依次恢复其子节点,通过一个foreach循环就可以把所有的子节点恢复;注意的是每个父节点的子节点形式可能不同,而且他们需要传递的信息也不完全相同。部分代码如下



wfNode.getCanvas().setSize(node.getSize());

//设置节点的大小

wfNode.setSize(node.getSize().x, node.getSize().y);

//记录节点的大小

gra.addNode(wfNode);

节点的信息如下



wfNode.setBpelOperation(node.getBpelOperation());

wfNode.setSuppressJionFaliare(node.getSuppressJionFaliare());

wfNode.setJionCondition(node.isJionCondition());

wfNode.setOporation(node.getOporation());

wfNode.setLink(node.getLink());

//以上为所有节点都有的属性

wfNode.setCondition(node.getCondition());

//FlowNode和WhileNode有的属性

wfNode.setCaseCondiction(node.getCaseCondiction());

//FlowNodeµÄ×Ó½ÚµãÓеÄÊôÐÔ

  

childNode.setFromPart(element.getFromPart());

childNode.setFromVar(element.getFromVar());

childNode.setToPart(element.getToPart());

childNode.setToVar(element.getToVar());

//以上四个是copy有的节点
6。图形的复制与粘贴

1)        为各个节点以及底层面板创建菜单项,包括复制,粘贴,删除;在工具栏以及菜单栏创建相应的项;

2)        关于复制

复制的方法比较简单,就是把一个新的变量指向要复制的对象,然后把这个变量通过get方法,让外界可以获得它;



public void copy(BaseWFNode node){

              midNode = node;

}



3)        关于粘贴

粘贴的过程是创建一个新的节点,他所携带的信息和复制的节点相同

1、 获得要粘贴节点的引用;判断是否为空,是就继续,否则就什么也不做;

2、 构建一个新的节点,确定节点的id,位置等于声称代码无关的信息;

3、 判断节点具体是哪一种节点,并把原节点的信息赋给新的节点;

4、 Gragh中添加这个节点;

5、 根据第三步,若这个节点是某个复杂节点,就把它的子节点也构建出来,并赋予相应的信息;实现的过程和恢复图形类似;

4)        工具栏复制的实现

1、 这里添加监听的时候用了一个标记,当双击一个节点的时候,就记录这个标记为1,然后让一个中间的变量指向这个节点,



public void mouseDoubleClick(MouseEvent e){                   

           WSCAttribute.showWind(work, node);

           deleteFlag = 1;//当点击其他地方时设为0;

           preDelNode = node;

       }

2、点击复制的时候判断标记是否为1,判断PreDelNode是不是空,不是就根据上面说的复制来执行;删除节点也是用这个思想;

3、 点击粘贴,判断中间节点是否时空,不是就在底层面板的起始处将节点复制下来;否则就什么也不做;
分享到:
评论

相关推荐

    【重大更新】用SWT/JFace实现的放大镜JZoomer V1.1.1(附源码)

    添加SWT/JFace的jar包到工程lib目录下 ·BasicWindow添加对鼠标移动点击的事件监听,以实现组件可用鼠标拖拽功能 ·BasicWindow添加在屏幕中央显示/随鼠标位置显示方法 ·更改屏幕采样并缩放的核心算法...

    [开源]用SWT/JFace实现的放大镜软件jZoomer v1.2.0(附源码)

    调整缩放范围,使其既可放大屏幕也可缩小屏幕 3. 核心调整: ·添加SWT/JFace的jar包到工程lib目录下 ·BasicWindow添加对鼠标移动点击的事件监听,以实现组件可用鼠标拖拽功能 ·BasicWindow添加在...

    SWT_JFace.rar_ImageAnalyzer_SWT-jface_swt jface

    本项目"SWT_JFace.rar_ImageAnalyzer_SWT-jface_swt_jface"是围绕这些技术展开的一个示例应用,名为"ImageAnalyzer",它可能是用于分析或处理图像的工具。下面将详细阐述这两个组件及其在项目中的应用。 首先,SWT ...

    基于swt的企业项目管理系统

    SWT-ProjectManage 目录为SWT/JFace版的企业项目管理系统,界面比较美观!但由于课程进度的限制,功能没有做完,但已经设置了权限,实现了MD5加密算法,数据分页显示等功能;分层实现,便于了维护和管理... 数据库...

    SWT详细精解

    "SWT详细精解"这一主题涵盖的内容广泛,包括SWT的基础概念、组件使用、事件处理、布局管理以及与Eclipse JFace的结合使用等。 1. SWT基础: SWT是基于原生系统API的,这意味着它能够提供与操作系统一致的外观和...

    SWT_JFace_in_action.pdf.zip_模式识别(视觉/语音等)_Java_

    通过阅读《SWT_JFace_in_Action》,开发者将学习如何利用这些技术创建交互式应用程序,同时结合SWT和JFace的强大功能,实现用户界面的定制化和高效性。书中可能涵盖的主题包括: 1. SWT控件的使用:按钮、文本框、...

    IT应用文考试要求.docx

    8. 气象科普产品入库系统采用SWT/Jface技术 9. 气象科普资源库管理系统的SWT/Jface实现 10. 气象信息动态展现方法研究,涉及CS架构和Flash技术 11. epub电子书制作技术及应用 12. 并行计算在MATLAB环境下的研究及其...

    java计算器[收集].pdf

    1. **用户界面(UI)**:使用Java的GUI库,如AWT/Swing或SWT/JFace,构建计算器的图形界面,实现按钮、文本框等组件。 2. **事件处理**:通过监听按钮点击事件,实现计算逻辑。例如,当用户点击数字按钮时,将数值...

    IT应用文考试要求 (2).pdf

    例如电子商务物流配送系统、房地产租赁管理信息系统、Web应用设计(如大学生综合素质测评系统、在线考试系统等)、数字水印系统、Android应用开发(校园外卖、天气信息查询)、JSP与SWT/Jface的气象信息系统、并行...

    基于插件技术的数据挖掘平台设计与实现.pdf

    2. 插件技术特色:Eclipse的特色包括创新性的图形API(SWT/JFace)、其插件机制、以及基于插件机制开发出的大量功能强大的插件,如JUnit、Ant等。 3. Eclipse架构:Eclipse有一个非常小的内核,所有的附加功能都通过...

    Java跳棋(基于SWT)项目源代码

    2. **JFace和SWT的关系**:JFace是基于SWT构建的高级UI框架,简化了SWT的使用,提供了数据绑定、视图模型、对话框等功能,使得开发者能更专注于业务逻辑而不是底层细节。 3. **事件驱动编程**:Java跳棋应用的核心...

    大数据-算法-桌面化学数据库应用系统ChemDataBase2的研究和实现.pdf

    - 第二章详细探讨了Eclipse RCP开发的关键技术,包括开发环境、插件机制、SWT和JFace的使用。 - 后续章节可能涵盖了系统设计、实现过程、性能评估和应用案例等方面,详细论述了ChemDataBase2如何利用大数据算法提升...

    基于java—MAPGIS二开

    5. **SWT/JFace** 或 **JavaFX**:用于创建用户界面,这些图形库可以帮助开发者构建美观且功能丰富的GIS应用程序界面。 6. **地图渲染**:学习如何使用Java和MAPGIS SDK将GIS数据转化为可视化地图,包括图层管理、...

    eclipse插件swtDesigner的注册码,java反编译工具(有使用说明图示),灵格斯免安装版本,JAVA面试宝典

    SWT Designer是用于帮助Java开发者设计和构建 SWT(Standard Widget Toolkit)和JFace用户界面的工具。它提供了一个图形化界面,允许用户通过拖放方式创建和编辑界面元素,大大简化了UI设计过程。然而,这个插件可能...

    java毕业设计

    - **SWT/JFace**:SWT(Standard Widget Toolkit)是一种用于开发图形用户界面(GUI)的应用程序框架,而JFace则是在SWT基础上的一组更高层次的GUI组件库,两者结合可以快速构建出复杂的用户界面。 - **RCP**:...

    swt table扩展

    `TableViewer`是SWT JFace库的一部分,它提供了更高级的抽象层,可以方便地处理数据模型与显示视图的同步。 在实现自定义列类型时,我们可以创建一个新的`CellEditor`类的子类,比如`TextCellEditor`或`...

    Java技术与就业指导

    首先,从UI层开始,Java提供了AWT和Swing库用于构建桌面应用程序的图形用户界面,而SWT和JFace则常用于Eclipse插件开发。在Web浏览器端,HTML、CSS和JavaScript构成了网页的基础,Ajax技术则用于实现页面的异步更新...

    Web信息自动/半自动抽取系统——演示版

    Web信息自动/半自动抽取系统 build 091010 基于SimpleTreeMatching算法 ...使用Java6+SWT(JFace)+htmlparser+dom4j开发,自带精简版Jre6. 本科毕业设计内容,仅用于演示算法,有问题可以给我留言。

    基于Java的文字识别系统的研究.pdf

    1. **系统总体设计目标:** 通过图形化用户界面工具包(如Eclipse中的SWT和JFace)实现一个轻量级的用户交互界面,使系统操作简单、快捷。 2. **功能模块划分:** 主面板容器类集合所有功能,包含的主要功能模块有:...

Global site tag (gtag.js) - Google Analytics