Swing is a single threaded framework. That is, all interactions with UI are expected to occur from within a single thread, known as the Event Dispatching Thread.
Any action that blocks this thread, will prevent the EDT from updating the screen or processing any new events.
Your while-loop
is blocking the EDT, preventing it from painting any updates until after the while-loop
is completed.
Take a look at Concurrency in Swing for more details.
There are a number of approaches you could take...
You could use a Thread
, but this causes problems as you need to ensure that any changes you make to the UI are re-synced back to the EDT and this can become messy...
For example
You could use a javax.swing.Timer
that ticks at a regular interval and you would update any internal parameters from within it's assigned ActionListener
. Because the tick events occur within the EDT, it is save to update the screen from within it.
For example
You could use a SwingWorker
to run the task in the background. It has methods for re-syncing updates back to the EDT, but might be a little over kill for your purposes...
Updated with a possible Timer
example
Caveat- It is very hard to produce a reasonable example with only a code snippet, but, something like this might work
public void golpe(final int pbola, int pvelocidad, String pdireccion, final JLabel[] listalabels) throws InterruptedException{
listabolas[pbola].setVelocidad(pvelocidad);
listabolas[pbola].setDireccion(pdireccion);
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (listabolas[pbola].getVelocidad() == 0) {
((Timer)evt.getSource()).stop();
} else {
moverBola(pbola, listalabels);
}
}
});
timer.setRepeats(true);
timer.start();
}