我正在开发一个使用 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();
}
});
}
}