首页 > 解决方案 > 动态更新观察者中的饼图?

问题描述

我正在使用饼图在JFrame使用 JFreeChart 包中显示一些统计信息。我正在使用PieDataset要传递给该createChart方法。此外,数据集设置为动态更新,因为我在我的应用程序中使用了观察者模式,我对其进行了彻底的调试。我的问题是,尽管能够动态更新数据集,但框架上的饼图并未按原样更新,可能无法获取新的(更新的)值并显示结果。我想知道是否有其他方法可以动态更新饼图。

public void update(Observable observable, Object o) {
    if (o instanceof Game || o instanceof GameController) {
        String label = "<html><head><h1>World Domination View</h1></head><body> ";

        territoriesList = Game.getInstance().getGameMap().getTerritories();
        String[] name = new String[Game.getInstance().getNumPlayers()] ;
        Float[] value = new Float[Game.getInstance().getNumPlayers()];
        for (int i = 0; i < Game.getInstance().getNumPlayers(); i++) {
            int tempTerritoryCount = 0;
            float percentage = 0;

            for (Territory territory : territoriesList) {
                if (territory.getOwner() == Game.getInstance().getPlayerById(i)) {
                    tempTerritoryCount += 1;
                }
            }
            percentage = (float) 100.0 * tempTerritoryCount / Game.getInstance().getGameMap().getTerritories().size();
            label = label + Game.getInstance().getPlayerById(i).getName() + " owns " + percentage
                    + " % territories and owns " + PhaseView.getInstance().curPArmies + "<br/>";
            worldDominationViewLabel.setText(label);
            //dt = createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);

            //createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);
            //for(int j=0; j<Game.getInstance().getNumPlayers();j++){
                name[i] = Game.getInstance().getPlayerById(i).getName();
            //}
            if(name[i] != null)
        {
            value[i] = percentage;
        }


    }
    dt = createDataset(name,value);
    chartPanel = new ChartPanel(createChart(dt));
    chartPanel.setBounds(1024,0,310,300);//390
    chartPanel.setVisible(true);
    frameFromPhase.add(chartPanel);
    worldDominationViewLabel.setText(label + "</body></html>");}}

//the dataset definition
public static PieDataset createDataset(String[] plname,Float[] value){
    DefaultPieDataset dataset = new DefaultPieDataset();
    for(int i =0; i< plname.length;i++){
        dataset.setValue(plname[i],value[i]);

    }
    return dataset;
}

//chart definition
public static JFreeChart createChart(PieDataset dataset ) {
    JFreeChart chart = ChartFactory.createPieChart(
            "Player Map Domination: Territorywise",   // chart title
            dataset,          // data
            true,             // include legend
            true,
            false);

    return chart;
}

标签: javadynamicjfreechartpie-chartswingx

解决方案


正如这里所建议的,不要在每次更改时创建新的数据集和图表;相反,“更新图表的数据模型PieDataset然后监听视图将随之而来。” 接口的实现Observer可以在其方法中更新图表的模型update(),就像罐子的动作处理程序一样JButton。从这个完整的例子开始,我添加了一个空饼图View并修改update()为通过调用setValue()图表的数据集来跟踪猜测。

图片

class View extends JPanel {

    private static final String s = "Click a button.";
    private static final int SIZE = 256;
    private Model model;
    private ColorIcon icon = new ColorIcon(SIZE, Color.gray);
    private JLabel label = new JLabel(s, icon, JLabel.CENTER);
    DefaultPieDataset dataset = new DefaultPieDataset();

    public View(Model model) {
        super(new BorderLayout());
        this.model = model;
        label.setVerticalTextPosition(JLabel.BOTTOM);
        label.setHorizontalTextPosition(JLabel.CENTER);
        this.add(label, BorderLayout.CENTER);
        this.add(genButtonPanel(), BorderLayout.SOUTH);
        PiePlot plot = new PiePlot(dataset);
        plot.setSimpleLabels(true);
        JFreeChart chart = new JFreeChart(null, null, plot, false);
        this.add(new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        }, BorderLayout.WEST);
        model.addObserver(new ModelObserver());
    }
    …    
    private class ModelObserver implements Observer {

        private int pass, fail;

        @Override
        public void update(Observable o, Object arg) {
            if (arg == null) {
                label.setText(s);
                icon.color = Color.gray;
            } else {
                if ((Boolean) arg) {
                    label.setText("Win!");
                    dataset.setValue("Pass", ++pass);
                } else {
                    label.setText("Keep trying.");
                    dataset.setValue("Fail", ++fail);
                }
            }
        }
    }
    …
}

推荐阅读