Search code examples
javaarraysparameter-passingpaintcomponent

pass an array to a paint component class?


I have another beginner's question that hopefully someone can help with.

I'm trying to pass an array from one class to another in order to use it to produce a bar graph. I know I can pass an array as a parameter but I'm getting some errors and am basically a bit lost. The basic code for the classes for the chart are below. Supposing I want to pass "anArray" from "AnotherClass", can anyone tell me exactly how I should pass it?

I've tried passing it as a parameter of JBChart & chartComponent but I think I need it to be in paintComponent? As it already has "Graphics g" as parameter, I am rather confused. Anyway, either of those two and I get nullPointer errors (although I know I could be doing something else wrong too).

Here's the basic code for the chart classes. Any ideas very much appreciated:

public class JBChart extends JFrame {

    public JBChart()    {}

    public void buildChart()
    {   
        ChartComponent component = new ChartComponent();
        chartFrame.add(component);                           
        chartFrame.setVisible(true);
    }
}
public class ChartComponent extends JComponent {
    public ChartComponent() {}

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
    }

--

-EDIT-

This is the first few lines of one of the stack traces (I hope that's enough?): --

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at ChartComponent.<init>(ChartComponent.java:43) at JBChart.<init>(JBChart.java:32) 
at JavaBallGUI.displayBarChart(JavaBallGUI.java:273) 
at JavaBallGUI.actionPerformed(JavaBallGUI.java:310) 

-- The line it points to is:

for (int i = 0; i < teamObjects.length; i++) 
{ 
    if (teamObjects[i] != null) 
    { 
    teamName = teamObjects[i].getTeamName(); 
    System.out.println(teamName); 
    } 
} 

Solution

  • You should probably pass it to the constructor:

    public class ChartComponent extends JComponent {
        private final int[] values; // For example
    
        public ChartComponent(int[] values) {
            this.values = values;
        }
    
        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D) g;
        }
    }
    

    Note that this will still allow either class to change the values within the array afterwards, as they've both got a reference to the same mutable object. There are various ways round this, depending on exactly what you're trying to do. You'd then use:

    ChartComponent component = new ChartComponent(array);
    

    Alternatively, you could always create setter methods on the ChartComponent and call those at the appropriate time. You won't be able to change the signature of paintComponent and still get the behaviour you want, so you'll need to provide the data before the method is called.