0

Consider the following code snippets in java: class: GraphPanel.java

package graph_draw;

import graph_draw.LocationPrinter;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
class GraphPanel extends JPanel {

    private Color lineColor = new Color(44, 102, 230, 180);

    private List<Point> graphPoints = null;
    private static Graphics2D gra2;

    public GraphPanel(List<Point> gPoints) {
        graphPoints = gPoints;        
    }    

    @Override
    public void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
        //gra2 = (Graphics2D)g;
          gra2 = (Graphics2D)g.create();

        gra2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        drawGraph(gra2, graphPoints);
    }

    public void drawGraph(Graphics2D g2, List<Point> graphPoints)
    {
        Graphics2D g = (Graphics2D)g2;

        g.setColor(lineColor);

        int x1 = graphPoints.get(0).x;
        int y1 = graphPoints.get(0).y;

        int x2 = graphPoints.get(1).x;
        int y2 = graphPoints.get(1).y;

        int x3 = graphPoints.get(2).x;
        int y3 = graphPoints.get(2).y;

        int x4 = graphPoints.get(3).x;
        int y4 = graphPoints.get(3).y;

        int x5 = graphPoints.get(4).x;
        int y5 = graphPoints.get(4).y;

        g.drawLine(x1, y1, x2, y2);
        g.drawLine(x2, y2, x3, y3);
        g.drawLine(x2, y2, x4, y4);
        g.drawLine(x3, y3, x4, y4);
        g.drawLine(x2, y2, x5, y5);
        g.drawLine(x3, y3, x5, y5);

    }

    public static void drawNewColoredLine(List<Point> lst)
    {
        Graphics2D g21 = (Graphics2D)gra2;  // gra2 is 'null' here. So g21 is null. Hence: NullPointerException.

        g21.setColor(Color.GREEN);
        int SIZE = lst.size();

        for(int i = 0; i < SIZE -1 ; i++)
        {
            int xa = lst.get(i).x;
            int ya = lst.get(i).y;

            int xb = lst.get(i+1).x;
            int yb = lst.get(i+1).y;

            g21.drawLine(xa, ya, xb, yb);
        }       
    }


    public static void createAndShowGui(List<Point> graphPoints) {        

        GraphPanel mainPanel = new GraphPanel(graphPoints);
        mainPanel.setPreferredSize(new Dimension(1366, 768));
        JFrame frame = new JFrame("DrawGraph");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

now the class containing main - class: DriverClass.java

package graph_draw;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class DriverClass {

    public DriverClass() {
        // TODO Auto-generated constructor stub
    }

    public static void main(String[] args)
    {       
        List<Point> graphPoints = new ArrayList<>();

        // add points here.

        graphPoints.add(new Point(358, 237));
        graphPoints.add(new Point(366, 467));
        graphPoints.add(new Point(661, 468));
        graphPoints.add(new Point(636, 229));
        graphPoints.add(new Point(527, 648));

        GraphPanel.createAndShowGui(graphPoints);

        List<Point> ls = new ArrayList<Point>();

        ls.add(graphPoints.get(0));
        ls.add(graphPoints.get(1));
        ls.add(graphPoints.get(3));
        ls.add(graphPoints.get(2));
        ls.add(graphPoints.get(4)); 

        GraphPanel.drawNewColoredLine(ls); // not working.          
    }    
}

Problem: In the last line of the class DriverClass.java, the static method 'drawNewColoredLine' is called containing a list as parameter. I want to use the static object 'gra2' as graphics object for all the methods like 'drawNewColoredLine'.

'gra2' is initialized to a graphics object inside the method 'paintComponent'. 'gra2' works fine for the method 'drawGraph'. But it doesn't woek for the method 'drawNewColoredLine' - a null pointer exception is raised. [ 'gra2' is null inside 'drawNewColoredLine']. So how to make it work inside 'drawNewColoredLine'?

2 Answers 2

1

Is there any reason you use static methods? You should get rid of that. You create object of class GraphPanel, but you don't have reference for that, so after calling another static method you don't have initialized fields, as you expected. Try to remove all statics, remove creating new object inside createAndShowGui and call things like this:

....
GraphPanel graphPanel = new GraphPanel(graphPoints);
graphPanel.createAndShowGui(graphPoints); // actually you don't need to pass it again.
....
graphPanel.drawNewColoredLine(ls);
....
Sign up to request clarification or add additional context in comments.

2 Comments

well i didn't use 'Graphpanel' object to access the methods as inside the method 'createAndShowGui', another 'GraphPanel' type object is created. BUT your answer is not the solution to my question though. :(
when you call GraphPanel.drawNewColoredLine(ls); you don't have reference to object of GraphPanel created inside GraphPanel.createAndShowGui(graphPoints); that's why you have null there. Get rid of statics, it's really bad practice to code like this.
0

The Graphics object received in paintComponent should not be stored. Instead, call all the painting code from within paintComponent, and pass the Graphic2D object to the other painting functions, like you did for drawGraph.

public void paintComponent(Graphics g) 
{
    super.paintComponent(g);
    //gra2 = (Graphics2D)g;
      gra2 = (Graphics2D)g.create();

    gra2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    drawGraph(gra2, graphPoints);
}

public void drawGraph(Graphics2D g, List<Point> graphPoints)
{

    g.setColor(lineColor);
....
....

3 Comments

I want to draw a graph first. Then later at a certain moment I want to highlight a path with a different color in the graph. So I don't want to use all the methods inside 'paintComponent' method. Task 1: Draw the whole graph and Task 2: highlight a path - these two tasks are not supposed to happen together. Depending on application requirement task 2 should be able to be performed later. So I have not used both the methods inside 'paintComponent'.
Ok, then you could use Component.repaint() to trigger repainting. In the paintComponent method, you can find out if the path needs to be drawn or not with a variable of your class.
P.S. the problem with the other approach would be that if the window is minimised, paintComponent is called again, and the colored path disappears.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.