Rane
Rane

Reputation: 191

Can I change the text of a label from a Thread in Java?

I have another question for this forum. I am writing a small application with Java in which I have multiple Threads. I have two Threads that are in two different classes. I have one Thread (thread1) dedicated to defining all of the JFrame components. (JPanels, JButtons, ActionListeners, etc.) In another Thread, (thread2) I am checking for a variable (v) to equal a certain value. (98) When this variables does change to equal 98, that same thread is supposed to update a JLabel. (Let's call this label label for now.) It does not. Is there something I am doing wrong. I have tried writing a method for the class - that declares all of the JFrame components - that changes the text of label, but when I call this method from thread2 it does not update the label. I have tried calling a super class containing thread1, but that did not seem to make a difference. Also, I have been calling the repaint() method, but that does not seem to help.

Please let me know what I can do to update these JLabels from the two different Threads.

Thanks in advance, ~Rane

Code:

Class1:

JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("V does not equal 98 Yet...");
Thread thread1 = new Thread(){

  public void run(){

    panel.add(label);
    frame.add(panel);
    System.out.println("Components added!");

  }
});

public void setLabelText(String text){
  label.setText(text);
}

Class1=2:

v = 0;
Thread thread2 = new Thread(){

  public void run(){

    while(v < 98){

      System.out.println("V equals -" + v + "-.");
      v ++;
    }
    Class1 otherClass = new Class1();
    otherClass.label.setText("V is now equal to: " + v);
    otherClass.repaint();
    otherClass.setLabelText("V is now equal to: " + v);
    otherClass.repaint();
  }
});

Upvotes: 0

Views: 7525

Answers (1)

durron597
durron597

Reputation: 32323

Swing is not thread-safe. I repeat: do not call any methods on Swing objects from any threads other than the Event Dispatch Thread (EDT)

If you are getting events from multiple different threads and you want to have them directly affect Swing objects, you should use:

// Note you must use final method arguments to be available inside an anonymous class
private void changeJLabel(final JLabel label, final String text) {
  EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
      myLabel.setText(text);
    }
  });
}

Upvotes: 9

Related Questions