Graphics.drawimage无法正常使用Java 8

时间:2014-07-15 21:59:14

标签: java swing graphics thread-sleep

我一直在使用Graphics.drawImage很长时间来渲染图像,但是在我安装了java 8后,它停止了工作。没有错误。我不明白发生了什么。

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class Game implements Runnable {
    private BufferedImage img = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);

    private boolean running;

    private Thread thread;

    private JFrame f;
    private Canvas c;

    public Game() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gs = ge.getScreenDevices();
        for (GraphicsDevice gd : gs) {
            GraphicsConfiguration[] gc = gd.getConfigurations();
            for (GraphicsConfiguration gc1 : gc) {
                f = new JFrame("Title", gd.getDefaultConfiguration());
                c = new Canvas(gc1);
                f.getContentPane().add(c);
                f.setUndecorated(false);
                f.setIgnoreRepaint(true);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setSize(700, 600);
                f.setResizable(false);
                f.setLocationRelativeTo(null);
                f.setFocusable(true);
                f.setVisible(true);
            }
        }
    }

    public void init() {
        img.getGraphics().drawImage(img, 0, 0, Color.BLACK, null);
    }

    @Override
    public void run() {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000D / 60;

        int ticks = 0;
        int frames = 0;

        long lastTimer = System.currentTimeMillis();
        double delta = 0;

        init();

        while (running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / nsPerTick;
            lastTime = now;
            boolean shouldRender = true;

            while (delta >= 1) {
                ticks++;
                tick();
                delta -= 1;
                shouldRender = true;
            }

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }

            if (shouldRender) {
                frames++;
                render();
            }

            if (System.currentTimeMillis() - lastTimer >= 1000) {
                lastTimer += 1000;
                frames = 0;
                ticks = 0;
            }
        }
    }

    public synchronized void start() {
        running = true;

        thread = new Thread(this, "GAME");
        thread.start();
    }

    public synchronized void stop() {
        running = false;

        try {
            thread.join();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args) {
        new Game().start();
    }

    public void tick() { /*player movement, ect*/ }

    public void render() {
        c.createBufferStrategy(3);
        BufferStrategy bs = c.getBufferStrategy();

        Graphics g = bs.getDrawGraphics();
        g.drawImage(img, 100, 100, null);
        //I should also not that strings won't draw either.
        g.drawString("Hello, world", 50, 50);
        g.dispose();
        bs.show();
    }
}

我不明白为什么这不起作用,因为它在java 7中运行良好,我在安装java 8之前或之后没有对我的代码进行任何更改。 我也在使用MacBook pro,如果有帮助的话。

1 个答案:

答案 0 :(得分:4)

在Mac OS X版本10.9.4上,我可以验证createBufferStrategy(2)是否在Java 8下工作,而createBufferStrategy(3)失败,除非我恢复到Java 7.顺便说一句,请注意Swing GUI对象应该在event dispatch thread构建和操纵。

image

经测试:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import java.awt.EventQueue;

public class Game implements Runnable {
    private BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    private boolean running;
    private Thread thread;
    private JFrame f;
    private Canvas c;

    public Game() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gs = ge.getScreenDevices();
        for (GraphicsDevice gd : gs) {
            GraphicsConfiguration[] gc = gd.getConfigurations();
            for (GraphicsConfiguration gc1 : gc) {
                f = new JFrame("Title", gd.getDefaultConfiguration());
                c = new Canvas(gc1);
                f.add(c);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setSize(360, 300);
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        }
    }

    public void init() {
        img.getGraphics().drawImage(img, 0, 0, Color.BLUE, null);
    }

    @Override
    public void run() {
        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000D / 60;

        int ticks = 0;
        int frames = 0;

        long lastTimer = System.currentTimeMillis();
        double delta = 0;

        init();

        while (running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / nsPerTick;
            lastTime = now;
            boolean shouldRender = true;

            while (delta >= 1) {
                ticks++;
                tick();
                delta -= 1;
                shouldRender = true;
            }

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }

            if (shouldRender) {
                frames++;
                render();
            }

            if (System.currentTimeMillis() - lastTimer >= 1000) {
                lastTimer += 1000;
                frames = 0;
                ticks = 0;
            }
        }
    }

    public synchronized void start() {
        running = true;
        thread = new Thread(this, "GAME");
        thread.start();
    }

    public synchronized void stop() {
        running = false;

        try {
            thread.join();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

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

            @Override
            public void run() {
                new Game().start();
            }
        });
    }

    public void tick() { /*player movement, ect*/ }

    public void render() {
        c.createBufferStrategy(2);
        BufferStrategy bs = c.getBufferStrategy();
        Graphics g = bs.getDrawGraphics();
        g.drawImage(img, 100, 100, null);
        g.drawString("Hello, world: " + System.currentTimeMillis(), 50, 50);
        g.dispose();
        bs.show();
    }
}