文本框(JTextField/JLabel)顯示數字快速滾動,點擊「開始」啟動,點擊「停止」定格顯示一個隨機數字,類似抽獎/老虎機效果。
使用 Swing Timer 或獨立線程 + SwingUtilities.invokeLater 更新 UI,確保線程安全。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class NumberScroller extends JFrame {
private JTextField displayField;
private JButton btnStart, btnStop;
private Timer scrollTimer;
private Random random = new Random();
private volatile boolean running = false;
public NumberScroller() {
setTitle("數字滾動演示");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
displayField = new JTextField(10);
displayField.setFont(new Font("Monospaced", Font.BOLD, 24));
displayField.setHorizontalAlignment(JTextField.CENTER);
displayField.setEditable(false);
add(displayField);
btnStart = new JButton("開始");
btnStop = new JButton("停止");
btnStop.setEnabled(false);
add(btnStart);
add(btnStop);
// 使用 Swing Timer 確保在 EDT 更新 UI
scrollTimer = new Timer(50, e -> { // 50ms 刷新一次
if (running) {
int num = random.nextInt(100); // 0-99
displayField.setText(String.format("%02d", num));
}
});
btnStart.addActionListener(e -> {
running = true;
scrollTimer.start();
btnStart.setEnabled(false);
btnStop.setEnabled(true);
});
btnStop.addActionListener(e -> {
running = false;
scrollTimer.stop();
// 停止時顯示最終隨機數
int finalNum = random.nextInt(100);
displayField.setText(String.format("%02d", finalNum));
btnStart.setEnabled(true);
btnStop.setEnabled(false);
});
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new NumberScroller().setVisible(true));
}
}
| 技術點 | 說明 |
|---|---|
| Swing Timer | 在事件分發線程(EDT)執行,直接更新 UI 安全,無需 invokeLater |
| volatile boolean | 保證多線程可見性,停止信號即時生效 |
| String.format | 格式化輸出固定寬度,避免數字跳動導致界面抖動 |
| 按鈕狀態聯動 | 防止重複點擊,邏輯清晰 |
while(true) 且無 Thread.sleep,阻塞 EDT。random.nextInt() 參數錯誤或未調用 setText。running 非 volatile,或未調用 timer.stop()。