Quesiton:所以我正在尝试创建一个程序,其中球在JFrame上来回弹跳(稍后会变得更重,所以我使用Canvas)。但是,当我尝试运行代码时,我收到以下错误以及一个空白窗口:(任何帮助将不胜感激)
错误:
Exception in thread "Thread-1" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)
at sun.java2d.opengl.CGLGraphicsConfig.createCompatibleImage(CGLGraphicsConfig.java:200)
at java.awt.GraphicsConfiguration.createCompatibleImage(GraphicsConfiguration.java:178)
at sun.awt.image.SunVolatileImage.getBackupImage(SunVolatileImage.java:236)
at sun.awt.image.VolatileSurfaceManager.getBackupSurface(VolatileSurfaceManager.java:263)
at sun.awt.image.VolatileSurfaceManager.initialize(VolatileSurfaceManager.java:126)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:88)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:98)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:109)
at sun.java2d.opengl.CGLGraphicsConfig.createBackBufferImage(CGLGraphicsConfig.java:356)
at sun.lwawt.LWCanvasPeer.createBuffers(LWCanvasPeer.java:62)
at java.awt.Component$FlipBufferStrategy.createBuffers(Component.java:4016)
at java.awt.Component$FlipBufferStrategy.<init>(Component.java:3956)
at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Component.java:4479)
at java.awt.Component.createBufferStrategy(Component.java:3833)
at java.awt.Canvas.createBufferStrategy(Canvas.java:194)
at java.awt.Component.createBufferStrategy(Component.java:3756)
at java.awt.Canvas.createBufferStrategy(Canvas.java:169)
at gpractice.Window.render(Window.java:37)
at gpractice.Window.run(Window.java:54)
at java.lang.Thread.run(Thread.java:724)
这是我的主 Window 类和 Prisoner 类的代码:
窗口类的代码
public class Window extends Canvas implements Runnable{
static Window game = new Window();
static Prisoner pris;
static Cop cop;
static Boolean running = false;
private Thread thread;
public static void main(String[]args){
JFrame frame = new JFrame("Java Sucks!");
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setSize(600, 500);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.add(game);
game.start();
}
public void init(){
cop = new Cop();
pris = new Prisoner();
}
public void render(){
BufferStrategy bs = this.getBufferStrategy();
if (bs == null)
{
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
//Background///////////////
g2d.fillRect(0, 0, 600, 500);
///////////////////////////
pris.render(g);
g.dispose();
bs.show();
}
public void run() {
init();
while (running){
render();
}
stop();
}
private synchronized void start() {
if (running){
return;
}
else{
running = true;
}
thread = new Thread(this);
thread.start();
}
private void stop() {
if (!running){
return;
}
else{
running = false;
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
}
囚犯班代码
public class Prisoner {
private int x = 0;
private int y = 0;
private int dx, dy=0;
Cop cop = new Cop();
public Prisoner(){
x = 250;
y = 200;
dx = 1;
dy = 1;
}
public void render(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.fillOval(x,y,50,50);
move();
}
public void move(){
if (x <= 0){
dx = 1;
}
if (y <= 0){
dy = 1;
}
if (x >= 550){
dx = -1;
}
if (y >=430){
dy = -1;
}
x += dx;
y += dy;
}
}
来自 Cop 类的代码(将来会用到,所以里面不多)
public class Cop {
private int x;
private int y;
public Cop()
{
x = 0;
y= 0;
}
public void render(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fillOval(x, y, 50, 50);
}
}
在"开始"游戏之前,请确保窗口已正确实现(附加到本机对等体)并调整大小。
还应确保在事件调度线程的上下文中创建 UI
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Java Sucks!");
frame.setResizable(false);
frame.add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
game.start();
}
});
}
});
}
因为框架还包括框架装饰,所以可视量可能比物理窗口大小小,而不是依赖于幻数,应该从组件本身取值
利用getPreferredSize
让窗口的布局管理器了解您希望组件的大小,并JFrame#pack
将窗口打包在内容周围......
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 500);
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
//Background///////////////
g2d.fillRect(0, 0, getWidth(),getHeight());
///////////////////////////
pris.render(g);
g.dispose();
bs.show();
}
另外,删除static
声明,它们真的很危险,并且随着代码复杂性的增加而变得有问题,而不是在static main
中创建 UI,使用其他一些非静态驱动程序来初始化 UI
public class MyAwesomeGame {
public static void main() {
new MyAwesomeGame()
}
public MyAwesomeGame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Window game = new Window();
JFrame frame = new JFrame("Java Sucks!");
frame.setResizable(false);
frame.add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
game.start();
}
});
}
});
}
}