调用`repaint()`是否需要“invoke”?

ltskdhd1  于 2021-07-11  发布在  Java
关注(0)|答案(0)|浏览(215)

打电话吗 Component#repaint 要求 invokeLater 或者 invokeAndWait 如果它不是在awt事件调度线程中调用的?
我已经创建了一个最小的时钟(只是为了练习和以后的扩展),代码如下:

package digiclock;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.time.Instant;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ClockPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    public class ClockTimerTask extends TimerTask {

        @Override
        public void run() {
            SwingUtilities.invokeLater(new Repainter());
            var delay = calculateDelay(precision);
            timer.schedule(new ClockTimerTask(), delay);
        }
    }

    public class Repainter implements Runnable {

        @Override
        public void run() {
            ClockPanel.this.repaint();
        }
    }

    private Timer timer;
    private Precision precision;

    public ClockPanel(Precision precision) {
        this.precision = precision;

        this.setBackground(Color.DARK_GRAY);

        // note that the Swing timer is so imprecise that it's usefulness is basically reduced to zero
        this.timer = new Timer("ClockTimer");
        var initialDelay = calculateDelay(precision);
        this.timer.schedule(new ClockTimerTask(), initialDelay);
    }

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

        g.setColor(Color.GREEN);
        // TODO take care of resizing specific to size of time etc
        g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 40));
        g.drawString(getTimeString(precision, LocalTime.now()), 10, 50);
    }

    private static int calculateDelay(Precision precission) {
        Instant delayNow = Instant.now();
        return precission.getInMilli() - (int) (delayNow.toEpochMilli() % precission.getInMilli());
    }

    private static String getTimeString(Precision precision, LocalTime time) {
        // TODO take care of precision

        // pattern for 24 hrs
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("HH:mm:ss");
        return time.format(pattern);
    }
}
package digiclock;

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class DigiClock extends JFrame {

    private static final long serialVersionUID = 1L;

    private static final double MM_IN_INCH = 0.0393701;

    private static final Dimension DIMENSION_IN_MM = new Dimension(120, 40);

    private static int RES = Toolkit.getDefaultToolkit().getScreenResolution();

    private static Dimension convertFromDimensionInMM(Dimension dimInMM) {
        return new Dimension(mmToPixels(dimInMM.width), mmToPixels(dimInMM.height));

    }

    private static int mmToPixels(int mm) {
        return (int) (mm * MM_IN_INCH * RES);
    }

    public static void main(String[] args) {
        var clock = new DigiClock();
        clock.setTitle("24-hour clock");
        clock.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        clock.setSize(convertFromDimensionInMM(DIMENSION_IN_MM));
        clock.add(new ClockPanel(Precision.SECOND));
        clock.setVisible(true);
    }
}

最后:

package digiclock;

public enum Precision {
    DECISECOND(100), SECOND(1000), MINUTE(60_000);

    private int inMS;

    private Precision(int inMS) {
        this.inMS = inMS;
    }

    public int getInMilli() {
        return inMS;
    }
}

我希望我的代码尽可能少地等待时间,原因很明显。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题