I need a delay in my JTable every time a row is added.
public void añadirNuevo(Procesos procesosArray){
for(int i=0;i<procesosArray.size();i++){
Object nuevo[]= {procesosArray.obtener(i).getNombre(),procesosArray.obtener(i).getTam()};
nuevoTbl.addRow(nuevo);
//DELAY
}
}
Use javax.swing.Timer
Setting up a timer involves creating a Timer object, registering one
or more action listeners on it, and starting the timer using the start
method. For example, the following code creates and starts a timer
that fires an action event once per second (as specified by the first
argument to the Timer constructor). The second argument to the Timer
constructor specifies a listener to receive the timer's action events.
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
You can use Thread.sleep method
public void añadirNuevo(Procesos procesosArray){
for(int i=0;i<procesosArray.size();i++){
Object nuevo[]= {procesosArray.obtener(i).getNombre(),procesosArray.obtener(i).getTam()};
nuevoTbl.addRow(nuevo);
try {
Thread.sleep(1000); // 1 second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
Related
I need to make a GUI where a worker enters a station (a spot on the panel) and stays there for a set amount of seconds, shown in a countdown about the workers head (so, once the workers moves to the spot, the station's label shows 3s -> 2s -> 1s and then the worker leaves, and the label reverts back to "OPEN"). I'm having trouble with making this happen, as I'm not too good with the Timer(s?) that Java has. I tried with something like this:
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
//change label text/color, decrement countdown
panel.repaint();
Thread.sleep(1000);
}
});
But I can't reach the number of seconds to count down from from inside the timer, and I'm not sure how to pass that value to the timer. If someone can help me out, I'd really appreciate it.
Get rid of the Thread.sleep(). That's what the 1000 in Timer(1000, new ActionListener() does. It sets an interval for each timer event. Every time a timer event is fired, the actionPerformed is called. So you need to determine what needs to happen every "tick", and put that code in the actionPerformed. Maybe something like
Timer timer = new Timer(1000, new ActionListener() {
private int count = 5;
#Override
public void actionPerformed(ActionEvent e) {
if (count <= 0) {
label.setText("OPEN");
((Timer)e.getSource()).stop();
count = 5;
} else {
label.setText(Integer.toString(count);
count--;
}
}
});
You need to decide when to call timer.start().
For general information, see How to Use Swing Timers
Problem #1: You are calling Thread.sleep() from within the Swing GUI thread. That causes the thread to stop taking input and freeze. Delete that line. It does you no good! While you are at it, delete the repaint call as well.
Now that that's said and done, instead of creating an anonymous instance of ActionListener, you can create an actual class that implements ActionListener and provides a constructor. That constructor can have as an argument the number of seconds you want to start counting down. You can declare that class inside the method you are using, or you can declare it inside the class.
Here's a skeletal example:
public class OuterClass {
JLabel secondsLabel = ...;
Timer myTimer;
private void setupTimer(int numSecondsToCountDown) {
secondsLabel.setText(Integer.toString(numSecondsToCountDown));
myTimer = new Timer(1000, new CountdownListener(numSecondsToCountDown));
myTimer.start();
}
// ...
class CountdownListener implements ActionListener {
private int secondsCount;
public CountdownListener(int startingSeconds) { secondsCount = startingSeconds; }
public void actionPerformed(ActionEvent evt) {
secondsLabel.setText(Integer.toString(secondsCount);
secondsCount--;
if (secondsCount <= 0) { // stop the countdown
myTimer.stop();
}
}
}
}
I'm trying to stop the program for a second using Swing Timer.
Timer timer = new Timer(10000,
new ActionListener(public void actionPerformed(ActionEvent e) {}));
didn't work
public class Card extends JButton implements ActionListener {
int numberClick = 0;
public card() {
addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
numberClick++;
if(numberClick == 2) {
Timer timer = new Timer(10000, );
timer.start();
numberClick = 0;
}
}
}
You seem to lack basic understanding of how the Timer works. Please read How to Use Swing Timers. The concept is fairly simple.
The first argument in the Timer constructor is the delay. Seems you have that part down. The second argument is the ActionListener that listens for the "Timer Events" (actually ActionEvents). An event is fired each delayed time. The callback (actionPerformed) contains what should be performed after that delay (tick). So whatever you want to happen after that second, put it in the actionPerformed of the timer's ActionListener.
Also if you only want it t occur once, you should call timer.setRepeats(false);. Also note, you are using 10000, which is in milliseconds, so it's 10 seconds, not 1. You should change it to 1000
Example Flow
JButton button = new JButton("Press Me");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
Timer timer = new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Print after one second");
}
});
timer.setRepeats(false);
timer.start();
}
});
Press Button → Wait One Second → Print Statement
I am trying to implement a Thread.sleep(6000) line but it seems to freeze in the applet. When I tried to use Timers, I wasn't sure how to use because I am not very good with event listeners. I am basically trying to call a method fetchUrl() every 6 seconds, after the user clicks the enter button. How can I implement this?
public void init() {
c = getContentPane();
c.setLayout(flow);
c.setBackground(forum);
question.setForeground(Color.white);
question.setFont(tnr);
question2.setForeground(Color.white);
question2.setFont(tnr);
result.setForeground(Color.white);
result.setFont(tnr);
resp.setBorder(BorderFactory.createBevelBorder(0));
timeLength.setBorder(BorderFactory.createBevelBorder(0));
c.add(question);
c.add(resp);
c.add(question2);
c.add(timeLength);
c.add(enter);
c.add(result);
resp.requestFocus();
enter.addActionListener(this);
t = new Timer(DELAY, this);
t.setInitialDelay(DELAY);
}
public void actionPerformed(ActionEvent e) {
final String n1;
int timeMin, timeSec, count = 0, maxCount;
timeMin = Integer.parseInt(timeLength.getText());
timeSec = timeMin * 60;
maxCount = (int)(timeSec/6);
if (e.getSource() == enter) { //user clicks enter
n1 = resp.getText();
while (count < maxCount) {
fetchUrl(n1); //this method called every 6 seconds
t.start();
count++;
}
}
}
First I would start by separating the ActionListener for the Timer and for the JButton.
Second nothing is happening logically with the Timer because you're swallowing it with the button source check.
Third you should understand how the timer works. Basically for every "tick" (in your case six seconds) the actionPerformed of the timer ActionListener is called. So if you want the fetch() method called, then that's what you should be visible/accessible to the in the Timer's actionPerformed.
The button's ActionListener should only handle the starting of the timer I believe. So just separate the listeners. Give each one an anonymous ActionListener and no need to make the class implement ActionListener.
For example
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do some stuff every six seconds
fetchURL();
}
});
enter = new JButton(...);
enter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
If you want some automatic stopping feature for the timer, you could do something like
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (someStoppingCondition()) {
timer.stop();
} else {
// do some stuff every six seconds
fetchURL();
}
// do some stuff every six second
}
});
You need to call a method after user clicks on button every 6 seconds, but you have not said how many times you want to call it.
For infinite number of times, try something like the following,
while(true){
new Thread(){
#Override
public void run(){
try{
Thread.sleep(6000);
fetchUrl(n1);
}catch(InterruptedException e){}
}
}.start();
}
If you will use Thread.sleep() in your applet, then your applet will be hanged for 6 seconds and so create a new thread for it.
Basically, I have this game where once guesses the correct answer it starts a new game with a new word. I want to display Correct! but after three seconds, change it to a empty string. How do I do that?
My attempt:
if (anagram.isCorrect(userInput.getText()))
{
anagram = new Anagram();
answer.setText("CORRECT!");
word.setText(anagram.getRandomScrambledWord());
this.repaint();
try
{
Thread.currentThread().sleep(3000);
}
catch (Exception e)
{
}
answer.setText("");
} else
{
answer.setForeground(Color.pink);
answer.setText("INCORRECT!");
}
Edit:
My solution:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
// TODO add your handling code here:
if (anagram.isCorrect(userInput.getText()))
{
answer.setText("CORRECT!");
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
anagram = new Anagram();
word.setText(anagram.getRandomScrambledWord());
answer.setText("");
userInput.setText("");
}
};
Timer timer = new Timer(3000, taskPerformer);
timer.setRepeats(false);
timer.start();
} else
{
answer.setForeground(Color.pink);
answer.setText("INCORRECT!");
}
}
I am not sure, but I hope that I am following MadProgrammer's advice and not blocking the event itself, but the new thread. I will look up Java Timer also.
Swing is an event driven environment. While you block the Event Dispatching Thread, no new events can be processed.
You should never block the EDT with any time consuming process (such as I/O, loops or Thread#sleep for example).
You might like to have a read through The Event Dispatch Thread for more information.
Instead, you should use a javax.swing.Timer. It will trigger a ActionListener after a given delay.
The benefit of which is that the actionPerformed method is executed with the context of the Event Dispatching Thread.
Check out this or this or this or this for an examples
it works after 3 seconds..
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
statusbar.setText("Status");
}
};
Timer timer = new Timer(3000, taskPerformer);
timer.setRepeats(false);
timer.start();
if these piece of code is in the event handlers, then you are holding up the UI thread, and it is not going to work as UI update will only happens after you finished your work in the event handlers.
You should create another thread do the work of "sleep 3 second, and change the text field, and trigger repaint". Using Timer or similar utilities is the easiest way to achieve what I am describing.
private class MultipleGensListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
for(int i = 0; i < 25; i++)
{
game.runSimulationOneGen();
changeGrid();
}
}
}
//this is the loop. The changeGrid method displays a game grid on a GUI but
// only the 25th iteration is visible on screen. I would like each one to be
// visible for about a half a second before the loop continues.
// I have seen some questions answered on here that are very close to what I'm asking,
// but I just don't really understand how to apply it to my program..
// thanks for any help.
If the code performed by the simulation is quick and does not consume too much CPU and time, then consider using a Swing Timer to do your looping and delay. Otherwise, you'll need to use a background thread such as can be done with a SwingWorker object.
For e.g. if using both Swing Timer and SwingWorker:
private class MultipleGensListener implements ActionListener {
protected static final int MAX_INDEX = 25;
public void actionPerformed(ActionEvent e) {
int timerDelay = 500; // ms delay
new Timer(timerDelay, new ActionListener() {
int index = 0;
public void actionPerformed(ActionEvent e) {
if (index < MAX_INDEX) { // loop only MAX_INDEX times
index++;
// create the SwingWorker and execute it
new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
game.runSimulationOneGen(); // this is done in background thread.
return null;
}
#Override
protected void done() {
changeGrid(); // this is called on EDT after background thread done.
}
}.execute(); // execute the SwingWorker
} else {
((Timer) e.getSource()).stop(); // stop the timer
}
}
}).start(); // start the Swing timer
}
}
NEVER BLOCK THE GUI EVENT THREAD
you can use a timer for that and have it only fire 25 times
final Timer t = new Timer(500,null);
t.addActionListener(new ActionListener(){
int i=0;
public void actionPerformed(ActionEvent e){
game.runSimulationOneGen();//run 1 iteration per tick
changeGrid();
if(i>25){t.stop();}
i++;
}
});
t.setRepeats(true);
t.start();
btw the reason only the last iteration is shown is that gui updates (redraws) are done in a separate event, but to let another event trigger you need to return from the listener method which you didn't
the Timer I showed is a more elaborate iteration which lets other events run in between iterations allowing the gui to show the changes
check my post that shows both methods java.swing.Timer#setDelay(int)
and
correct usage of Thread.sleep(int)
java wait cursor display problem