[英]How to prevent timer locking my Applet?
我正在嘗試在Applet中開發游戲,而我遇到了這個問題。 我希望顯示屏在游戲繼續之前向用戶顯示倒計時。 但是,倒數計時將不會顯示,而實際上會使GUI凍結。 如何避免這種情況? 這是一些演示此問題的代碼。
編輯:“幾乎”下面的代碼有效,計時器正在運行,但是每當按下開始按鈕時,屏幕只會更新為新的計時器值。 如何使文本自動刷新?
public class TestApplet extends JApplet implements ActionListener{
final JTextField _displayField = new JTextField("Countdown", 6);
CountDownTimer clock = new CountDownTimer();
JButton jbtnStart = new JButton("Start");
public void addComponentToPane(Container pane) {
JPanel mainPanel = new JPanel();
mainPanel.add(jbtnStart);
mainPanel.add(_displayField);
pane.add(mainPanel);
jbtnStart.addActionListener(this);
}
public void init() {
TestApplet testApplet = new TestApplet();
testApplet.setVisible(true);
testApplet.addComponentToPane(this.getContentPane());
this.setSize(200, 100);
}
public void actionPerformed(ActionEvent e) {
if ( e.getSource() == jbtnStart ){
clock.start(_displayField);
}
}
}
// ********************************************************************************
//********************************************************************************
//********************************************************************************
class CountDownTimer {
private static final int N = 60;
private final ClockListener cl = new ClockListener();
private final Timer t = new Timer(1000, cl);
static int count =0;
public int getCount(){
System.out.println(count);
return count;
}
public void setCount(int n){
count = n;
}
public CountDownTimer() {
t.setInitialDelay(0);
}
public void start(JTextComponent c) {
t.start();
Boolean bool = false;
while ( bool ==false){
c.setText( "Starting new game in... "+ this.getCount() );
bool = ( this.getCount()<10 );
}
}
private class ClockListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
count %= N;
count++;
setCount(count);
}
}
}
您在ActionListener中有一個while循環,該循環阻止了EDT。 更新顯示字段的代碼不應位於ActionListener中。
相反,此代碼應在Timer類中。 然后,每當計時器觸發時,您只需減去一並更新顯示字段。 當計數達到零時,您將停止計時器。
另外,您的CountDownTimer不應擴展JFrame。 它只是一個類,與框架無關。
編輯:
這是Swing計時器的簡單用法:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class TimerTime extends JFrame implements ActionListener
{
JLabel timeLabel;
public TimerTime()
{
timeLabel = new JLabel( new Date().toString() );
getContentPane().add(timeLabel, BorderLayout.NORTH);
}
public void actionPerformed(ActionEvent e)
{
timeLabel.setText( new Date().toString() );
}
public static void main(String[] args)
{
TimerTime frame = new TimerTime();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
int time = 1000;
javax.swing.Timer timer = new javax.swing.Timer(time, frame);
timer.setInitialDelay(1);
timer.start();
}
}
我們一直在爭論是否可以使用帶有后台線程的解決方案,因此我使用輔助線程對解決方案進行了編碼,並且效果很好。
“ N”常量穩定倒數的時間
公共類TestApplet擴展了JApplet實現ActionListener {
JTextField _displayField; CountDownTimer clock; JButton jbtnStart; Thread thread; public TestApplet(){ this.jbtnStart = new JButton("Start"); this._displayField = new JTextField("Countdown", 30); this.clock = new CountDownTimer(_displayField); this.thread = null; } public void addComponentToPane(Container pane) { JPanel mainPanel = new JPanel(); mainPanel.add(jbtnStart); mainPanel.add(_displayField); pane.add(mainPanel); jbtnStart.addActionListener(this); } public void init() { TestApplet testApplet = new TestApplet(); testApplet.setVisible(true); testApplet.addComponentToPane(this.getContentPane()); this.setSize(200, 100); } public void actionPerformed(ActionEvent e) { if ( e.getSource() == jbtnStart ){ if(thread != null){ thread.interrupt(); } thread = new Thread(clock); thread.start(); } }
}
/ * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * *** /// ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * * / / * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * *** * /
public class CountDownTimer implements Runnable{
private static final int N = 60;
JTextComponent c;
static int count =0;
public int getCount(){
System.out.println(count);
return count;
}
public void setCount(int n){
count = n;
}
public CountDownTimer(JTextComponent c) {
this.c = c;
}
@Override
public void run() {
try {
for(int i=N; i>0; i--){
setCount(i);
c.setText( "Starting new game in... "+ this.getCount() );
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
setCount(0);
}
}
}
使用並發進行倒計時怎么樣?
public void actionPerformed(ActionEvent e) {
if ( e.getSource() == jbtnStart ){
//You should start your new thread here
Thread thread = Thread(new Runnable(){
public void run(){
clock.start();
Boolean bool = false;
while ( bool ==false){
//You can not modify the UI from a secondary thread, so you should call to some
//method in the GUI thread...
_displayField.setText( "Starting new game in... "+ clock.getCount() );
bool = ( clock.getCount()==5 );
}
}
thread.start();
}
}
}
注意:該代碼是由內心完成的,因此容易出現一些錯誤,但是它表達了要點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.