NullPointerException when using Double Buffer in swing

倖福魔咒の 提交于 2019-12-12 12:46:13

问题


In the following code i'm using a doubleBuffer to avoid flickering of the image as was suggested in this question of mine

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class TestProgram extends JFrame implements KeyListener {
    private Image doubleBuffer;
    private Graphics myGraphics;
    private BufferedImage TestImage;
    private int cordX = 100;
    private int cordY = 100;

    public TestProgram() {
        setTitle("Testing....");
        setSize(500,500);
        imageLoader();
        setVisible(true);
    }

    public static void main(String[] args) {
        new TestProgram();
    }

    public void imageLoader() {
        try {
            String testPath = "test.png";
            TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));

        } catch (IOException ex) {
            ex.printStackTrace();
        }

        addKeyListener(this);

        doubleBuffer = createImage(getWidth(), getHeight());
        myGraphics = doubleBuffer.getGraphics();
        drawImages();
    }

    @Override
    public void update(Graphics g) {
        drawImages();
        g.drawImage(doubleBuffer, 0, 0, this);        
    }

    public void drawImages() {
        myGraphics.drawImage(TestImage, cordX, cordY, this);
    }



    public void keyPressed(KeyEvent ke) {
        switch (ke.getKeyCode()) {
            case KeyEvent.VK_RIGHT: {
                cordX+=5;
            }
            break;
            case KeyEvent.VK_LEFT: {
                cordX-=5;
            }
            break;
            case KeyEvent.VK_DOWN: {
                cordY+=5;
            }
            break;
            case KeyEvent.VK_UP: {
                cordY-=3;
            }
            break;
        }
        repaint();
    }

    public void keyTyped(KeyEvent ke) {}

    public void keyReleased(KeyEvent ke) {}
}

The problem is that im getting a nullPointerException at this line

myGraphics = doubleBuffer.getGraphics();

is my approach correct in doing this? Please help. thanks


回答1:


  1. don't paint to JFrame directly, put there JPanel or JComponent

  2. Swing GUI should be starting from Initial Thread

  3. whats TestImage and path to the Image???,

  4. KeyListener isn't designated for Swing JComponents, use KeyBindings instead

  5. after coordinates changed you have to call repaint()

  6. put that altogether

.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;

public class MoveIcon extends JPanel {

    private static final long serialVersionUID = 1L;
    private static final String IMAGE_PATH = "http://duke.kenai.com/misc/Bullfight.jpg";
    private static final String IMAGE_PATH_PLAYER = "http://duke.kenai.com/iconSized/duke4.gif";
    public static final int STEP = 3;
    private static final int TIMER_DELAY = STEP * 8;
    private BufferedImage bkgrndImage = null;
    private BufferedImage playerImage = null;
    private Map<Direction, Boolean> directionMap = new HashMap<Direction, Boolean>();
    private int playerX = 0;
    private int playerY = 0;

    enum Direction {

        UP(KeyEvent.VK_UP, 0, -1), DOWN(KeyEvent.VK_DOWN, 0, 1),
        LEFT(KeyEvent.VK_LEFT, -1, 0), RIGHT(KeyEvent.VK_RIGHT, 1, 0);
        private int keyCode;
        private int xDirection;
        private int yDirection;

        private Direction(int keyCode, int xDirection, int yDirection) {
            this.keyCode = keyCode;
            this.xDirection = xDirection;
            this.yDirection = yDirection;
        }

        public int getKeyCode() {
            return keyCode;
        }

        public int getXDirection() {
            return xDirection;
        }

        public int getYDirection() {
            return yDirection;
        }
    }

    public MoveIcon() {
        try {
            URL bkgrdImageURL = new URL(IMAGE_PATH);
            URL playerImageURL = new URL(IMAGE_PATH_PLAYER);
            bkgrndImage = ImageIO.read(bkgrdImageURL);
            playerImage = ImageIO.read(playerImageURL);
            setPreferredSize(new Dimension(bkgrndImage.getWidth(), bkgrndImage.getHeight()));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (Direction direction : Direction.values()) {
            directionMap.put(direction, false);
        }
        setKeyBindings();
        Timer timer = new Timer(TIMER_DELAY, new TimerListener());
        timer.start();
    }

    private void setKeyBindings() {
        InputMap inMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actMap = getActionMap();
        for (final Direction direction : Direction.values()) {
            KeyStroke pressed = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, false);
            KeyStroke released = KeyStroke.getKeyStroke(direction.getKeyCode(), 0, true);
            inMap.put(pressed, direction.toString() + "pressed");
            inMap.put(released, direction.toString() + "released");
            actMap.put(direction.toString() + "pressed", new AbstractAction() {

                private static final long serialVersionUID = 1L;

                @Override
                public void actionPerformed(ActionEvent e) {
                    directionMap.put(direction, true);
                }
            });
            actMap.put(direction.toString() + "released", new AbstractAction() {

                private static final long serialVersionUID = 1L;

                @Override
                public void actionPerformed(ActionEvent e) {
                    directionMap.put(direction, false);
                }
            });
        }

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (bkgrndImage != null) {
            g.drawImage(bkgrndImage, 0, 0, null);
        }
        if (playerImage != null) {
            g.drawImage(playerImage, playerX, playerY, null);
        }
    }

    private class TimerListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            boolean moved = false;
            for (Direction direction : Direction.values()) {
                if (directionMap.get(direction)) {
                    playerX += STEP * direction.getXDirection();
                    playerY += STEP * direction.getYDirection();
                    moved = true;
                }
            }
            if (moved) {
                int x = playerX - 2 * STEP;
                int y = playerY - 2 * STEP;
                int w = playerImage.getWidth() + 4 * STEP;
                int h = playerImage.getHeight() + 4 * STEP;
                MoveIcon.this.repaint(x, y, w, h); // !! repaint just the player
            }
        }
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("MoveIcon");
        frame.getContentPane().add(new MoveIcon());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                createAndShowUI();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/10879210/nullpointerexception-when-using-double-buffer-in-swing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!