在RCP应用上使用Jfreechart绘制图表(附源码)
2012-06-28 16:21 飘扬的红领巾 阅读(2462) 评论(0) 编辑 收藏 举报下午闲来无事,找出Jfreechart来复习一下,做了个在RCP上使用Jfreechart的小程序。
第一步、创建RCP程序。
在Eclipse中,使用向导创建Eclipse插件程序:
后面就不说了,填写相应项,一路下去,创建好Eclipse插件程序,运行可以看到:
第二步、创建视图
创建视图既可以使用向导创建,也可以手动添加Java类,如添加类似这样的类:
1 | public class ChartCategoryViewPart extends ViewPart |
然后在Perspective .java中将创建的视图添加到透视图中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Perspective implements IPerspectiveFactory { @Override public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); layout.addStandaloneView( com.cnblogs.leefreeman.views.ChartCategoryViewPart.ID, true , IPageLayout.LEFT, 0 .23f, editorArea); layout.addStandaloneView(ChartInfoViewPart.ID, true , IPageLayout.RIGHT, 0 .77f, editorArea); layout.setEditorAreaVisible( false ); layout.setFixed( true ); } } |
代码就不详细讲解了,最后会把整个例子的源代码共享出来。
创建了视图,应用程序运行起来就会是这样子:
第三步、在视图中创建树
在创建好的视图类中,添加创建树的代码,代码有点多不贴了,可以到附件中下载。
上图创建了一个树,表示将要在右边视图显示的图表的类别(柱状图、坐标图、饼图)
第四步、创建图表
先添加一个图表类,以饼图为例,如PieChart.java。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public class PieChart { /** * 创建提供给图表显示的数据 * * @return */ private static PieDataset createDataset() { DefaultPieDataset defaultpiedataset = new DefaultPieDataset(); defaultpiedataset.setValue( "C" , 17 .00D); defaultpiedataset.setValue( "Java" , 17 .00D); defaultpiedataset.setValue( "C++" , 9 .00D); defaultpiedataset.setValue( "Objective-C" , 8 .00D); defaultpiedataset.setValue( "C#" , 7 .00D); defaultpiedataset.setValue( "Other" , 42 .00D); return defaultpiedataset; } /** * 创建图表 * @return */ @SuppressWarnings ( "deprecation" ) public static JFreeChart createChart() { PieDataset dataset = createDataset(); JFreeChart chart = ChartFactory.createPieChart3D( "" , dataset, true , true , true ); // 设置图片的背景色 chart.setBackgroundPaint(java.awt.Color.white); // 设置图片标题的字体和大小 TextTitle title = new TextTitle( "编程语言排名" ); chart.setTitle(title); PiePlot3D pie = (PiePlot3D) chart.getPlot(); pie.setInsets( new RectangleInsets( 5 , 5 , 5 , 5 )); // 指定 section 轮廓线的颜色 pie.setOutlinePaint(java.awt.Color.BLACK); // 指定 section 轮廓线的厚度 pie.setOutlineStroke( new BasicStroke( 1 )); // 设置第一个 section 的开始位置,默认是12点钟方向,90度,逆时针 pie.setStartAngle( 90 ); // 指定 section 的色彩 pie.setSectionPaint( 1 , new Color( 0x99 , 0x99 , 0xFF )); pie.setLabelFont( new Font( "黑体" , Font.BOLD, 12 )); // 指定显示的饼图上圆形还椭圆形。true为圆形,false为椭圆形。默认为false pie.setCircular( true ); // 指定图片的透明度 pie.setForegroundAlpha( 0 .5f); pie.setLabelGap( 0.01 ); // 间距 pie.setNoDataMessage( "No data available" ); return chart; } } |
完成图表类之后,想要在视图中显示它,必须完成下面的工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Override public void createPartControl(Composite parent) { JFreeChart chart = ChartFactory.createChart(categoryEnum); if (chart != null ) { final ChartComposite frame = new ChartComposite(parent, SWT.NONE, chart, true ); if (parent.getChildren().length > 1 ) { parent.getChildren()[ 0 ].dispose(); } frame.pack(); parent.layout(); } } |
ChartFactory类是自定义的一个图表工厂,用于创建指定的图表。做完这些事儿,之后。
第五步、实现视图间的通信
简单的来说,就是点击左边的树节点,右边视图中的图表根据点击的节点做相应的更新。实现此功能有很多种方法,常用的方法是在左边视图中,取得右边视图的句柄,然后调用其相关的方法,实现更新。但此方法耦合性较高,不便于扩展,我们不推荐此方法。这里我们使用观察者模式来实现此功能,也就说创建一个被观察者(主题),让视图作为观察者,监听其变化,当监听到主题变化时,做更新图表的操作。而左边视图所做的事情就是在用户点击时,改变主题的内容,触发它的变化。
为此我们这样做:
添加主题:StateModel.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class StateModel extends Observable implements IAdaptable { private ChartCategoryEnum categoryEnum; /** * @return the categoryEnum */ public ChartCategoryEnum getCategoryEnum() { return categoryEnum; } /** * @param categoryEnum the categoryEnum to set */ public void setCategoryEnum(ChartCategoryEnum categoryEnum) { this .categoryEnum = categoryEnum; } @Override public Object getAdapter( @SuppressWarnings ( "rawtypes" ) Class adapter) { return null ; } public void fireModelChanged() { this .setChanged(); notifyObservers(); } } |
在应用程序启动时,放置到系统内存中:
1 2 3 4 5 6 7 8 9 10 11 | @Override public void postWindowOpen() { StateModel stateModel = new StateModel(); try { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.getWindow().openPage(PERSPECTIVE_ID, stateModel); } catch (WorkbenchException e) { e.printStackTrace(); } super .postWindowOpen(); } |
在左边视图类中先从系统内存中取得StateModel(主题):
1 2 3 4 5 | @Override public void init(IViewSite site) throws PartInitException { stateModel = (StateModel) site.getPage().getInput(); super .init(site); } |
然后点击事件中:
1 2 3 4 5 6 7 8 9 10 11 12 | Object obj = ((IStructuredSelection) selection) .getFirstElement(); if (obj.toString().equals( "Bar Chart" )) { stateModel.setCategoryEnum(ChartCategoryEnum.BAR); } if (obj.toString().equals( "Pie Chart" )) { stateModel.setCategoryEnum(ChartCategoryEnum.PIE); } if (obj.toString().equals( "MultipleAxis Chart" )) { stateModel.setCategoryEnum(ChartCategoryEnum.MULTIPLEAXIS); } stateModel.fireModelChanged(); |
stateModel就会触发变更。
而在右边视图中,同样先从内存中取得stateModel,然后将自己加入到观察者队列中(视图必须实现Observer接口):
1 2 3 4 5 6 | @Override public void init(IViewSite site) throws PartInitException { stateModel = (StateModel) site.getPage().getInput(); stateModel.addObserver( this ); super .init(site); } |
响应到主题变更后会自动调用update方法:
1 2 3 4 5 | @Override public void update(Observable o, Object arg) { categoryEnum = stateModel.getCategoryEnum(); draw(); } |
从而实现左右视图的消息传递。
(柱状图)
(坐标图)
下载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?