Hard to know what is happening without code, but probably the Event Dispatch Thread (EDT) is being blocked (or terminated?), e.g. by code being called by invokeLater
. The EDT is used to update the GUI and should not be used for (slow) non-GUI related calculations. See tutorial The Event Dispatch Thread and subsequent for more details.
Example (without blocking):
import java.awt.*;
import java.awt.event.ActionEvent;
import java.time.LocalTime;
import javax.swing.*;
public class LabelProgress {
public static void main(String[] args) {
LabelProgress main = new LabelProgress();
SwingUtilities.invokeLater(() -> main.showInternal1());
SwingUtilities.invokeLater(() -> main.showInternal2());
}
private JFrame frame;
private JLabel label;
private JDesktopPane desktop;
private JProgressBar bar;
private int progress = 0;
private LabelProgress() {
label = new JLabel("Label: ");
desktop = new JDesktopPane();
bar = new JProgressBar(0, 100);
bar.setStringPainted(true);
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(label, BorderLayout.BEFORE_FIRST_LINE);
frame.add(desktop, BorderLayout.CENTER);
frame.add(bar, BorderLayout.AFTER_LAST_LINE);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(600, 400);
frame.validate();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void showInternal1() {
JButton change = new JButton("Change");
change.addActionListener(this::doChange);
JInternalFrame internal = new JInternalFrame("Change Label");
internal.setLayout(new FlowLayout());
internal.add(change);
internal.setBounds(20, 20, 200, 150);
internal.setVisible(true);
desktop.add(internal);
}
private void showInternal2() {
JButton task = new JButton("Task");
task.addActionListener(this::doTask);
JInternalFrame internal = new JInternalFrame("Small Task");
internal.setLayout(new FlowLayout());
internal.add(task);
internal.setBounds(150, 100, 200, 150);
internal.setVisible(true);
desktop.add(internal);
}
private void doChange(ActionEvent ev) {
// using a SwingWorker:
// for demonstration I used an anonymous class, maybe a own class is better
SwingWorker<LocalTime , Void> worker = new SwingWorker<LocalTime , Void>() {
@Override
protected LocalTime doInBackground() throws Exception {
// not executed on the EDT - just get the current time
LocalTime someCalculation = LocalTime.now();
return someCalculation;
}
@Override
protected void done() {
// executed on EDT
try {
LocalTime resultOfSomeCalculation = get();
label.setText("Label: " + resultOfSomeCalculation.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
worker.execute();
}
private void doTask(ActionEvent ev) {
// no need to use SwingWorker
Thread thread = new Thread(this::slowTask);
thread.start();
}
private void slowTask() {
// not really that slow, just for demonstration
progress += 10;
if (progress > 100) progress = 100;
// and now switching to the EDT
SwingUtilities.invokeLater(() -> bar.setValue(progress));
}
}