Динамически обновить круговую диаграмму в Обозревателе? - PullRequest
0 голосов
/ 01 апреля 2019

Я использую круговую диаграмму для отображения статистики в 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;
}

1 Ответ

1 голос
/ 03 апреля 2019

Как предлагается здесь , не создавайте новый набор данных и диаграмму с каждым изменением; вместо этого «обновите данные диаграммы модель , PieDataset, и последует прослушивание представление ». Реализация интерфейса Observer может обновить модель диаграммы в ее методе update(), так же как и обработчик действия банки JButton. Начиная с этого полного примера , я добавил пустую круговую диаграмму в View и изменил update() для отслеживания догадок, вызвав setValue() в наборе данных диаграммы.

image

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