gpt4 book ai didi

java - 使用缓冲区策略获取图形对象进行绘制

转载 作者:行者123 更新时间:2023-11-30 06:24:55 25 4
gpt4 key购买 nike

我制作了一个带有 Canvas 的 JFrame,我想在该 Canvas 上绘图。稍后, Canvas 将每秒更新多次,因此我为此使用缓冲区策略。这是代码:

package mainPackage;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class TickPainter {
//just some presets for a window.
public static JFrame makeWindow(String title, int width, int height) {
JFrame mainWindow = new JFrame();
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setSize(width, height);
mainWindow.setVisible(true);
mainWindow.setLocationRelativeTo(null);
mainWindow.setTitle(title);

return mainWindow;
}

public static void main(String[] args) {

JFrame mainWindow = makeWindow("Practice", 800, 600);
Canvas mainCanvas = new Canvas();
mainWindow.add(mainCanvas);
mainCanvas.setSize(mainWindow.getWidth(), mainWindow.getHeight());
mainCanvas.setBackground(Color.white);
mainCanvas.createBufferStrategy(3);
BufferStrategy bufferStrat = mainCanvas.getBufferStrategy();

Graphics g = bufferStrat.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(250, 250, 250, 250);
g.dispose();
bufferStrat.show();
}
}

程序没有按预期绘制黑色矩形,我觉得我在这里错过了一些非常明显的东西,但我只是看不到它。目前该程序只是制作一个空白的白色 Canvas 。我觉得问题的一部分是缓冲区只是以比我看到的更快的速度传递带有矩形的帧,但之后没有要加载的帧,所以我不知道为什么要这样做。

最佳答案

BufferStrategy 有许多初始要求,在渲染之前必须满足这些要求。此外,由于其工作原理的性质,您可能需要多次重复绘制阶段,然后才能真正被硬件层接受。

我建议浏览 JavaDocstutorial ,它们为您如何使用 BufferStrategy

提供了宝贵的示例

以下示例使用 Canvas 作为基本组件,并在自定义Thread 内设置渲染循环。它非常基础,但显示了您需要实现的基本概念...

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TestCanvas canvas = new TestCanvas();

JFrame frame = new JFrame();
frame.add(canvas);
frame.setTitle("Test");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

canvas.start();
}
});
}

public class TestCanvas extends Canvas {

private Thread thread;
private AtomicBoolean keepRendering = new AtomicBoolean(true);

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

public void stop() {
if (thread != null) {
keepRendering.set(false);
try {
thread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

public void start() {
if (thread != null) {
stop();
}

keepRendering.set(true);
thread = new Thread(new Runnable() {
@Override
public void run() {

createBufferStrategy(3);

do {
BufferStrategy bs = getBufferStrategy();
while (bs == null) {
System.out.println("get buffer");
bs = getBufferStrategy();
}
do {
// The following loop ensures that the contents of the drawing buffer
// are consistent in case the underlying surface was recreated
do {
// Get a new graphics context every time through the loop
// to make sure the strategy is validated
System.out.println("draw");
Graphics graphics = bs.getDrawGraphics();

// Render to graphics
// ...
graphics.setColor(Color.RED);
graphics.fillRect(0, 0, 100, 100);
// Dispose the graphics
graphics.dispose();

// Repeat the rendering if the drawing buffer contents
// were restored
} while (bs.contentsRestored());

System.out.println("show");
// Display the buffer
bs.show();

// Repeat the rendering if the drawing buffer was lost
} while (bs.contentsLost());
System.out.println("done");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
} while (keepRendering.get());
}
});
thread.start();
}

}

}

请记住,BufferStrategy 的目的是让您完全控制绘制过程,因此它在通常由 AWT 和 Swing 实现的正常绘制过程之外工作

“稍后 Canvas 将每秒更新多次,因此我为此使用缓冲策略” - 在采用“直接到硬件”解决方案之前,我会考虑使用 Swing Timer 和正常的绘制过程来查看它的工作效果

关于java - 使用缓冲区策略获取图形对象进行绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47377513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com