Reputation: 145
I am trying to make a JFrame
and see the progress of the counter.
int i = 1;
while (i < 100000){
textField.setText(String.valueOf(i));
System.out.println(i);
i++;
}
When I start it I can see the progress at the console but the value of the textField
does not change. It changes to 100000 when the loop ends.
How can I make it show the progress like in console?
Upvotes: 1
Views: 4492
Reputation: 347184
There are a number of important differences between and other GUI toolkits like C#.
Firstly, Swing components SHARE a common native peer. In many other GUI frameworks, components have their own native peer, this affects the context in which how you can access these components.
Secondly, because Swing components share a common native peer, there are inherently un-thread safe (they all share the same message queue for example), this means you should never modify a UI component out side of the context of the Event Dispatching Thread.
Thirdly, you should never block the Event Dispatching Thread, this will prevent it from process new events, including paint requests.
In this context, you should should probably use s a javax.swing.Timer
, which will allow you to schedule a callback (which will occur within the context of the EDT) at a regular interval, making it safe to use within the context of the Swing framework, for example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Counter {
public static void main(String[] args) {
new Counter();
}
public Counter() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private Timer timer;
private int count;
public TestPane() {
label = new JLabel("...");
setLayout(new GridBagLayout());
add(label);
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
count++;
if (count < 100000) {
label.setText(Integer.toString(count));
} else {
((Timer)(e.getSource())).stop();
}
}
});
timer.setInitialDelay(0);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Take a look at Concurreny in Swing and How to Use Swing Timers for more details...
Upvotes: 3