问题
I'm getting a java.lang.NullPointerException on my super.paintComponent(e) line, I have looked at a few tutorials but I'm unsure of what I'm doing wrong.
Heres my Main class:
package pack;
public class Main {
public static void main(String[] args){
@SuppressWarnings("unused")
Display display = new Display("The JFrame", 510, 510);
Game game = new Game();
game.start();
}
}
Display class:
package pack;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Display {
private JFrame frame;
private String title;
private int width, height;
private static JPanel canvas;
public Display(String title, int width, int height) {
this.title = title;
this.width = width;
this.height = height;
createDisplay();
}
private void createDisplay(){
frame = new JFrame(title);
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
canvas = new JPanel();
canvas.setPreferredSize(new Dimension(width, height));
canvas.setMaximumSize(new Dimension(width, height));
canvas.setMinimumSize(new Dimension(width, height));
frame.add(canvas);
frame.pack();
}
public static JPanel getCanvas(){
return canvas;
}
}
And finaly the Game class where the error occurs:
package pack;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Game extends JPanel implements Runnable {
private Thread thread;
private boolean running = false;
public Graphics e;
public synchronized void stop() {
if(running = false){
return;
}
running = false;
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void start() {
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
@SuppressWarnings("unused")
int ticks = 0;
long timer = 0;
while(running) {
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if(delta >= 1){
paintComponent(e); //ERROR LINE
ticks++;
delta--;
}
if(timer >= 1000000000){
ticks = 0;
timer = 0;
}
}
stop();
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
}
}
If I replace
super.paintComponent(e)
with
g = Display.getCanvas().getGraphics();
The error no longer occurs.
回答1:
Change:
paintComponent(g);
To:
repaint(); //will cause a call to paintComponent with a VALID graphics instance
Working implementation. Besides fixing the error, this code adds an instance of the Game
to the frame so it is visible, and does something useful in the paintComponent(..)
override so that it can be seen to do anything.
import java.awt.*;
import javax.swing.*;
public class Display {
private JFrame frame;
private String title;
private int width, height;
private static Game canvas;
public Display(String title, int width, int height) {
this.title = title;
this.width = width;
this.height = height;
createDisplay();
}
private void createDisplay() {
frame = new JFrame(title);
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
canvas = new Game();
canvas.start();
canvas.setPreferredSize(new Dimension(width, height));
canvas.setMaximumSize(new Dimension(width, height));
canvas.setMinimumSize(new Dimension(width, height));
frame.add(canvas);
frame.pack();
}
public static JPanel getCanvas() {
return canvas;
}
public static void main(String[] args) {
Display display = new Display("The JFrame", 510, 510);
}
}
class Game extends JPanel implements Runnable {
private Thread thread;
private boolean running = false;
public synchronized void stop() {
if (running = false) {
return;
}
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void start() {
if (running) {
return;
}
running = true;
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
@SuppressWarnings("unused")
int ticks = 0;
long timer = 0;
while (running) {
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if (delta >= 1) {
//paintComponent(e); //ERROR LINE
repaint();
ticks++;
delta--;
}
if (timer >= 1000000000) {
ticks = 0;
timer = 0;
}
}
stop();
}
int x=0;
int y=0;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, x++, y++);
}
}
来源:https://stackoverflow.com/questions/28916103/java-lang-nullpointerexception-on-super-paintcomponentg