如何在jframe中使用BuffereImage进行图像渲染?

cu6pst1q  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(409)

我正在尝试渲染一组复杂的对象,而不是尝试单独渲染每个对象,我认为将它们渲染为BuffereImage会更快。我唯一能想到的方法是将bufferedimage转换成imageicon,并将其设置为jlabel,然后将jlabel添加到jframe。为了更新图像,我移除jlabel,用新的bufferedimage设置它,然后将它重新添加到jframe。这使得屏幕快速闪烁,因为您可以在每次渲染之间看到一个空帧。如果我不删除标签,程序运行非常慢。我该怎么解决这个问题?我应该使用jlabels还是有更好的方法?

  1. public static void createWindow() {
  2. frame = new JFrame("PlanetSim");
  3. frame.setPreferredSize(new Dimension(WINDOW_X, WINDOW_Y));
  4. frame.setMaximumSize(new Dimension(WINDOW_X, WINDOW_Y));
  5. frame.setMinimumSize(new Dimension(WINDOW_X, WINDOW_Y));
  6. foregroundLabel = new JLabel(new ImageIcon(foreground));
  7. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  8. frame.setResizable(false);
  9. frame.add(foregroundLabel);
  10. frame.pack();
  11. frame.setVisible(true);
  12. }
  13. public static void setForeground() {
  14. frame.getContentPane().remove(foregroundLabel);
  15. foregroundLabel = new JLabel(new ImageIcon(foreground));
  16. frame.getContentPane().add(foregroundLabel);
  17. frame.pack();
  18. }

我怀疑这个问题与循环本身有关,但我还是把它包括进来以防万一。

  1. public void run() {
  2. long lastTime = System.nanoTime(), now; //keeps track of time on computer in nanoseconds
  3. double amountOfTicks = 60.0; //number of ticks per rendering
  4. double delta = 0; //time step
  5. long timer = System.currentTimeMillis(); //timer to display FPS every 1000 ms
  6. int frames = 0;
  7. while (running) {
  8. now = System.nanoTime();
  9. delta += (now - lastTime) * amountOfTicks / 1000000000;
  10. lastTime = now;
  11. while(delta >= 1) {
  12. tick();
  13. delta--;
  14. }
  15. if (running)
  16. render();
  17. frames++;
  18. if (System.currentTimeMillis() - timer > 1000) {
  19. timer += 1000;
  20. System.out.println("FPS: " + frames);
  21. frames = 0;
  22. }
  23. }
  24. }
  25. public void render() {
  26. populateWindow();
  27. Window.setForeground();
  28. }
1u4esq0p

1u4esq0p1#

  1. frame.getContentPane().remove(foregroundLabel);
  2. foregroundLabel = new JLabel(new ImageIcon(foreground));
  3. frame.getContentPane().add(foregroundLabel);
  4. frame.pack();

我建议没有必要删除/添加标签或 Package 框架,因为我会假设图标每次都是相同的大小。
你所需要做的就是替换标签的图标。

  1. //frame.getContentPane().remove(foregroundLabel);
  2. foregroundLabel.setIcon( new ImageIcon(foreground) );
  3. //frame.getContentPane().add(foregroundLabel);
  4. //frame.pack();

我正在尝试渲染一组复杂的对象,而不是尝试单独渲染每个对象,我认为将它们渲染为BuffereImage会更快
否则只需在 paintComponent() 方法。swing在默认情况下是双缓冲的,因此它基本上不需要创建bufferedimage。
请参阅:获取类外jpanel的宽度和高度作为自定义绘制的示例。只需将球数从5更新为100,使其更复杂。

相关问题