我已经制作了一个带有画布的JFrame,我想在画布上画画。在稍后的日期,画布将每秒更新许多次,所以我使用缓冲策略。这是代码:
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();
}
}
程序没有按照预期绘制黑色矩形,我觉得我错过了一些非常明显的东西而且我无法看到它。目前该程序只是制作一个空白的白色画布。我觉得问题的一部分是缓冲区只是通过框架,矩形比我看到的更快,但是没有框架可以加载,所以我不知道它为什么这样做
答案 0 :(得分:1)
BufferStrategy
有许多初始要求,必须满足这些要求才能呈现。此外,由于其工作方式的性质,您可能需要多次重复绘制阶段才能实际接受硬件层。
我建议浏览JavaDocs和tutorial,它们提供了宝贵的示例,说明您如何使用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实现的正常绘画过程之外工作
"稍后画布将每秒更新多次,因此我正在使用缓冲策略" - 在进入"直接到硬件"解决方案,我考虑使用Swing Timer
和正常的绘画过程来看看它的运作情况