为什么使用 Swing 绘画在 Java 8 和 Java 6 中表现不同



我正在开发一个使用 Swing 作为 GUI 的 Java 应用程序。在这个项目中,我使用的是Java 8 Update 25。我一直在用Java编写另一个图形应用程序,但我使用的是Java 6。在这两个项目中,我都编写了相同的paint()方法。(如下所示)我也以同样的方式调用"repaint()"。在这两个项目中,我都在画一个字符串。此字符串显示本地整数的值,计数;每次调用 paint() 方法时,计数都会增加 1。

当两个项目的行为不同时,我的问题是。在 Java 6 中,屏幕更新速度超快,应用程序的行为符合预期。但是,在 Java 7 和 8 中,应用程序不显示任何内容。如果我增加重绘之间的延迟(大约 300 毫秒),我能够看到字符串闪烁。但是,如果我想在Java 8中开发游戏,例如角色的闪烁和抖动运动将是非常不可取的。

为什么不同的 Java 版本以这种方式表现不同?有没有办法使用类似的设置在 Java 8 中复制平滑重绘(通过 Java 6)?(如下所列)如果有,如何?如果没有,如何实现平滑、最小的闪烁显示?(我希望这种重绘是不断重绘,但它不像显示器的流程那么必要)

提前感谢您的帮助, ~雷恩

Java 6 项目代码:

public class App {
static AppDisplay display = new AppDisplay();
  public static void main(String args[]) {
    display.setup();
    Thread graphics = new Thread() {
      public void run() {
        while(true) {
          display.repaint();
          try {
            Thread.sleep(17); // This is the delay I am talking about above
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
    graphics.start();

  }
}
public class AppDisplay() extends JFrame {
  private static final long serialVersionUID = 1L;
  int count = 0;
  public void setup() {
    this.setSize(600, 600);
    this.setTitle("Application");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
  }
  public void paint(Graphics g) {
    super.paint(g);
    g.drawString("Count: " + count);
    count ++;
  }
}

Java 8 代码:

public class App {
static AppDisplay display = new AppDisplay();
  public static void main(String args[]) {
    display.setup();
    Thread graphics = new Thread() {
      public void run() {
        while(true) {
          display.repaint();
          try {
            Thread.sleep(17); // Delay
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
    graphics.start();

  }
}
public class AppDisplay() extends JFrame {
  private static final long serialVersionUID = 1L;
  int count = 0;
  public void setup() {
    this.setSize(600, 600);
    this.setTitle("Application");
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
  }
  public void paint(Graphics g) {
    super.paint(g);
    g.drawString("Count: " + count);
    count ++;
  }
}
  • 永远不要直接在 JFrame 中绘制。
  • 始终绘制一个 JComponent,例如 JPanel 或 JComponent。
  • 并绘制其paintComponent(Graphics g)覆盖,而不是paint(Graphics g)覆盖,以获得自动双缓冲的好处。
  • 请不要发布草率的代码。如果您的类扩展了另一个类,请显示它。细节决定成败。

例如,

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyApp extends JPanel {
   private static final int PREF_W = 600;
   private static final int PREF_H = 400;
   private static final int DELAY = 17;
   private int count = 0;
   public MyApp() {
      new Timer(DELAY, new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            count++;
            repaint();
         }
      }).start();
   }
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }
   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawString("Count = " + count, 20, 20);
   }
   private static void createAndShowGUI() {
      MyApp paintEg = new MyApp();
      JFrame frame = new JFrame("MyApp");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(paintEg);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }
}

相关内容

  • 没有找到相关文章

最新更新