Come creare un ritardo in Swing

Ho fatto un gioco di blackjack e voglio che il giocatore di IA si fermi tra le carte. Ho provato semplicemente a usare Thread.sleep (x), ma ciò lo rende fermo fino a quando il giocatore di IA non ha completato tutte le sue carte. So che Swing non è thread-safe, quindi ho guardato Timers, ma non riuscivo a capire come potrei usarne uno per questo. Ecco il mio codice attuale:

while (JB.total  0)) { case 0: JB.hit(); break; case 1: break done; case 2: JB.hit(); JB.bet *= 2; break done; } } 

A proposito, il colpo (); metodo aggiorna la GUI.

Bene, il codice seguente mostra un JFrame con un JTextArea e un JButton. Quando si fa clic sui pulsanti, il Timer invia l’evento ripetutamente (con un secondo ritardo tra di loro) all’actionListener relativo al pulsante che accoda una linea con l’ora corrente.

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Calendar; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.Timer; public class TimerTest extends JFrame implements ActionListener{ private static final long serialVersionUID = 7416567620110237028L; JTextArea area; Timer timer; int count; // Counts the number of sendings done by the timer boolean running; // Indicates if the timer is started (true) or stopped (false) public TimerTest() { super("Test"); setBounds(30,30,500,500); setDefaultCloseOperation(EXIT_ON_CLOSE); setLayout(null); area = new JTextArea(); area.setBounds(0, 0, 500, 400); add(area); JButton button = new JButton("Click Me!"); button.addActionListener(this); button.setBounds(200, 400, 100, 40); add(button); // Initialization of the timer. 1 second delay and this class as ActionListener timer = new Timer(1000, this); timer.setRepeats(true); // Send events until someone stops it count = 0; // in the beginning, 0 events sended by timer running = false; System.out.println(timer.isRepeats()); setVisible(true); // Shows the frame } public void actionPerformsd(ActionEvent e) { if (! running) { timer.start(); running = true; } // Writing the current time and increasing the cont times area.append(Calendar.getInstance().getTime().toString()+"\n"); count++; if (count == 10) { timer.stop(); count = 0; running = false; } } public static void main(String[] args) { // Executing the frame with its Timer new TimerTest(); } } 

Bene, questo codice è un esempio di come utilizzare gli oggetti javax.swig.Timer. In relazione al caso particolare della domanda. L’istruzione if per fermare il timer deve cambiare e, ovviamente, le azioni dell’actionPerformsd. Il seguente frammento è uno scheletro della soluzione actionPerformsd:

 public void actionPerformsd(ActionEvent e) { if (e.getComponent() == myDealerComponent()) { // I do this if statement because the actionPerformsd can treat more components if (! running) { timer.start(); runnig = true; } // Hit a card if it must be hitted switch (getJBTable(JB.total, JB.aces > 0)) { case 0: JB.hit(); break; case 1: break done; case 2: JB.hit(); JB.bet *= 2; break done; } if (JB.total >= 21) { // In this case we don't need count the number of times, only check the JB.total 21 reached timer.stop() running = false; } } } 

IMHO risolve il problema, ora @ user920769 deve pensare a dove mettere l’actionListener e le condizioni di avvio / arresto …

@kleopatra: Grazie per avermi mostrato l’esistenza di questa class di timer, non ne so nulla ed è sorprendente, rendere ansible un sacco di cose con compiti in un’applicazione swing 🙂

quindi ho guardato Timers, ma non riuscivo a capire come potrei usarne uno per questo

The Timer è la soluzione, poiché come dici tu stai aggiornando la GUI che dovrebbe essere fatta sull’EDT.

Non sono sicuro di quale sia la tua preoccupazione. Ti occupi di una carta e avvia il timer. Quando il timer scocca, decidi di prendere un’altra carta o tenerla. Quando tieni fermo il timer.

Bene, una rapida spiegazione su Timers.

Prima di tutto, hai bisogno di una variabile java.util.Timer nella tua class e di un’altra class nel tuo progetto che si estenda da java.util.TimerTask (chiamiamolo Tasker).

L’inizializzazione della variabile Timer è così semplice:

 Timer timer = new Timer(); 

Ora la class Tasker:

 public class Tasker extends TimerTask { @Override public void run() { actionToDo(); // For example take cards } // More functions if they are needed } 

Infine, l’installazione del timer con il relativo Tasker:

 long delay = 0L; long period = pauseTime; timer.schedule(new Tasker(),delay,period); 

La funzione di pianificazione indica quanto segue: Param prica: Azione da eseguire ogni millisecondo di un periodo (Esegue la funzione di esecuzione di una class TimerTask o la sua estensione) Secondo parametro: quando il timer deve iniziare. In questo caso, inizia quando viene chiamata la funzione di pianificazione. Il seguente esempio indica un avvio 1 secondo dopo chiamata la funzione di pianificazione: timer.schedule(new Tasker(),1000,period); Terzo parametro: millisecondi tra una chiamata della funzione Tasker.run () e la seguente chiamata.

Spero tu capisca questo microtutorial :). Se hai qualche problema, chiedi informazioni più dettagliate!

Cordiali saluti!

Penso che in questo tutorial sia chiaro come usare i Timer per ottenere ciò che vuoi, senza dover trattare con Thread.