I want to put a delay between every if in this for
I've triend with Thread.sleep() but this freezes the gui and I don't know is it viable to use multiple swing timers in a loop.
Here I'm trying with a swing timer and keeps freezing the gui, what I'm doing wrong?.
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
int i=0;
public void actionPerformed(ActionEvent evt) {
try
{
System.out.print(solucion.get(i)+" "+solucion.get(i+1)+" "+solucion.get(i+2)+" \n"+solucion.get(i+3)+" "+solucion.get(i+4)+" "+solucion.get(i+5)+" \n"+solucion.get(i+6)+" "+solucion.get(i+7)+" "+solucion.get(i+8));
System.out.println("\n");
Btn1.setText(solucion.get(i));
Btn2.setText(solucion.get(i+1));
Btn3.setText(solucion.get(i+2));
Btn4.setText(solucion.get(i+3));
Btn5.setText(solucion.get(i+4));
Btn6.setText(solucion.get(i+5));
Btn7.setText(solucion.get(i+6));
Btn8.setText(solucion.get(i+7));
Btn9.setText(solucion.get(i+8));
i++;
}
catch(IndexOutOfBoundsException e){((Timer)evt.getSource()).stop();} //if it gets a error we are at the end of the list and stop the timer
}
};
new Timer(delay, taskPerformer).start();
Use a Swing Timer. The Timer replaces the loop.
Every time the Timer fires you set the text and then increment the value of "i". When "i" reaches a specific value you stop the Timer.
See: Jlabel showing both old and new numbers for a simple example to get you started.
Read the section from the Swing tutorial on How to Use Swing Timers for more information.
If you want the guid not to freeze you need to execute it in a different thread. Running it in the main thread will aways cause the guid to freeze. You are using swing so the way to go would be:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// put your statements and delay here
}
});
Related
I want to make a ProgressBar move gradually using a Jbutton. To achieve this I am using a for loop and the method Thread.sleep. The problem is that insted of moving a tiny bit every second (the progress bar) after pressing the button, the program waits until the loop finishes and then does instantly move the progress up. When I take the loop outside of the button listener it works as I want but I really need it to work when pressing the button. Here is the code:
progressBar.setOrientation(SwingConstants.VERTICAL);
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setValue(50);
panel1.setLayout(null);
panel1.add(progressBar);
progressBar.setBounds(40,6,100,100);
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int counter = 5;
for (int i = 0; i < 5; i++) {
progressBar.setValue(progressBar.getValue() + counter);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
});
If anyone can help me I will be very grateful!
Your code runs on the Event Dispatcher Thread (EDT). That thread is responsible for handling events, but also for repainting. Because it's just one thread, the repainting only occurs after your method ends.
There are some ways to solve this. In your case, a javax.swing.Timer would probably be easiest. Instead of running the loop in a single method, the button click starts a timer that runs every second. When it's done the timer can cancel itself. A slightly more difficult alternative is to use a SwingWorker. You could publish data in the doInBackGround method, and override process to perform the updates to the progress bar.
For more information, please read Concurrency in Swing.
Hy!
So I'm starting with netbeans java gui development and I have run into this problem:
I have made a window with a button and a text field. When the user clicks the button I want the text field to start typing itself with a delay. So for example:
textfield.text=h
wait(1) sec
textfield.text=he
wait(1) sec
textfield.text=hel
wait(1) sec
textfield.text=hell
wait(1) sec
textfield.text=hello
I have already tried with Thread.sleep(), but in the example above it waits 4 seconds or so and after that displays the whole text (so it's not giving me the typo effect that I would want).
Can somebody help me with this?
If you use Thread.sleep(...) or any other code that delays the Swing event thread, you'll end up putting the entire Swing event thread to sleep, and with it your application. The key here is to instead use a Swing Timer. In the Timer's ActionListener's actionPerformed method, add a letter and increment your index, and then use that index to decide what letter to next add.
i.e.,
String helloString = "hello";
// in the Timer's ActionListener's actionPerformed method:
if (index >= helloString.length()) {
// stop the Timer here
} else {
String currentText = textField.getText();
currentText += helloString.charAt(index);
textField.setText(currentText);
index++;
}
Got it working by using something like this:
Timer a,b,c
Timer c=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(abc)}})
Timer b=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(ab);c.start()}})
Timer a=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(a);b.start()}})
a.setRepeats(false);
b.setRepeats(false);
c.setRepeats(false);
a.start()
Does anybody know a more simple method with the same effect maybe?
For some reason even though I am using the exact code example from oracle's website for the Swing Timer it is not waiting for 1 second. It just skips to the JOptionPane that says "Your score was etc etc".
Here is my source code for a school project. Why is this not working and not waiting for 1 second before running the rest of the code?
//Check to see if user has enetered anything
if(!answered)
{
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
afk = true;
incorrect += 1;
answered = true; //This breakes it out of the loop
}
A timer is used to run a callback after a specific amount of time. If you simply want to delay, you can either move the code to be run after the delay into the taskPerformer action listener.
Thread.sleep(1000) is not ideal here, because it will cause the UI to completely freeze as you will make the UI thread sleep.
Hy!
So I'm starting with netbeans java gui development and I have run into this problem:
I have made a window with a button and a text field. When the user clicks the button I want the text field to start typing itself with a delay. So for example:
textfield.text=h
wait(1) sec
textfield.text=he
wait(1) sec
textfield.text=hel
wait(1) sec
textfield.text=hell
wait(1) sec
textfield.text=hello
I have already tried with Thread.sleep(), but in the example above it waits 4 seconds or so and after that displays the whole text (so it's not giving me the typo effect that I would want).
Can somebody help me with this?
If you use Thread.sleep(...) or any other code that delays the Swing event thread, you'll end up putting the entire Swing event thread to sleep, and with it your application. The key here is to instead use a Swing Timer. In the Timer's ActionListener's actionPerformed method, add a letter and increment your index, and then use that index to decide what letter to next add.
i.e.,
String helloString = "hello";
// in the Timer's ActionListener's actionPerformed method:
if (index >= helloString.length()) {
// stop the Timer here
} else {
String currentText = textField.getText();
currentText += helloString.charAt(index);
textField.setText(currentText);
index++;
}
Got it working by using something like this:
Timer a,b,c
Timer c=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(abc)}})
Timer b=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(ab);c.start()}})
Timer a=new Timer(500, new ActionListener(){public void actionPerformed(ActionEvent e){textfield.setText(a);b.start()}})
a.setRepeats(false);
b.setRepeats(false);
c.setRepeats(false);
a.start()
Does anybody know a more simple method with the same effect maybe?
I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.
An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.
If the timer reaches zero, the program quits.
If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.
There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.
I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)
My questions are:
What is the best way to implement this?
I'm assuming this needs to run in a thread?
Will the timer be easily configurable? (not important, just interesting)
Thanks for your help. If you need to see code, I can find some.
EDIT: Just for some clarification/context:
This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.
If I were you, I'd use:
an AtomicInteger variable which would keep the current countdown value;
a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
(possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.
Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.
The timer thread's run() method could be as simple as:
for (;;) {
if (counter.decrementAndGet() <= 0) {
// TODO: exit the app
}
Thread.sleep(1000);
}
I think it's much easier to get this right than trying to manage multiple Timer objects.
The best way to impliment timer in your application is using some sheduler frameworks like Quartz
You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.
Like this:
timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
And then make a class like this to handle the timerschedule:
class Task extends TimerTask {
public void run() {
System.exit(0);
}
}
If the requirements is met, then do this to stop it from executing:
timer.cancel();
If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker
I would write something like this:
SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
Integer timer=60;
#Override
protected String doInBackground() throws Exception {
//update guiModel
//label.setText(timer.toString());
while(timer>0){
Thread.sleep(1000);
timer--;
}
return null;
}
#Override
public void done(){
System.exit(0);
}
};
JButton restart = new JButton(){
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.cancel(true);
timer.execute();
}
});
}
};