导入库
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
方法中调用setForeground
或setBackground
。事实上,您应该避免从任何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);
}
}
}