java - 画布未绘制到 JFrame
问题描述
我一直在寻找答案,多次重写我的代码,仍然没有。本质上,我试图绘制一个只包含一个简单矩形的 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
是一种低级绘画机制,可让您完全控制绘画过程。有了这种“力量”,您需要准备好管理一些复杂性
JavaDocs和BufferStrategy 和 BufferCapabilities提供了一些关于如何管理 API 的优秀示例。
API 是易变的,这意味着您需要进行多次检查以确保您所绘制的内容已正确传递到渲染管道/硬件,否则您需要再次重复绘制过程。这是您可能遇到问题的地方。
您还需要记住,虽然setVisible
立即返回,但这并不意味着窗口在屏幕上可见或已完全实现(附加到本机对等点),这也会影响何时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();
}
}
现在,这个例子还有一个“主循环”的基本概念,它负责提供基线,您可以从中生成动态内容并渲染它。但是您可以简单地尝试调用render
一个窗口可见
正如我所说,BufferStrategy
它是一个低级 API,它功能强大、灵活且管理复杂。
一个更简单的解决方案可能是通过 Swing 进行自定义绘画路线。有关更多详细信息,请参阅在 AWT 和 Swing中执行自定义绘画和绘画。Swing 组件提供自动双缓冲,并且为您完成了绘制调度(尽管您确实需要使用诸如运行绘制通道之类的东西)repaint
推荐阅读
- math - 如何计算两个圆圈外部接触的时间?
- javascript - 如何使用javascript在html页面中将英文数字显示为bangla unicode格式?
- javascript - 在 React Native 上无法使用 : 读取文件名
- javascript - HTML:如何在包装标签中引用特定的 URL
- javascript - 在 Angular 中的 POST 请求后调用 GET 请求
- kubernetes - 在 k8s 中查找 admin_ca、cluster_ca 和 admin_cert 的位置
- excel - 在一个条件下修复一个单元格值,否则让用户输入任何值
- python - Django 测试使用来自会话输入的电子邮件地址创建用户,assertRedirects 不起作用
- php - 通过 fopen 在 PHP 中获取 AT 命令的输出值
- hp-uft - UFT:如何识别动态 webtable 中的 webEdit