画布未绘制到JFrame [英] Canvas not drawing to JFrame

查看:103
本文介绍了画布未绘制到JFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找答案,多次重写了我的代码,仍然一无所获.本质上,我试图绘制一个仅包含一个简单矩形的JFrame,但是每次在Frame中都没有显示任何东西时-它只是空白.

I've been looking around for an answer to this, re-written my code multiple times, still nothing. Essentially I am trying to draw to a JFrame containing just a simple rectangle, yet each time nothing shows in the Frame - its just blank.

package com.Graphics;

import java.awt.*;
import java.awt.image.*;
import javax.swing.*;

public class GraphicsMain {

    public static void main(String[] args) {

        GraphicsMain myGraphics = new GraphicsMain();

        myGraphics.createDisplay();

    }

    void createDisplay(){

        int width = 500;
        int height = 500;
        String title = "TestFrame";
        Graphics g;

        Canvas myCanvas = new Canvas();
        JFrame myFrame = new JFrame(title);

        myFrame.setVisible(true);
        myFrame.setResizable(false);
        myFrame.setSize(width, height);
        myFrame.setLocationRelativeTo(null);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        myCanvas.setPreferredSize(new Dimension(500, 500));
        myCanvas.setMaximumSize(new Dimension(500, 500));
        myCanvas.setMinimumSize(new Dimension(500, 500));

        myFrame.add(myCanvas);
        myFrame.pack();

        myCanvas.createBufferStrategy(2);

        BufferStrategy bs = myCanvas.getBufferStrategy();

        g = bs.getDrawGraphics();

        g.setColor(Color.red);
        g.fillRect(10, 50, 50, 70);

        bs.show();
        g.dispose();
    }
}

我意识到这里的约定很糟糕-这只是我的图形习惯.通常,我会将其分为单独的类,等等.我们非常感谢您的帮助.谢谢.

I realize conventions here are terrible - this is just a practice for me with graphics. Normally I would have this broken into separate classes etc. Any help is greatly appreciated. Thank you.

推荐答案

BufferStrategy是一种低级绘画机制,可以完全控制绘画过程.这种力量"带来了一些复杂性,您需要准备好对其进行管理

BufferStrategy is a low level painting mechanism which places full control of the painting process in your hands. With this "power" comes some complexity which you need to be ready to manage

JavaDocs BufferStrategy和BufferCapabilities 提供了许多很好的例子来说明您必须管理API.

The JavaDocs and BufferStrategy and BufferCapabilities provide a number of excellent examples into how you must manage the API.

API是易失性的,这意味着您需要进行大量检查,以确保已将绘制的内容正确地传递到了渲染管道/硬件,否则,您需要再次重复绘制过程.这就是您可能遇到问题的地方.

The API is volatile, this means that you need to make a number of checks to ensure that what you've been painting has been passed to the rendering pipeline/hardware correctly, otherwise you need to repeat the paint pass again. This is where you're probably having issues.

您还需要记住,尽管setVisible立即返回,但这并不意味着该窗口在屏幕上可见或已完全实现(附加到本机对等体),这也可能影响BufferStrategy准备绘画.

You also need to remember that, while setVisible returns immediately, this doesn't mean that the window is visible on the screen or that it's been fully realised (attached to a native peer), this can also affect when BufferStrategy is ready to paint.

例如...

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;

public class Test extends Canvas implements Runnable {

    private static final long serialVersionUID = 1L;

    public static int WIDTH = 200;
    public static int HEIGHT = 200;

    private Thread thread;
    private boolean running = false;

    public Test() {
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(WIDTH, HEIGHT);
    }

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

    }

    public synchronized void stop() {
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (running) {
            update();
            render();

            // Control frame rate
            try {
                Thread.sleep(5);
            } catch (InterruptedException ex) {
            }
        }

    }

    public void update() {
        // Make changes to the model which need to be painted
    }

    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }

        do {
            do {
                Graphics2D g = (Graphics2D) bs.getDrawGraphics();
                // You MUST clear the page before painting, bad things
                // happen otherwise
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, getWidth(), getHeight());
                g.setColor(Color.red);
                g.fillRect(10, 50, 50, 70);
                g.dispose();
            } while (bs.contentsRestored());
            bs.show();
        } while (bs.contentsLost());
    }

    public static void main(String[] args) {
        Test test = new Test();
        JFrame frame = new JFrame();
        frame.add(test);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        test.start();

    }

}

现在,此示例还具有主循环"的基本概念,它负责提供基线,您可以从中生成动态内容并进行渲染.但是您可以简单地尝试调用render,使窗口可见

Now, this example also has a basic concept of a "main loop", this is responsible for providing base line from which you can generate dynamic content and render it. But you could simply try calling render one the window is made visible

正如我所说,BufferStrategy是一个低级API,它功能强大,灵活且复杂.

As I said, BufferStrategy is a low level API, it's powerful, flexible and complex to manage.

一个更简单的解决方案可能是通过Swing进行自定义绘制路线.请参见执行自定义绘画

A simpler solution might be to go a custom painting route through Swing. See Performing Custom Painting and Painting in AWT and Swing for more details. Swing components offer automatic double buffering and the paint scheduling is done for you (although you do need to use things like repaint to get a paint pass to run)

这篇关于画布未绘制到JFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆