Как обновить набор данных в JFreeChart Bar Chart - PullRequest
0 голосов
/ 05 мая 2018

У меня есть JFrame, в этом кадре есть JPanel, в JPanel есть JFreeChart (диаграмма берет набор данных из метода), и эта диаграмма добавляется в ChartPanel, созданную в JPanel, затем ChartPanel добавляется в JPanel. Также у меня есть JComboBox в JPanel, если я изменю опцию в этом JComboBox, ActionListener обновляет значение набора данных. Также метод, который возвращает набор данных, берет строку из JComboBox (данные набора данных зависят от вывода JComboBox). Поэтому, если я изменю опцию в JComboBox, я бы хотел обновить JFreeChart новым набором данных и отобразить его на экране. Я знаю, что мне нужно добавить код в этот ActionListener, но я не делаю то, что должен добавить, есть ли метод, который обновляет уже созданный JFreeChart?

private class PanelChart extends JPanel { {
    this.setLayout(new BorderLayout());

    // Create Dataset
    //method GUIImplementation.GetDataForChart takes as an input value of combobox

    CategoryDataset dataset = GUIImplementation.GetDataForChart(comboBoxCrimeTypeChart.getSelectedItem().toString());


    //Create chart
    JFreeChart crimeNumberBarChart = ChartFactory.createBarChart(
        "Number of crimes by type", //Chart Title
        "Fallen within", // Category axis
        "Number of crimes", // Value axis
        dataset,
        PlotOrientation.VERTICAL,
        true,true,false
        );
    ChartPanel panelCrimeNumberBarChart = new ChartPanel(crimeNumberBarChart);
    this.add(panelCrimeNumberBarChart, BorderLayout.CENTER);

    PanelChartSouth panelChartSouth = new PanelChartSouth(); //there is a combobox
    this.add(panelChartSouth, BorderLayout.SOUTH);
}}

private class ChartButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == backChart) {
            SizeAndTitleSetter(0);
            SwapPanelChart(0);
        } else if(e.getSource() == comboBoxCrimeTypeChart) { //comboBoxCrimeTypeChart is a JComboBox from PanelChartSouth
            String crimeType = comboBoxCrimeTypeChart.getSelectedItem().toString();
            System.out.println(crimeType);
            dataset = GUIImplementation.GetDataForChart(crimeType); // dataset updated
        }
    }
}

До сих пор мне удалось как-то обновить эту диаграмму, удалив PanelChart из JFrame, затем создать новую PanelChart и добавить ее в JFrame и использовать repaint и revalidate. Это сработало, если я изменил опцию в JComboBox один раз, после второго изменения все начало тормозить на экране, старый график не хотел исчезать, и новый график находился под ним, и я мог видеть его, если я изменил размер экрана.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вы можете обновить существующего набора данных диаграммы, как показано в этих примерах ; при обновлении модели (набора данных) график прослушивания (представление) будет обновляться соответствующим образом; конкретные реализации CategoryDataset обычно обеспечивают подходящие мутаторы.

DefaultCategoryDataset model = …
…
@Override
public void actionPerformed(ActionEvent e) {
    model.setValue(…);
}

Вы можете заменить набор данных существующего графика, используя метод setDataset() соответствующего графика.

CategoryPlot plot = (CategoryPlot) chart.getPlot();
…
@Override
public void actionPerformed(ActionEvent e) {
    plot.setDataset(…);
}

Хотя технически возможно заменить компонент внешнего вида, как предлагается здесь , обычно лучше обновить или заменить модель, как предложено здесь .

0 голосов
/ 05 мая 2018

Я нашел ответ, что он работает, но есть небольшая проблема с ним. Итак, теперь мой ActionListener выглядит так:

private class ChartButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == backChart) {
            SizeAndTitleSetter(0);
            SwapPanelChart(0);
        } else if(e.getSource() == comboBoxCrimeTypeChart) {
            SwingUtilities.invokeLater(() -> {
                frame.remove(panelChart);
                panelChart = new PanelChart();
                frame.add(panelChart);
                frame.pack();
                frame.invalidate();
                frame.revalidate();
                frame.repaint();
            });
        }
    }
}

После того, как я добавил SwingUtilities.invokeLater, он начал работать хорошо, но теперь проблема в том, что программа замедляется после изменения параметра JComboBox несколько раз. Поклонники компьютеров сходят с ума, теперь я не знаю, если это проблема с этой частью кода, или я где-то допустил ошибку. Когда я возвращаюсь в главное меню своей программы и использую другие компоненты, она работает так же, как и раньше.

Я выяснил, почему это начало отставать, в классе PanelChartSouth я добавлял actionListener в JComboBox, и после каждого удаления и создания новой PanelChart в JComboBox добавлялся следующий actionListener. Поэтому, чтобы предотвратить это, я добавил операцию добавления слушателей действия в оператор if

      if(ifActionListenerSet == false) {

        ifActionListenerSet = true;
    ChartButtonListener chartButtonListener = new ChartButtonListener();
    backChart.addActionListener(chartButtonListener);
    comboBoxCrimeTypeChart.addActionListener(chartButtonListener);
    }

Теперь все хорошо.

...