简体   繁体   English

时间不会在Applet中重绘

[英]Time doesn't repaint in Applet

I have a small problem but I don't know to fix it. 我有一个小问题,但我不知道要解决。 I create simple Applet in which should be simple digital clock. 我创建了一个简单的Applet,其中应该是简单的数字时钟。 I created all methods correctly but repaint methods doesn't repaint my applet. 我正确地创建了所有方法,但是重绘方法不会重绘我的applet。 Can you check my code and say where is mistake. 您能检查我的代码并说出错误之处吗? Thanks. 谢谢。

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);
}
}

Just use a javax.swing.Timer . 只需使用javax.swing.Timer See how to use Swing Timer 了解如何使用Swing计时器

Here's an example. 这是一个例子。 But rather than painting on top-level container like JApplet which you are doing, I'm painting on JPanel which is more recommended 但是,我不是在像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);
            }
        });
    }
}

More directly answering your question, your code works when I test it, the only thing you're forgetting to do is call super.paint() . 更直接地回答您的问题,当我对其进行测试时,您的代码就可以工作,而您唯一要做的就是调用super.paint() Works as expected after doing so 这样做后按预期工作

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

You'll want to avoid Thread.sleep though. 您将要避免Thread.sleep You may notice this causes flickering. 您可能会注意到这会导致闪烁。 It's preferred to use javax.swing.Timer . 最好使用javax.swing.Timer That's why I answered with my example first. 这就是为什么我首先回答我的例子。

Look at this another example. 再看另一个例子。 As @peeskillet answer, I also used JPanel to show time, but in my code I am using JLabel to show time. 作为@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);
        }
    });
    }
}

时钟

You should use a private attribute like 您应该使用私有属性,例如

private boolean running = true;

You set it in stop-method to false . 您将其在stop-method中设置为false And in run-method you evaluate it as stop condition instead of evaluating timeThread != null . 在运行方法中,您将其评估为停止条件,而不是评估timeThread != null This procedure is safer because otherwise you get into concurrency problems within run-method caused by NullPointerException . 此过程比较安全,因为否则您会遇到由NullPointerException引起的运行方法内的并发问题。

And you should check the applet state by watching its console output in browser plugin. 而且,您应该通过在浏览器插件中查看其applet的控制台输出来检查applet的状态。 Do you see exceptions? 你看到例外了吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM