java - 如何在 jframe 中使用 bufferedimage 进行图像渲染?
问题描述
我正在尝试渲染一组复杂的对象,而不是尝试单独渲染每个对象,我认为将它们渲染为 BufferedImage 会更快。我能弄清楚如何做到这一点的唯一方法是将 BufferedImage 转换为 ImageIcon,并将其设置为 JLabel,然后将 JLabel 添加到 JFrame。为了更新图像,我删除了 JLabel,使用新的 BufferedImage 对其进行设置,然后将其重新添加到 JFrame。这会使屏幕快速闪烁,因为您可以在每次渲染之间看到一个空帧。如果我不删除标签,程序运行非常缓慢。我该如何解决?我什至应该使用 JLabels 还是有更好的方法?
public static void createWindow() {
frame = new JFrame("PlanetSim");
frame.setPreferredSize(new Dimension(WINDOW_X, WINDOW_Y));
frame.setMaximumSize(new Dimension(WINDOW_X, WINDOW_Y));
frame.setMinimumSize(new Dimension(WINDOW_X, WINDOW_Y));
foregroundLabel = new JLabel(new ImageIcon(foreground));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(foregroundLabel);
frame.pack();
frame.setVisible(true);
}
public static void setForeground() {
frame.getContentPane().remove(foregroundLabel);
foregroundLabel = new JLabel(new ImageIcon(foreground));
frame.getContentPane().add(foregroundLabel);
frame.pack();
}
我怀疑这个问题与循环本身有关,但我还是把它包括在内以防万一。
public void run() {
long lastTime = System.nanoTime(), now; //keeps track of time on computer in nanoseconds
double amountOfTicks = 60.0; //number of ticks per rendering
double delta = 0; //time step
long timer = System.currentTimeMillis(); //timer to display FPS every 1000 ms
int frames = 0;
while (running) {
now = System.nanoTime();
delta += (now - lastTime) * amountOfTicks / 1000000000;
lastTime = now;
while(delta >= 1) {
tick();
delta--;
}
if (running)
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
}
public void render() {
populateWindow();
Window.setForeground();
}
解决方案
frame.getContentPane().remove(foregroundLabel);
foregroundLabel = new JLabel(new ImageIcon(foreground));
frame.getContentPane().add(foregroundLabel);
frame.pack();
我建议不需要删除/添加标签或打包框架,因为我会假设图标每次都是相同的大小。
您需要做的就是替换标签的图标。
//frame.getContentPane().remove(foregroundLabel);
foregroundLabel.setIcon( new ImageIcon(foreground) );
//frame.getContentPane().add(foregroundLabel);
//frame.pack();
我正在尝试渲染一组复杂的对象,而不是尝试单独渲染每个对象,我认为将它们渲染为 BufferedImage 会更快
否则,只需在您的paintComponent()
方法中进行渲染。Swing 默认情况下是双缓冲的,因此它基本上消除了创建 BufferedImage 的需要。
请参阅:在类之外获取 JPanel 的宽度和高度,以获取自定义绘画的示例。只需将球数从 5 更新为 100 以使其更复杂。
推荐阅读
- amazon-web-services - 在自定义 docker 镜像中安装 Docker
- python - 使用 LSTMcell 自定义 RNN
- postgresql - 将服务器上的数据库与数据库本地计算机同步
- string-matching - 字符串匹配有限自动机预处理时间
- json - 在 Schema (Json-LD) 中,我应该为文章和技术文章使用什么,“描述”或/和“抽象”或/和“背景故事”?
- c++ - 删除二叉搜索树中的节点
- ms-access - 从批处理文件或任务计划程序将报告输出到 PDF 时出现“无当前记录”错误
- go - 错误:rpc 错误:代码 = 已取消 desc = 上下文已取消
- powershell - 如何使用 Powershell 或 REST 读取 SharePoint Note 字段的 AppendOnlyHistory
- node.js - 无法从节点服务器设置 cookie -> 应用程序