How do you add a XChart PieChart to an existing Java GUI?

1k views Asked by At

Recently I asked a question similar to this but didn't give enough info and my code was too long for a code review. I have written a new file with the same bare bones as my previous post. Here I'm reaching the same issues once again.

When I attempt to click the Show Graph button, I get the following Error:

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
          at org.knowm.xchart.XChartPanel.<init>(XChartPanel.java:65)
          at testMain$1.actionPerformed(testMain.java:78)"

Here is my code:

import java.awt.*;

import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.table.DefaultTableModel;

import org.knowm.xchart.PieChart;
import org.knowm.xchart.PieChartBuilder;
import org.knowm.xchart.SwingWrapper;
import org.knowm.xchart.XChartPanel;
import org.knowm.xchart.style.PieStyler.AnnotationType;
import org.knowm.xchart.style.Styler.ChartTheme;
import org.knowm.xchart.style.Styler.LegendPosition;


    public class testMain extends JFrame {

       private static final long serialVersionUID = 1L;
       private JPanel gui, choiceBar,insertPanel;
       private XChartPanel chartPanel;
       private JButton showGraph;
       private PieChart chart;

      public testMain() {

        this.setTitle("Test Frame");
        this.setSize(500, 500);
        JPanel gui = new JPanel(new BorderLayout());

        //choice bar testing
        choiceBar = new JPanel(new FlowLayout());

        // Radio button group
        JRadioButton halfhalf = new JRadioButton("Split half");
        JRadioButton quarters = new JRadioButton("Split quarters");
        ButtonGroup group1 = new ButtonGroup();
        group1.add(halfhalf); group1.add(quarters);

        //add to choice bar
        choiceBar.add(halfhalf); choiceBar.add(quarters);

        //Side panel for inserting user values
        insertPanel = new JPanel();
        GroupLayout groupLayout = new GroupLayout(insertPanel);
        groupLayout.setAutoCreateGaps(true);
        groupLayout.setAutoCreateContainerGaps(true);


        //Display Button
        JButton showGraph = new JButton("Show Graph");
        JLabel showGraphLabel = new JLabel("Finish");

        //JTextfield for inserting value
        JTextField value = new JTextField("value");
        JLabel valueLabel = new JLabel("Insert value here:");

        // Grouping JTextFields
        GroupLayout.SequentialGroup groupH = groupLayout.createSequentialGroup();
        GroupLayout.SequentialGroup groupV = groupLayout.createSequentialGroup();

        groupH.addGroup(groupLayout.createParallelGroup().addComponent(valueLabel).addComponent(showGraphLabel));
        groupH.addGroup(groupLayout.createParallelGroup().addComponent(value).addComponent(showGraph));
        groupLayout.setHorizontalGroup(groupH);
        groupV.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE).addComponent(valueLabel).addComponent(value));
        groupV.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE).addComponent(showGraphLabel).addComponent(showGraph));
        groupLayout.setVerticalGroup(groupV);

        showGraph.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                String valueText = value.getText();
                double valueAmount = Double.parseDouble(valueText);
                if (halfhalf.isSelected()) {
                    chartPanel = new XChartPanel(chart);
                    chart = new PieChartBuilder().width(600).height(400).title("Split By").theme(ChartTheme.GGPlot2).build();
                    chart.getStyler().setLegendVisible(false);
                    chart.getStyler().setAnnotationType(AnnotationType.LabelAndPercentage);
                    chart.getStyler().setAnnotationDistance(1.15);
                    chart.getStyler().setPlotContentSize(.7);
                    chart.getStyler().setStartAngleInDegrees(90);
                    chart.addSeries("1", valueAmount/2);
                    chart.addSeries("2", valueAmount/2);

                    new SwingWrapper(chart).displayChart();
                    gui.add(chartPanel, BorderLayout.SOUTH);
                    gui.validate();
                    gui.repaint();

                }
                else {
                    chartPanel = new XChartPanel(chart);
                    chart = new PieChartBuilder().width(600).height(400).title("Split By").theme(ChartTheme.GGPlot2).build();
                    chart.getStyler().setLegendVisible(false);
                    chart.getStyler().setAnnotationType(AnnotationType.LabelAndPercentage);
                    chart.getStyler().setAnnotationDistance(1.15);
                    chart.getStyler().setPlotContentSize(.7);
                    chart.getStyler().setStartAngleInDegrees(90);
                    chart.addSeries("1",valueAmount/4);
                    chart.addSeries("2", valueAmount/4);
                    chart.addSeries("3", valueAmount/4);
                    chart.addSeries("4", valueAmount/4);

                    new SwingWrapper(chart).displayChart();
                    gui.add(chartPanel, BorderLayout.SOUTH);
                    gui.validate();
                    gui.repaint();
                }
            }

        });
        // add to gui
        gui.add(choiceBar, BorderLayout.NORTH);
        gui.add(insertPanel, BorderLayout.WEST);
        this.add(gui);


    }
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                testMain frame = new testMain();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.setVisible(true);
                frame.setLocationRelativeTo(null);
            }
        });
    }
}
`

I'm trying to write a Java GUI where once the user clicks the button, the graph shows up on the same GUI. I still would like to implement this using nested layouts as I like the clean look. Someone mentioned that I could use cardLayout but I think that would be too cluttered.

Thanks, and any help is apprecaited.

0

There are 0 answers