为什么我的图形程序中出现线程异常



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();
                    }
                });
            }
        });
    }
}

相关内容

  • 没有找到相关文章

最新更新