NullPointerException on Java graphics

后端 未结 2 1583
难免孤独
难免孤独 2021-01-26 19:30

I\'m trying to implement a method to paint a specific portion of a grid. To do so I overrided the paintComponent method:

public class Frame extends JPanel {
...
         


        
相关标签:
2条回答
  • 2021-01-26 20:02

    Change

    public void specificPaint(int coordinateX, int coordinateY, Color color)
    

    to

    public void specificPaint(int coordinateX, int coordinateY, Color color, Graphics g)
    

    Then call specificPaint inside your paintComponent method with the Graphics object you are drawing with

    See Hovercraft's answer for more details as to why using this.getGraphics() doesn't work

    0 讨论(0)
  • 2021-01-26 20:22

    Never do this when getting a Graphics object from a component:

    Graphics g = this.getGraphics();
    

    The Graphics object thus obtained will not be long-lived, and this can result in either NPE (like you're getting) or an image that does not persist on repaints. Instead, do your drawing within the paintComponent method. Note that you can call repaint(...) and specify a particular Rectangle to paint by passing in a Rectangle parameter.

    Note that you can call getGraphics() on a BufferedImage and draw to it, and then draw the BufferedImage within your paintComponent method if you want to do spot drawing that does not move.

    An unrelated recommendation: Avoid calling your class Frame as this can result in a name clash with the java.awt.Frame class if you're not careful.

    For example:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class MyPanel extends JPanel {
        private static final int PREF_W = 400;
        private static final int PREF_H = PREF_W;
        private int cols;
        private int rows;
        private static final Color BG = Color.BLACK;
        private static final int GAP = 1;
        private BufferedImage img;
        private int rectWidth;
        private int rectHeight;
    
        public MyPanel(int rows, int cols) {
            this.cols = cols;
            this.rows = rows;
            img = createMyImage();
        }
    
        public void specificPaint(int coordinateX, int coordinateY, Color color) {
            Graphics g = img.getGraphics(); // get img's Graphics object
            int x = coordinateX * this.rectWidth + GAP;
            int y = coordinateY * this.rectHeight + GAP;
            g.setColor(color);
            g.fillRect(x, y, rectWidth - 2 * GAP, rectWidth - 2 * GAP);
            g.dispose();
            repaint();
        }
    
        private BufferedImage createMyImage() {
            img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = img.createGraphics();
            g2.setBackground(BG);
            g2.clearRect(0, 0, img.getWidth(), img.getHeight());
            this.rectWidth = img.getWidth() / cols;
            this.rectHeight = img.getHeight() / rows;
    
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    int x = i * this.rectWidth + GAP;
                    int y = j * this.rectHeight + GAP;
                    g2.setColor(Color.WHITE);
                    g2.fillRect(x, y, this.rectWidth - 2 * GAP, this.rectHeight - 2 * GAP);
                }
            }
            g2.dispose();
            return img;
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                g.drawImage(img, 0, 0, this);
            }
    
            // if you need to draw changing non-static images, do it here
        }
    
        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet() || img == null) {
                return super.getPreferredSize();
            }
            int w = img.getWidth();
            int h = img.getHeight();
            return new Dimension(w, h);
        }
    
        private static void createAndShowGui() {
            MyPanel modelMap = new MyPanel(50, 50);
            JFrame frame = new JFrame("MyPanel");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(modelMap);
            frame.pack();
            frame.setResizable(false);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
            modelMap.specificPaint( 40,40,Color.RED );
            modelMap.specificPaint( 10,10,Color.RED );
            modelMap.specificPaint( 20,25,Color.BLUE );
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGui();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题