Assuming that your actionPerformed method actionPerformed called in the context of the Dispatching Event thread, no user interface updates will be executed until AFTER the actionPerformed method has actionPerformed , even with SwingUtilities#invokeLater , since the actionPerformed method completes, EDT will not be able to continue processing (among other things) redraw requests.
The best you can do is start the second thread and from within that thread, update the user interface components ... but you will be forced to use SwingUtilities#invokeLater , since you will NEVER update any user interface component outside of the EDT.
The advantage, however, is that the thread does not have to compete for EDT to start processing the redraw request.
UPDATED with an example
public class SwingThreadUpdate { public static void main(String[] args) { new SwingThreadUpdate(); } public SwingThreadUpdate() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new BlinkPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class BlinkPane extends JPanel { private JLabel label; private JButton button; public BlinkPane() { setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridy = 0; label = new JLabel("Blinky"); label.setBackground(Color.RED); button = new JButton("Click me"); add(label, gbc); gbc.gridy++; add(button, gbc); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { button.setEnabled(false); new Thread(new BlinkTask(BlinkPane.this)).start(); } }); } private void setBlink(boolean blink) { label.setOpaque(blink); } private void reset() { button.setEnabled(true); label.setOpaque(false); } } public class BlinkTask implements Runnable { private BlinkPane blinkPane; protected BlinkTask(BlinkPane blinkPane) { this.blinkPane = blinkPane; } @Override public void run() { Blink blinkOn = new Blink(blinkPane, true); Blink blinkOff = new Blink(blinkPane, false); for (int index = 0; index < 10; index++) { if (index % 2 == 0) { SwingUtilities.invokeLater(blinkOn); } else { SwingUtilities.invokeLater(blinkOff); } try { Thread.sleep(125); } catch (InterruptedException ex) { } } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { blinkPane.reset(); } }); } } public class Blink implements Runnable { private BlinkPane blinkPane; private boolean blink; public Blink(BlinkPane blinkPane, boolean blink) { this.blinkPane = blinkPane; this.blink = blink; } @Override public void run() { blinkPane.setBlink(blink); blinkPane.repaint(); } } }
You may need to read "Painting in AWT and Swing" for more information.
source share