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

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


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

最佳答案

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

JavaDocsBufferStrategy and BufferCapabilities提供了许多有关如何管理API的出色示例。

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

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

例如...

java -  Canvas 未绘制到JFrame-LMLPHP

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,使窗口可见

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

一个更简单的解决方案可能是通过Swing进行自定义绘制路线。有关更多详细信息,请参见Performing Custom PaintingPainting in AWT and Swing。 Swing组件提供自动双缓冲,并且为您完成了绘画调度(尽管您确实需要使用诸如repaint之类的方法来使绘画传递运行)

08-05 07:46