以下代码是时钟的动画。
程序中必须进行哪些更改才能使其不闪烁?
为什么必须在addNotify()函数中进行字段启动才能显示指针?
您可以将所有文件复制到一个.java文件中,它应该可以工作(闪烁;))。
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class ac extends Frame implements Runnable {
// for double buffering
Graphics og;
Image oi;
Thread t = null;
int width, height;
int timeH, timeM, timeS, radius = 50, lenH, lenM, lenS,
lenIn, cx, cy, x1, y1, x2, y2;
private boolean timeToQuit;
ac() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
stopRunning();
dispose();
}
});
setMinimumSize(new Dimension(300, 300));
EventQueue.invokeLater(new Runnable() {
public void run() {
setVisible(true);
}
});
}
public void addNotify() {
super.addNotify();
width = getBounds().width;
height = getBounds().height;
setSize(width, height);
lenH = 5 * radius / 10;
lenM = 6 * radius / 10;
lenS = 7 * radius / 10;
lenIn = 8 * radius / 10;
cx = width / 2;
cy = height / 2;
// for double buffering
oi = createImage(width, height);
og = oi.getGraphics();
}
public static void main(String [] args) {
ac clock = new ac();
clock.start();
}
public void start() {
if (t == null) {
t = new Thread(this);
t.start();
}
}
public void stopRunning() {
timeToQuit = true;
}
public void run() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY - 1);
do {
repaint();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
}
}
while (!timeToQuit);
System.out.println("Quitting");
}
public void paint(Graphics g) {
og.setColor(new Color(170, 170, 170));
og.fillRect(0, 0, width, height);
Calendar cal = new GregorianCalendar();
timeH = cal.get(Calendar.HOUR);
timeM = cal.get(Calendar.MINUTE);
timeS = cal.get(Calendar.SECOND);
if (timeH >= 12)
timeH -= 12;
for (int i = 1 ; i < 13 ; i++) {
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + radius * Math.sin(i * 2 * 3.14159f / 12));
y2 = (int) (cy - radius * Math.cos(i * 2 * 3.14159f / 12));
if (i % 3 != 0) {
x1 = (int) (cx + 0.9f * radius * Math.sin(i * 2 * 3.14159f / 12));
y1 = (int) (cy - 0.9f * radius * Math.cos(i * 2 * 3.14159f / 12));
}
else {
x1 = (int) (cx + 0.8f * radius * Math.sin(i * 2 * 3.14159f / 12));
y1 = (int) (cy - 0.8f * radius * Math.cos(i * 2 * 3.14159f / 12));
}
og.drawLine(x1, y1, x2, y2);
og.setColor(new Color(230, 230, 230));
og.drawLine(x1 - 1, y1 - 1, x2 - 1, y2 - 1);
}
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenH * Math.sin((timeH + timeM / 60.0f + timeS / 3600.0f)
* 2 * 3.14159f / 12));
y2 = (int) (cy - lenH * Math.cos((timeH + timeM / 60.0f + timeS / 3600.0f)
* 2 * 3.14159f / 12));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.red);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenM * Math.sin((timeM + timeS / 60.0f) * 2 * 3.14159f
/ 60));
y2 = (int) (cy - lenM * Math.cos((timeM + timeS / 60.0f) * 2 * 3.14159f
/ 60));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.green);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
x2 = (int) (cx + lenS * Math.sin(timeS * 2 * 3.14159f / 60));
y2 = (int) (cy - lenS * Math.cos(timeS * 2 * 3.14159f / 60));
og.drawLine(cx, cy, x2, y2);
og.setColor(Color.blue);
og.drawLine(cx - 1, cy - 1, x2 - 1, y2 - 1);
og.setColor(new Color(20, 20, 20));
og.drawOval((width - 2 * radius) / 2, (height - 2 * radius) / 2,
2 * radius, 2 * radius);
og.setColor(new Color(230, 230, 230));
og.drawOval((width - 2 * radius) / 2 - 1, (height - 2 * radius) / 2 - 1,
2 * radius, 2 * radius);
g.drawImage(oi, 0, 0, this);
}
}
答案 0 :(得分:1)
这使用了旧的awt并且它绘制在主框架上 - 而不是制作swing UI的最佳方式。你可以试试这个:
对于2和3,您可以保留原始类来生成Frame / JFrame,并将java.awt.Panel或javax.swing.JComponent添加到前者中。
不会在我的mac系统上闪烁,所以我认为它是一个OS +倍的刷新问题。意义建议1可能有用 - 首先尝试。谈论代码行:
Thread.sleep(800);
答案 1 :(得分:1)
信不信由你,通过添加函数来解决问题:
public void update(Graphics g)
{
paint(g);
}
但问题仍然存在,为什么?当你在addNotify()函数之外启动类字段时,为什么不显示指针?