Java 2D API: Null Pointer Exception

2019-09-02 19:35发布

问题:

Please have a look at the following code

package java2D;

import java.awt.BasicStroke;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;
import java.awt.*;

public class Joins extends JFrame
{
    private JPanel centerPanel;

    public Joins()
    {   
        this.setLayout(new BorderLayout());
        this.add(createCenterPanel(),"Center");

        this.setSize(200,250);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private JPanel createCenterPanel()
    {
        centerPanel = new JPanel();
        //centerPanel.setLayout(new FlowLayout());

        Graphics g = centerPanel.getGraphics();

        Graphics2D g2d =  (Graphics2D)g;

        BasicStroke bs1 = new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
        g2d.setStroke(bs1);
        g2d.drawRect(15, 15, 80, 50);

        BasicStroke bs2 = new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
        g2d.setStroke(bs2);
        g2d.drawRect(125, 15, 80, 50);

        BasicStroke bs3 = new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2d.setStroke(bs3);
        g2d.drawRect(235, 15, 80, 50);


        return centerPanel;
    }

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

            @Override
            public void run() {
                new Joins();
            }
        });
    }
}

This code generates NullPointerException. I need to draw the graphics inside the centerPanel. When I develop Swing applications, I normally divide the JFrame area into number of JPanels, and I did it here too, but ended up with NullPointerException!

Following is the error

run:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at java2D.Joins.createCenterPanel(Joins.java:34)
    at java2D.Joins.<init>(Joins.java:17)
    at java2D.Joins$1.run(Joins.java:55)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
BUILD SUCCESSFUL (total time: 6 seconds)

Please help!

回答1:

As has already been pointed out, Graphics g = centerPanel.getGraphics(); is the source of your problem.

You should never use getGraphics to perform custom painting. At best getGraphics is a snapshot of the last paint cycle, at worst, well, you've seen the worst result, it's null

To perform custom painting you should create yourself a custom component (from something like a JPanel for example) and override its paintComponent method (don't forget to call super.paintComponet)

Take a look at Performing Custom Painting for more details



回答2:

Don't use getGraphics. Create a new JPanel and place your paint functionality into the paintComponent method remembering to call super.paintComponent(g).



回答3:

The mistake is at:

Graphics g = centerPanel.getGraphics();

According to javadocs:

Creates a graphics context for this component. This method will return null if this component is currently not displayable.

Maybe you need to first add the JPanel to your Joins frame, so after you can use getGraphics()?



回答4:

Nothing is visible, thus getGraphics() returns null. Try:

    centerPanel = new JPanel();
    JFrame frame = new JFrame();
    frame.add(centerPanel);
    frame.setVisible(true);
    centerPanel.setVisible(true);