Java 画布未绘制到JFrame
我一直在寻找这个问题的答案,多次重新编写代码,仍然一无所获。本质上,我试图绘制一个只包含一个简单矩形的JFrame,但每次框架中都没有显示任何内容—它只是空白Java 画布未绘制到JFrame,java,swing,graphics,awt,Java,Swing,Graphics,Awt,我一直在寻找这个问题的答案,多次重新编写代码,仍然一无所获。本质上,我试图绘制一个只包含一个简单矩形的JFrame,但每次框架中都没有显示任何内容—它只是空白 package com.Graphics; import java.awt.*; import java.awt.image.*; import javax.swing.*; public class GraphicsMain { public static void main(String[] args) {
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
是一种低级绘画机制,可将绘画过程的完全控制权交给您。伴随着这种“力量”而来的是一些你需要准备好管理的复杂性
并提供了许多关于必须如何管理API的优秀示例
API是易变的,这意味着您需要进行大量检查,以确保已绘制的内容已正确传递到渲染管道/硬件,否则需要再次重复绘制过程。这就是你可能遇到的问题
您还需要记住,虽然setVisible
会立即返回,但这并不意味着窗口在屏幕上可见或已完全实现(连接到本机对等机),这也会影响BufferStrategy
准备绘制的时间
例如
现在,这个示例还有一个“主循环”的基本概念,它负责提供基线,您可以从基线生成动态内容并进行渲染。但是您可以尝试调用render
一个窗口,使其可见
正如我所说,BufferStrategy
是一个低级API,它功能强大、灵活且管理复杂
一个更简单的解决方案可能是通过Swing进行自定义绘制。有关更多详细信息,请参阅和。Swing组件提供自动双缓冲,绘制计划为您完成(尽管您确实需要使用
重新绘制
之类的方法来运行绘制过程)@ElarbiMohamedAymen请不要建议只从代码中删除所有空行的编辑。这会严重损害可读性,在本例中,代码格式(缩进)存在一个实际问题,您没有费心解决这个问题。另请参见。您应该使用JPanel
,重写paintComponent(Graphics gc)
方法,并在其中绘制矩形。感谢程序员的帮助。我想我有一些关于这个API的研究要做。。。哈哈,这只是一个简单的问题,关于为什么一个人必须像上面那样做?我在上面发布的方法中基本上完成了所有这些,但显然排除了线程和各种方法。只是不明白为什么要这样做。再次感谢您的帮助:)@Matthew您没有做的是检查缓冲区的内容是否已成功传递到渲染管道(即缓冲区是否在绘制过程中无效)-请参阅render
方法中的doubledo while
循环。正如我所说,仅仅因为您调用了setVisible
,并不意味着窗口(在屏幕上)是可见的,也不意味着它已经准备好进行绘制了。好的,您在消息的开头也这么说。不知怎么错过了。最后一个问题,为什么会发生这样的事情?为什么缓冲区的内容不能成功通过?@Matthew视频卡的内存是共享的且“不稳定的”,这意味着视频卡可以决定将其从您手中拿走(或做其他事情),因为BufferStrategy
正试图以尽可能低的级别运行,它无法防范这一点,它只是让你知道什么时候发生
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();
}
}