aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Can't update GUI from thread - need syntax for invokeLater Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Can Watch "Can New topic
Author

Can't update GUI from thread - need syntax for invokeLater

Paul Carter
Ranch Hand

Joined: Sep 20, 2006
Posts: 57
Serious Greenhorn here...

Been messing around for a while, but can't get a label to change between 2 colours with a pause in the middle when running via the ActionListener thread created for the buttons (my actual requirement is more elaborate than that, but this illustrates the problem).

As I understand it the ActionListener for the buttons is a thread, and as such does not update the GUI until it has completed i.e. only the last colour change is effective.

I've had a few suggestions, but can't seem to get them to work. I think I just need to see it applied to my problem for it to make sense.

As such can someone just edit this example to show how you would get the method DOCOLOURCHANGES to update the GUI correctly i.e. change the colours of a label with a pause in between.

Major thanks in advance

Paul.

P.S. Apologies if there are any glaring errors - I have edited the code to simplify in places and may have knocked something out - my actual code does work (minus the first colour change).

/*
* Tower.java
*
* Created on 28 July 2006, 11:02
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package darktower;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


/**
*
* @author paul
*/
public class Tower extends JPanel {

final static Label picLabel = new Label;
final static TowerCode tc = new TowerCode();
final static String btnCaptions[] = {
"Yes/Buy", "Repeat", "No/End", "Haggle", "Bazaar", "Clear", "Tomb",
"Move", "Sanctuary", "DarkTower", "Frontier", "Inventory"};

/** Creates a new instance of Tower */
public Tower(JFrame frame) {

super(new BorderLayout());
setLayout(new GridLayout(2, 1));

JPanel buttonsPanel = CreateTowerButtons();
buttonsPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

add(picLabel);
add(buttonsPanel);

tc.SetUpGame();
}

private JPanel CreateTowerButtons(){
final JButton[] towerButtons = new JButton[btnCaptions.length];

for (int buttonNo=0;buttonNo<towerButtons.length; ++buttonNo) {
final int buttonNo2 = buttonNo;

towerButtons[buttonNo] = new JButton(btnCaptions[buttonNo]);

towerButtons[buttonNo].addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
DOCOLOURCHANGES();

}
});
}
return createPane("Whatever", towerButtons);
}

private JPanel createPane(String description, JButton[] TowerButtons) {
int NumButtons = TowerButtons.length;

JPanel newBox = new JPanel();
newBox.setLayout(new GridLayout(0, 3));

for (int i = 0; i < NumButtons; i++)
newBox.add(TowerButtons[i]);

return newBox;
}

private static void CreateAndShowTowerGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window
JFrame MainTowerFrame = new JFrame("Dark Tower");
MainTowerFrame.setPreferredSize(new Dimension(350, 400 ));

MainTowerFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Set up the 1st Controls container
Container MainTowerContainer = MainTowerFrame.getContentPane();

//Populate the MainContainer control
MainTowerContainer.add(new Tower(MainTowerFrame));

//Diplay The Window
MainTowerFrame.pack();
MainTowerFrame.setVisible(true);
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
//Schedule thread to show GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
CreateAndShowTowerGUI();
}
});
}
}


final void DOCOLOURCHANGES(); {
picLabel.setIcon(new ImageIcon("C:/DT/images/BLACK.jpg));
sleep(1000);
picLabel.setIcon(new ImageIcon("C:/DT/images/RED.jpg));
}
[ January 10, 2007: Message edited by: Paul Carter ]
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
here's a simple demo from your description
(the delay has to be in a separate thread, otherwise the gui painting is
blocked, then the gui updated via SwingUtilities...)



but it may be a bit easier for you if you used a timer

Paul Carter
Ranch Hand

Joined: Sep 20, 2006
Posts: 57
Thanks for that, but still can't get the syntax right for the second image i.e.

new Thread(){
public void run(){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
picLabel.setIcon(new ImageIcon("C:/DT/images/BEAST.jpg"));
}
});
try{Thread.sleep(1000);}catch(InterruptedException ie){ie.printStackTrace();}

}
NOW SHOW SECOND IMAGE AFTER THE ABOVE PAUSE
}.start();
Paul Carter
Ranch Hand

Joined: Sep 20, 2006
Posts: 57
Ah wait.... Have something that seems to show it working in principle.

I now need to play a little bit.

Many thanks

Paul.

private void MiniTest(int pauseVal, String picName) {
new Thread(){
public void run(){
try{Thread.sleep(1000);}catch(InterruptedException ie){ie.printStackTrace();}

SwingUtilities.invokeLater(new Runnable(){
public void run(){
picLabel.setIcon(new ImageIcon("C:/DT/images/BEAST.jpg"));
}
});
try{Thread.sleep(1000);}catch(InterruptedException ie){ie.printStackTrace();}

SwingUtilities.invokeLater(new Runnable(){
public void run(){
picLabel.setIcon(new ImageIcon("C:/DT/images/HEALER.jpg"));
}
});
try{Thread.sleep(1000);}catch(InterruptedException ie){ie.printStackTrace();}

SwingUtilities.invokeLater(new Runnable(){
public void run(){
picLabel.setIcon(new ImageIcon("C:/DT/images/SCOUT.jpg"));
}
});
}
}.start();
}
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can't update GUI from thread - need syntax for invokeLater