在RCP应用上使用Jfreechart绘制图表(附源码)

转载自:https://www.cnblogs.com/leefreeman/archive/2012/06/28/2567794.html

在RCP应用上使用Jfreechart绘制图表(附源码)

2012-06-28 16:21 by 飘扬的红领巾, 1900 阅读, 0 评论, 收藏, 编辑

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

第一步、创建RCP程序。

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

image

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

image

第二步、创建视图

    创建视图既可以使用向导创建,也可以手动添加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);

    }

 

}

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

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

image

第三步、在视图中创建树

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

image

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

第四步、创建图表

    先添加一个图表类,以饼图为例,如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类是自定义的一个图表工厂,用于创建指定的图表。做完这些事儿,之后。

image

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

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

为此我们这样做:

添加主题: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();

    }

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

image

(柱状图)

image

(坐标图)

下载

下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值