打电话吗 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;
}
}
我希望我的代码尽可能少地等待时间,原因很明显。
暂无答案!
目前还没有任何答案,快来回答吧!