【发布时间】:2020-01-29 14:07:47
【问题描述】:
我正在尝试使用 Java Swing/AWT 2D 图形在窗口中显示一些非常基本的信息。此时,我只是在画一些字符串,虽然这个任务看起来并不难,但它运行起来非常慢。
在什么都不画的情况下,我可以以 100 FPS 左右的速度重新绘制。使用 1 个字符串,大约 30 FPS。有 20 个字符串,大约 3 FPS。
小例子:
import javax.swing.*;
import java.awt.*;
public class Example {
public static void main(String[] args) {
JFrame frame = buildFrame();
JPanel pane = new JPanel() {
int counter = 0;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.black);
g2.drawString(Integer.toString(counter++), 20, 20);
g2.drawString("HALLO", 50, 50);
g2.drawString("HALLO", 50, 60);
g2.drawString("HALLO", 50, 70);
g2.drawString("HALLO", 50, 80);
g2.drawString("HALLO", 50, 90);
g2.drawString("HALLO", 50, 100);
g2.drawString("HALLO", 50, 110);
g2.drawString("HALLO", 50, 120);
g2.drawString("HALLO", 50, 130);
g2.drawString("HALLO", 50, 140);
g2.drawString("HALLO", 50, 150);
g2.drawString("HALLO", 50, 160);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 160);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 170);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 180);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 190);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 100);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 110);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 120);
g2.drawString("DIES IST NUR EINT EST FÜR EINEN LANGENSTRING", 200, 130);
g2.dispose();
}
};
frame.add(pane);
while (true) {
pane.repaint();
frame.setVisible(true);
}
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(480, 272);
frame.setVisible(true);
return frame;
}
}
我在树莓派 3b+ 上运行,这不是一台非常快的机器,但应该能够显示一些字符串。使用System.nanoTime 对函数计时表明主循环和paintComponent 函数都低于1ms,这让我更加困惑。
我是否从根本上错过了什么?
【问题讨论】:
-
“这个任务似乎没有那么难”——好吧,渲染文本比你想象的要难,需要进行大量计算才能确定哪些像素应该着色,哪些不应该着色。除此之外,我可以想象硬件加速未启用甚至不可用 - 如果这是真的,那么一切都必须在非常慢的软件中完成。
-
既然你想展示“非常基本的信息”,为什么不简单地使用组件呢?喜欢
JLabel左右.. -
代码中另一个可能的问题是
g2.dispose();。来自dispose()上的 JavaDoc:“...为了提高效率,程序员应该在使用完 Graphics 对象后调用 dispose,前提是它是直接从组件或另一个 Graphics 对象创建的。” - 你没有创建g2,所以你不应该自己处理它。 -
您不应该丢弃
Graphics,因为 JPanel 将继续使用它。 -
“实际上使用 JLabels 确实快很多” 提示:添加@GeorgeZ。 (或
@很重要的人)通知新评论的人。
标签: java swing graphics awt java-2d