Update Jlabel Every X Seconds from Arraylist<List> - Java

Update JLabel every X seconds from ArrayList List - Java

First, build and display your GUI. Once the GUI is displayed, use a javax.swing.Timer to update the GUI every 500 millis:

final Timer timer = new Timer(500, null);
ActionListener listener = new ActionListsner() {
private Iterator<Word> it = words.iterator();
@Override
public void actionPerformed(ActionEvent e) {
if (it.hasNext()) {
label.setText(it.next().getName());
}
else {
timer.stop();
}
}
};
timer.addActionListener(listener);
timer.start();

JLabel will not update unless something causes the method to hang

Make sure you don't run your task (your "Loading..." procedure) on the EDT (Event Dispatch Thread); if you do so, your GUI won't get updated.

You have to run your application code (unless it's very fast, say less than 100ms, no network access, no DB access, etc) on a separate thread. The SwingWorker (see javadocs) class might come handy for this purpose.

The EDT (e.g. code blocks inside user interface listeners) should only contain code for updating the GUI, operating on Swing components, etc. Everything else you should run on its own Runnable object.

--

EDIT: reponse to Andy's comment. Here's a raw example (written on the fly, it might have typos and such and might not run as-is) of how you can use the SwingWorker class

Put this in your mouse listener event or whatever makes your task start

//--- code up to this point runs on the EDT
SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>()
{

@Override
protected Boolean doInBackground()//This is called when you .execute() the SwingWorker instance
{//Runs on its own thread, thus not "freezing" the interface
//let's assume that doMyLongComputation() returns true if OK, false if not OK.
//(I used Boolean, but doInBackground can return whatever you need, an int, a
//string, whatever)
if(doMyLongComputation())
{
doSomeExtraStuff();
return true;
}
else
{
doSomeExtraAlternativeStuff();
return false;
}
}

@Override
protected void done()//this is called after doInBackground() has finished
{//Runs on the EDT
//Update your swing components here
if(this.get())//here we take the return value from doInBackground()
yourLabel.setText("Done loading!");
else
yourLabel.setText("Nuclear meltdown in 1 minute...");
//progressBar.setIndeterminate(false);//decomment if you need it
//progressBar.setVisible(false);//decomment if you need it
myButton.setEnabled(true);
}
};
//---code under this point runs on the EDT
yourLabel.setText("Loading...");
//progressBar.setIndeterminate(true);//decomment if you need it
//progressBar.setVisible(true);//decomment if you need it
myButton.setEnabled(false);//Prevent the user from clicking again before task is finished
sw.execute();
//---Anything you write under here runs on the EDT concurrently to you task, which has now been launched

Update my textField every 5 seconds

The easiest way to achieve this is using class Timer.

    Timer t = new Timer();
t.schedule(new TimerTask() {
@Override public void run() {
// textField_t.setText(YOUR TEXT);
}
}, 0L, 5000L);

Increase or Decrease Swing Timer Speed with Buttons?

Can't you do the following? The timing won't be perfect but probably not noticeable to the user:

   bFaster.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tM = 100;
timer.stop();
timer.setDelay( tM );
timer.start();
}
});
bSlower.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tM = 1000;
timer.stop();
timer.setDelay( tM );
timer.start();
}
});

Timer pause before jlabel change its text

A possible way to do that goes something like this:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.*;
import java.util.Timer;

import javax.swing.*;

public class StackOverflow {

private final List<JLabel> arrayList = Arrays.asList(new JLabel("This is the first text."), new JLabel("This is the second text."), new JLabel("And this is the third and last text."));
private JFrame frame;
private JButton button;

public static void main(final String[] arguments) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
StackOverflow clazz = new StackOverflow();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
clazz.create("Stackoverflow | Question", 350, 200);
clazz.doLayout();
}

public void create(final String title, final int width, final int height) {
this.frame = new JFrame(title);
EventQueue.invokeLater(() -> {
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setLocationRelativeTo(null);
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
frame.getContentPane().setBackground(Color.WHITE);
frame.setVisible(true);
});
}

public void doLayout() {
this.button = new JButton("Answer question");
EventQueue.invokeLater(() -> {
button.addActionListener(new ActionListener() {
int index = 0;
@Override
public void actionPerformed(final ActionEvent action) {
// Important: This is the java.util.Timer and not the javax.swing.Timer class.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (index + 1 >= arrayList.size()) {
timer.cancel();
}
EventQueue.invokeLater(() -> {
frame.getContentPane().add(arrayList.get((index += 1) - 1));
frame.getContentPane().validate();
});
}
}, 0l, 2000l);
}
});
frame.add(button);
});
}
}

Hopefully, this answers your question. If it did, Show it to me with an upvote.

How to repaint a jpanel every x seconds?

Use Swing Timer,

class GamePanel extends JPanel implements ActionListener{

Timer timer=new Timer(1000, this);

public GamePanel() {
timer.start();// Start the timer here.
}

public void actionPerformed(ActionEvent ev){
if(ev.getSource()==timer){
repaint();// this will call at every 1 second
}

}


Related Topics



Leave a reply



Submit