八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  231 随笔 :: 0 文章 :: 2944 评论 :: 11 Trackbacks

利用org.eclipse.draw2d.SWTGraphics类和org.eclipse.swt.graphics.ImageLoader类可以实现把画布导出到图片文件的功能,原理是在内存里创建一个空白的Image,然后把Diagram画到它上面,最后保存到指定文件和格式。

我们可以把导出工作分为两部分,第一部分负责提供要导出的IFigure实例(若要导出整个画布,应从GraphicalViewer获得PRINTABLE_LAYERS,否则会丢失画布上的连线),并负责将得到的图片数据写入文件;第二部分负责IFigure实例到图片数据的转换过程。以下是前者的示例代码:

String filename = ...;
PracticeEditor editor 
= ...;
ScalableFreeformRootEditPart rootPart 
= ...;
IFigure figure 
= rootPart.getLayer(ScalableFreeformRootEditPart.PRINTABLE_LAYERS);//To ensure every graphical element is included
byte[] data = createImage(figure, SWT.IMAGE_PNG);
try {
    FileOutputStream fos 
= new FileOutputStream(filename);
    fos.write(data);
    fos.close();

catch (IOException e) {
    e.printStackTrace();
}

上面代码里调用的createImage()方法是实际在内存里作画并转换为可写入为文件的二进制流的地方,代码如下所示:

private byte[] createImage(IFigure figure, int format) {
    Rectangle r 
= figure.getBounds();
    ByteArrayOutputStream result 
= new ByteArrayOutputStream();
    Image image 
= null;
    GC gc 
= null;
    Graphics g 
= null;
    
try {
        image 
= new Image(null, r.width, r.height);
        gc 
= new GC(image);
        g 
= new SWTGraphics(gc);
        g.translate(r.x 
* -1, r.y * -1);
        figure.paint(g);
        ImageLoader imageLoader 
= new ImageLoader();
        imageLoader.data 
= new ImageData[] { image.getImageData() };
        imageLoader.save(result, format);
    } 
finally {
        
if (g != null) {
            g.dispose();
        }
        
if (gc != null) {
            gc.dispose();
        }
        
if (image != null) {
            image.dispose();
        }
    }
    
return result.toByteArray();
}

点此下载工程,此工程修改自GEF应用实例中的GefPractice,目标文件的扩展名为.gefpractice不变。


图1 运行后增加了导出功能按钮

GEF新闻组里相关链接:
http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg05012.html
http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg06329.html

posted on 2007-08-01 00:01 八进制 阅读(3475) 评论(48)  编辑 收藏 所属分类: EclipseGEF

评论

#1楼  2007-08-14 19:08 uyj [未注册用户]
请问在gef中的大纲视图中的鹰眼功能如何实现选中,删除功能??

  回复  引用    

#2楼 [楼主] 2007-08-14 21:52 八进制      
恐怕不行,outline里的thumb图是可以看作是一张图片。
  回复  引用  查看    

#3楼  2007-08-17 10:14 diystyle [未注册用户]
我测试了一下,好像不行,会报如下异常,我测试了其它图片格式是没有问题的,只有PNG格式会有问题,不知道是不是我环境有问题:
org.eclipse.swt.SWTException: Unsupported or unrecognized format
at org.eclipse.swt.SWT.error(SWT.java:3374)
at org.eclipse.swt.SWT.error(SWT.java:3297)
at org.eclipse.swt.SWT.error(SWT.java:3268)
at org.eclipse.swt.internal.image.PNGFileFormat.unloadIntoByteStream(PNGFileFormat.java:146)
at org.eclipse.swt.internal.image.FileFormat.unloadIntoStream(FileFormat.java:122)
at org.eclipse.swt.internal.image.FileFormat.save(FileFormat.java:110)
at org.eclipse.swt.graphics.ImageLoader.save(ImageLoader.java:199)
at com.example.actions.DiagramActionBarContributor$ExportImageAction.createImage(DiagramActionBarContributor.java:119)
  回复  引用    

#4楼 [楼主] 2007-08-17 11:28 八进制      
我这里可以,但听同事提到过PNG格式报错的问题,怀疑是SWT版本不同造成的,试一下3.3版本的eclipse呢?
  回复  引用  查看    

#5楼  2007-08-17 12:53 diystyle [未注册用户]
下了一个3.3的测试了一下,是没有问题,看来得升级版本了,比较郁闷得事情.在这先谢谢八进制的提醒了,^_^
  回复  引用    

#6楼  2007-08-20 11:59 uyj [未注册用户]
八进制你好!请问一下怎么在大纲视图的菜单命令调用Editor 里定义的command?
谢谢!!!
  回复  引用    

#7楼  2007-08-21 13:31 小妍 [未注册用户]
八进制您好!我看了你大部分的gef的例子,但是我现在还不知道,在emf和gef结合的例子中,通过*.genmodel,可以生成部分代码,但是生成的结果中,subjectEditor prject的src中没有那么多包,其他的包是自己建立的还是自动生成的。例如在subjectEditor prject中只有src/*.presentation。
非常着急,等待你的回复,谢谢了
  回复  引用    

#8楼 [楼主] 2007-08-21 21:19 八进制      
subject例子里emf只生成模型部分代码,gef部分如各种editpart、editpolicy那些都是自己写的。gmf可以帮助生成gef相关代码。
  回复  引用  查看    

#9楼 [楼主] 2007-08-21 22:57 八进制      
@uyj
大纲视图一般是在Editor里创建的,你只要把需要的Action加在大纲视图上应该就可以了吧。如果你需要修改模型,也许需要把EditingDomain传给大纲视图。
  回复  引用  查看    

#10楼  2007-08-24 14:44 auranja [未注册用户]
请问可以把draw2d画出的图在jsp页面里显示么?
最近在做一个东西,需要显示树型的组织结构图(不是目录结构的那种),想用draw2d来做,可是不知道显示出来之后能不能在jsp里面显示,完全没有思路
  回复  引用    

#11楼 [楼主] 2007-08-24 18:39 八进制      
可以,文中的createImage()方法得到的流输出到response.getOutputStream()即可,在web应用的WEB-INF/lib里要加上这几个包:org.eclipse.draw2d_xxx.jar,org.eclipse.swt.win32.win32.x86_xxx.jar,org.eclipse.swt_xxx.jar,另外classpath里要包含swt-win32-xxxx.dll文件。
  回复  引用  查看    

#12楼  2007-08-29 10:38 tutr [未注册用户]
请问一下能否改变一下从AbstractBorder继承来的Border的边框变成圆形的??
谢了!!!
  回复  引用    

#13楼 [楼主] 2007-08-29 11:43 八进制      
覆盖border的paint()方法就可以吧
  回复  引用  查看    

#14楼  2007-09-11 14:06 tutr [未注册用户]
八进制你好!!
请问一下我想把SWT中的TEXT控件放在GEF的Editor中,可以吗??
  回复  引用    

#15楼 [楼主] 2007-09-11 14:49 八进制      
应该说不行,在draw2d里编辑文字用CellEditor,http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg03112.html
  回复  引用  查看    

#16楼 [楼主] 2007-09-11 14:57 八进制      
补充一下,其实也不是绝对不行,但GEF的设计是不支持的,要实现它需要自己实现一些代码。新闻组里有很多关于这方面的讨论,例如http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg15998.html
  回复  引用  查看    

#17楼  2007-09-18 11:38 bclz [未注册用户]
八进制您好!我们公司最近在做一个项目,其中要在Editor中设计一个表格,完成一个表格的所有功能,想了很久还是搞不定,能不能把你上面的有一篇关于表格的源码发一份啊!!!先谢谢了!!!!!!!!!!!
EMAIL:fumli@sina.com
  回复  引用    

#18楼 [楼主] 2007-09-18 13:41 八进制      
抱歉,表格的代码属于公司,所以不能分发,但我能肯定关键的地方都已经在文中写清楚了。另外,要实现表格的“所有”功能可能需要在那个例子的基础上再继续改进,例如支持内容滚动等等。
  回复  引用  查看    

#19楼  2007-10-24 16:34 homer4503 [未注册用户]
八进制你好:我想扩展eclipse中的ResourceNavigator视图,按照网上的介绍做了,但是出现下面的问题,而且rcp工程也启动不了,请问是怎么回事?谢谢
java.lang.RuntimeException: Application "GefTest.application" could not be found in the registry. The applications available are: org.eclipse.ant.core.antRunner.
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:216)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334)
at org.eclipse.core.launcher.Main.basicRun(Main.java:278)
at org.eclipse.core.launcher.Main.run(Main.java:973)
at org.eclipse.core.launcher.Main.main(Main.java:948)
  回复  引用    

八进制你好,看来你的文章,学习到很多东西,想请教一个问题,在GEF中连接线如果设置为虚线类型的,虚线的点间的间隔及虚线的长度可否进行设置?
  回复  引用    

#21楼 [楼主] 2007-11-28 13:34 八进制      
可以:
connection.setLineDash(new int[] { 10, 10 });
connection.setLineStyle(Graphics.LINE_CUSTOM);
  回复  引用  查看    

#22楼  2007-11-28 21:56 metaphy [未注册用户]
八进制:
您好!
我希望用gef做个棋类游戏玩,有2个问题:
1.palette的tool是否能像commandButton那样,点击一个,然后将另外某一个disable呢?

2.能否实现一个Timer,由它来驱动Request,然后导致界面上的图元自动移动呢?我看你写的,说Request只能由Tool来发出,真的没有办法了吗?

谢谢!
  回复  引用    

#23楼  2007-11-29 12:07 metaphy [未注册用户]
8进制:没这样用过,但都能实现。
=============
非常感谢。
还要再深入研究下
  回复  引用    

#24楼  2007-12-07 15:33 zhou_zch [未注册用户]
八进制:
请问下,如果要把GEF编辑的流程图移植到浏览器上,该用到些什么技术呀
  回复  引用    

#25楼 [楼主] 2007-12-09 16:31 八进制      
看到过用ajax方式实现的浏览器里的流程编辑器,但响应很慢,因为每次操作都需要和服务器通讯。纯js的流程编辑器还没见过太好的,和gef应用比起来像玩具。还有一种方式是flash的,效率也成问题。所以我不太建议在浏览器里加入流程编辑器,可以考虑用webstart方式,在页面上提供一个链接,用户点击后自动下载和运行一个gef流程编辑器。
  回复  引用  查看    

#26楼  2007-12-10 09:22 zhou_zch [未注册用户]
八进制你好:
感谢你对我提的问题的及时答复!
我由于工作的需要,才刚接触GEF,虽然看了你写的GEF入门系列,可还是有很多的问题没有弄懂,希望以后能够得到你的指导,我的QQ是14459330,如果方便的话加下我QQ,方便联系,先谢了啊
  回复  引用    

#27楼  2007-12-11 09:22 zhou_zch [未注册用户]
八进制:
请问下,如果我要把GEF做的流程编辑器移植到Applet中,再在浏览器上加载Applet。当我把GEF移植到Applet中时要做些什么呢?
  回复  引用    

#28楼 [楼主] 2007-12-12 17:11 八进制      
很难,gef要依赖eclipse才能运行。
  回复  引用  查看    

#29楼  2007-12-21 10:37 help [未注册用户]
你好,八进制,
现在导出图片应该是要打开编辑器,才能够导出。
能不能不打开编辑器(或者不显示打开编辑器)导出图片呢?(例如,我要导出一个工程下的所有相关文件的图片).

谢谢!!
  回复  引用    

八进制,你好:
这是我在 中国eclipse社区-图形和模型 板块提的问题和网友的解答,你有什么评论?

如何在gef的editor中创建swt的widget
在目前所有的gef的editor例子中都是由draw2D来创建IFigure,现在我想用swt的控件(比如Text,Button等,甚至有可能是JFreechart的控件,比如饼图和柱状图)来创建一个IFigure,该怎么做呢?


扯乎?!
swt控件得指定parent
IFigure是图在lws上的~lws不能作为swt控件的parent

不过lws是画在canvas上的,canvas好像可以作为swt插件的parent,
但是这样就不是gef了,不能用editpart操作
  回复  引用    

#31楼  2007-12-21 17:46 jiezi [未注册用户]
好像draw2d下有button类,但没用过,不知道是不是跟swt的button一个样子的
  回复  引用    

#32楼 [楼主] 2007-12-24 23:53 八进制      
draw2d提供的控件都是在draw2d的图形上画出来的,和swt的控件不是一回事,只能解决一些简单问题,下拉列表就无法解决。在新闻组里了解到,Eclipse的VE项目是利用off screen方式切下swt控件的图片,然后用draw2d的imagefigure画在图形上,可以解决界面设计的问题,可以参考一下。
  回复  引用  查看    

#33楼  2007-12-26 11:37 jiezi [未注册用户]
八进制大哥能留个联系方式么,邮箱啥的,左上角那个已经没了
我的 bit506@163.com
  回复  引用    

#34楼  2008-01-07 17:45 jiezi [未注册用户]
请问可以只选择画布中的部分导出到图片么,例如树形的某子树
  回复  引用    

#35楼 [楼主] 2008-01-08 11:34 八进制      
可以导出任何IFigure,如果子树的所有节点都是子树根的child就可以。
  回复  引用  查看    

#36楼  2008-03-26 23:53 20080326 [未注册用户]
八进制大哥,请问能不能实现动态的虚线?就是让虚线中的点慢慢的移动,但是虚线的两个端点不改变。同时能设置PolylineConnection的颜色吗?
  回复  引用    

#37楼 [楼主] 2008-03-30 16:55 八进制      
是指蚂蚁线吗,抱歉我没有实现过。
PolylineConnection的颜色用setForegroundColor()就可以了吧。
  回复  引用  查看    

#38楼  2008-05-28 18:11 syh [未注册用户]
八进制你好:
刚开始学习GEF,看了你的文章收获很多,我想请问一下如何保存成svg格式的图片
  回复  引用    

#39楼  2008-05-29 12:51 syh [未注册用户]
另外,我还有个问题,假如一个父类图形有两个子类图形(类似于类图),这两个子类图像都要求能自动增加Node节点,请问怎么实现加入节点时区别这两个子图形的问题,
能不能直接通过在模型中定义一个状态来决定getContentPane的返回值来切换往哪个子图形中加节点?
  回复  引用    

#40楼  2008-06-04 10:09 tyler_yu [未注册用户]
我在 outline 选中一个节点时 , properties view 只会显示 基本信息 。
怎样显示 tab properties
  回复  引用    

#41楼  2008-06-04 10:23 tyler_yu [未注册用户]
在请教一个问题 :
1 :项目文件的 如 **.java 的双击事件怎么扩展
2 :GMF 生成的 图形如何选中
如 :我已打开的时候 就默认选中其中一个图形


  回复  引用    

#42楼 [楼主] 2008-06-12 20:58 八进制      
@tyler_yu
1) .java这个扩展名应该是绑定到JDT定义的java编辑器,是通过org.eclipse.ui.editors扩展点绑定的,不知道你要怎样扩展?
2) SelectInDiagramHelper.selectElement(yourView);
  回复  引用  查看    

#43楼 [楼主] 2008-06-12 21:01 八进制      
@tyler_yu
tabbed属性视图有专门的扩展点,请参考下面文章:
http://www.eclipse.org/articles/Article-Tabbed-Properties/tabbed_properties_view.html
  回复  引用  查看    

#44楼 [楼主] 2008-06-12 21:10 八进制      
@syh
可能要通过第三方支持(不清楚GMF是怎样实现的),例如http://gef-batik.tigris.org/
  回复  引用  查看    

#45楼  2008-06-13 15:26 tyler_yu [未注册用户]
@八进制
这个可以解决了。
加入
<input type="com.zte.ssb.entitydesign.model.diagram.part.NodeTreeEditPart"/>
自定义的outline的editPart 就可以啦。



  回复  引用    

#46楼  2008-06-13 15:37 tyler_yu [未注册用户]
--引用--------------------------------------------------
八进制: @tyler_yu
1) .java这个扩展名应该是绑定到JDT定义的java编辑器,是通过org.eclipse.ui.editors扩展点绑定的,不知道你要怎样扩展?
2) SelectInDiagramHelper.selectElement(yourView);
--------------------------------------------------------
双击一个文件(自定义文件不是diagram文件)
打开GMF编辑器 , 选中编辑器中一个图形 。

这个是上面两个问题的环境 。
  回复  引用    

#47楼 [楼主] 2008-06-13 20:50 八进制      
@tyler_yu
在GMF生成的editor类里适当的位置(也许要覆盖父类方法)加上选中一个图形的代码就可以了吧。
  回复  引用  查看    

#48楼  2008-07-17 17:06 开发人 [未注册用户]
八进制,想问你一个问题,如果我弄了两个Node,那么我导出包括这两个Node的图片就可以了,没有必要导出一个diagram图.要不会有很多空白的,这个怎么做呢,请赐教.
  回复  引用