zoukankan      html  css  js  c++  java
  • 在RCP应用上使用Jfreechart绘制图表(附源码)

            下午闲来无事,找出Jfreechart来复习一下,做了个在RCP上使用Jfreechart的小程序。

    第一步、创建RCP程序。

        在Eclipse中,使用向导创建Eclipse插件程序:

    image

    后面就不说了,填写相应项,一路下去,创建好Eclipse插件程序,运行可以看到:

    image

    第二步、创建视图

        创建视图既可以使用向导创建,也可以手动添加Java类,如添加类似这样的类:

    public class ChartCategoryViewPart extends ViewPart

    然后在Perspective .java中将创建的视图添加到透视图中:

    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);
    	}
    
    }

    代码就不详细讲解了,最后会把整个例子的源代码共享出来。

    创建了视图,应用程序运行起来就会是这样子:

    image

    第三步、在视图中创建树

    在创建好的视图类中,添加创建树的代码,代码有点多不贴了,可以到附件中下载。

    image

    上图创建了一个树,表示将要在右边视图显示的图表的类别(柱状图、坐标图、饼图)

    第四步、创建图表

        先添加一个图表类,以饼图为例,如PieChart.java。

    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;
    	}
    }

    完成图表类之后,想要在视图中显示它,必须完成下面的工作:

    @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类是自定义的一个图表工厂,用于创建指定的图表。做完这些事儿,之后。

    image

    第五步、实现视图间的通信

        简单的来说,就是点击左边的树节点,右边视图中的图表根据点击的节点做相应的更新。实现此功能有很多种方法,常用的方法是在左边视图中,取得右边视图的句柄,然后调用其相关的方法,实现更新。但此方法耦合性较高,不便于扩展,我们不推荐此方法。这里我们使用观察者模式来实现此功能,也就说创建一个被观察者(主题),让视图作为观察者,监听其变化,当监听到主题变化时,做更新图表的操作。而左边视图所做的事情就是在用户点击时,改变主题的内容,触发它的变化。

    为此我们这样做:

    添加主题:StateModel.java

    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();
    	}
    }

    在应用程序启动时,放置到系统内存中:

    @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(主题):

    @Override
    	public void init(IViewSite site) throws PartInitException {
    		stateModel = (StateModel) site.getPage().getInput();
    		super.init(site);
    	}

    然后点击事件中:

    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接口):

    @Override
    	public void init(IViewSite site) throws PartInitException {
    		stateModel = (StateModel) site.getPage().getInput();
    		stateModel.addObserver(this);
    		super.init(site);
    	}

    响应到主题变更后会自动调用update方法:

    @Override
    	public void update(Observable o, Object arg) {
    		categoryEnum = stateModel.getCategoryEnum();
    		draw();
    	}

    从而实现左右视图的消息传递。

    image

    (柱状图)

    image

    (坐标图)

    下载

    下载地址

  • 相关阅读:
    #include <utility>
    Html的空格显示
    ExtJs自学教程(1):一切从API開始
    天黑的时候,我又想起那首歌
    citrix协议ICA技术原理
    约瑟夫环问题
    数据结构和算法设计专题之---八大内部排序
    HDU
    深入分析C++引用
    八大排序算法总结
  • 原文地址:https://www.cnblogs.com/leefreeman/p/2567794.html
Copyright © 2011-2022 走看看