时间不会在Applet中重新绘制

我有一个小问题,但我不知道要解决它。 我创建了简单的Applet,其中应该是简单的数字时钟。 我正确地创建了所有方法,但重绘方法不会重新绘制我的applet。 你能检查我的代码并说出错误的地方吗? 谢谢。

public class DigitalClock extends JApplet implements Runnable { private Thread timeThread; Date date = new Date(); public void start() { timeThread = new Thread(this, "Clock"); timeThread.start(); } @Override public void stop() { if (timeThread == null) { return; } timeThread = null; } @Override public void run() { while (timeThread != null) { repaint(); try { timeThread.sleep(1000); } catch (InterruptedException e) { } } } @Override public void paint(Graphics g) { date.setTime(System.currentTimeMillis()); g.drawString(date.toString(), 50, 95); } } 

只需使用javax.swing.Timer了解如何使用Swing Timer

这是一个例子。 但是,不是像JApplet那样在顶层容器上绘画,而是在JPanel上绘画,这是更推荐的

在此处输入图像描述

 import java.awt.*; import java.awt.event.*; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.*; public class TimerPanel extends JPanel { private String dateString; private final SimpleDateFormat format; private final Font font; private final Date date; public TimerPanel() { format = new SimpleDateFormat("hh:mm:ss a"); font = new Font("impact", Font.PLAIN, 30); date = new Date(); date.setTime(System.currentTimeMillis()); dateString = format.format(date); Timer timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { date.setTime(System.currentTimeMillis()); dateString = format.format(date); repaint(); } }); timer.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setFont(font); FontMetrics fm = g.getFontMetrics(font); int width = fm.stringWidth(dateString); int height = fm.getAscent(); int x = getWidth() / 2 - width / 2; int y = getHeight() / 2 + height / 2; g.drawString(dateString, x, y); } @Override public Dimension getPreferredSize() { return new Dimension(300, 100); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { TimerPanel timer = new TimerPanel(); JOptionPane.showMessageDialog( null, timer, "Digital Clock", JOptionPane.PLAIN_MESSAGE); } }); } } 

更直接地回答你的问题,你的代码在我测试时工作,你唯一忘记做的就是调用super.paint() 。 这样做后按预期工作

 @Override public void paint(Graphics g) { super.paint(g); 

你会想要避免使用Thread.sleep 。 您可能会注意到这会导致闪烁。 最好使用javax.swing.Timer 。 这就是为什么我先回答我的例子。

再看另一个例子。 正如@peeskillet的回答,我也使用JPanel来显示时间,但在我的代码中我使用JLabel来显示时间。

 public class ClockPane extends JPanel { private JLabel clock; public ClockPane() { setLayout(new BorderLayout()); clock = new JLabel(); clock.setHorizontalAlignment(JLabel.CENTER); clock.setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD, 32f)); tickTock(); add(clock); Timer timer = new Timer(500, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { tickTock(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.setInitialDelay(0); timer.start(); } public void tickTock() { clock.setText(DateFormat.getDateTimeInstance().format(new Date())); } public static void main(String args[]){ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ClockPane clock = new ClockPane(); JOptionPane.showMessageDialog( null, clock, "Digital Clock", JOptionPane.PLAIN_MESSAGE); } }); } } 

时钟

你应该使用像这样的私有属性

 private boolean running = true; 

您将stop-method设置为false 。 在run-method中,您将其评估为停止条件,而不是评估timeThread != null 。 此过程更安全,因为否则您会在由NullPointerException引起的run-method中遇到并发问题。

你应该通过在浏览器插件中观察它的控制台输出来检查applet状态。 你看到例外吗?