计时器达到0时闪烁



导入库

public class Countdown1 extends Applet implements Runnable {
// getting user input
String input = JOptionPane.showInputDialog("Enter seconds: ");
// converting string to integer
int counter = Integer.parseInt(input);
Thread countdown;
public void start() {
countdown = new Thread(this);
countdown.start();
}
// executed by thread
public void run() {
Timer timer;
timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
public void actionPerformed(ActionEvent evt) {
if (counter > 0) {
counter--;
// repainting each second
repaint();
}
}
});
// timer started 
timer.start();
}
public void paint(Graphics g) {
//painting text and time 
g.setFont(new Font("Times New Roman", Font.BOLD, 35));
g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
setBackground(Color.orange);
setForeground(Color.magenta);
// change background to cyan when timer reaches 0
if (counter == 0) {
setBackground(Color.cyan);
}
}
}

问题不在于Timer(尽管我确实质疑是否需要在单独的线程中启动它),问题在于重写paint

Applet这样的顶级容器不是双重缓冲的,这意味着每个绘制操作往往会被拼命地发送到底层的Graphics设备。

现在你可以通过员工的一些双重缓冲过程来解决这个问题,或者你可以。。。

  • 改为从JApplet扩展
  • 创建一个从类似JPanel的东西扩展的自定义组件,并替代它的paintComponent方法,将您的自定义绘画移动到此方法
  • 将此组件添加到小程序中

它应该能解决眼前的问题。。。

您还应该避免从任何paint方法中调用setForegroundsetBackground。事实上,您应该避免从任何paint方法中调用任何可能调用repaint的方法。。。

看一看表演自定义绘画

我确信String input = JOptionPane.showInputDialog("Enter seconds: ");这是个坏主意。相反,您应该在UI中提供某种控件或选项来更改此值。。。

粗略示例

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Countdown1 extends JApplet {
@Override
public void init() {
add(new CounterPane());
}
public class CounterPane extends JPanel {
String input = JOptionPane.showInputDialog("Enter seconds: ");
int counter = Integer.parseInt(input);
public CounterPane() {
Timer timer;
timer = new Timer(1000, new ActionListener() /* counting down time inputted */ {
public void actionPerformed(ActionEvent evt) {
System.out.println(counter);
if (counter > 0) {
counter--;
setBackground(Color.orange);
setForeground(Color.magenta);
if (counter <= 0) {
setBackground(Color.cyan);
}
repaint();
}
}
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Times New Roman", Font.BOLD, 35));
g.setColor(getForeground());
g.drawString("Seconds: " + String.valueOf(counter), 260, 210);
}
}
}

最新更新