Updating JTextArea from Observer

Hello everyone,

I was trying to update my UI by using an observer which notifies me whenever something changes.

The problem I have is that my UI always freezes until my function is done running and then parses all the info the observer passed to the TextArea instead of parsing it whenever I do the notify. Though if I write the info the oberserver passes to the console window it works properly. Now I read it has something to do with multithreading. The UI is locked because my functions is running and thus can't update.

But I have no clue how to solve it. Can someone give me a hint on how to make it work?

Below you can find a simple example.

Thanks in advance for any help.

My Main Class (The observer)

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Observable;

import java.util.Observer;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextArea;

publicclass Mainextends JFrameimplements ActionListener,Observer{

private JTextArea txtTest;

private JPanel pnlTest;

private JButton btnTest;

public Main(){

pnlTest =new JPanel(null);

txtTest =new JTextArea();

txtTest.setBounds(250, 325, 550, 150);

txtTest.setEditable(false);

btnTest =new JButton("Test");

btnTest.setBounds(400, 500, 150, 25);

btnTest.addActionListener(this);

pnlTest.add(txtTest);

pnlTest.add(btnTest);

this.getContentPane().add(pnlTest);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setTitle("Test");

this.setSize(1024,784);

this.show();

}

publicstaticvoid main(String[] args){

Main m =new Main();

}

publicsynchronizedvoid update(Observable o,final Object arg){

txtTest.append(arg.toString());

System.out.println(arg);

}

publicvoid actionPerformed(ActionEvent arg0){

Object obj = arg0.getSource();

if(obj == btnTest){

testRun tr =new testRun();

tr.addObserver(this);

tr.run();

}

}

}

My Class containing the function (Observable)

import java.util.Observable;

publicclass testRunextends Observable{

public testRun(){

}

publicvoid run(){

for(int i=0; i <= 1000; i++){

setChanged();

notifyObservers("a");

}

}

}

Observer interface

import java.util.Observable;

publicinterface Observer{

publicvoid upate(Observable o,Object arg);

}

Message was edited by:

lemr

Message was edited by:

lemr

[5008 byte] By [lemra] at [2007-11-27 6:41:48]
# 1

Hi

You must use event dispatch thread to run GUI work & ordinary thread for background work.

read this http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html

use SwingUtilities.invokeLater(); method to your run()::testRun as

public class testRun extends Observable implements Runnable {

public testRun(){

}

public void run(){

if(SwingUtilities.isEventDispatchThread())

{

for(int i=0; i <= 1000; i++){

setChanged();

notifyObservers("a");

}

else

SwingUtilities.invokeLater(this);

}

}

}

GsrCa at 2007-7-12 18:11:41 > top of Java-index,Desktop,Core GUI APIs...
# 2

Thanks for your answer but it still doesn't work I even tried other things I found in the article.

It still finishes the loop leaving my GUI in a lock and then updates the textarea.

I read an article here to use weak references but I have no clue what they mean by that. (feels stupid).

Any solutions are welcome :).

lemra at 2007-7-12 18:11:41 > top of Java-index,Desktop,Core GUI APIs...
# 3
> it still doesn't work Then your code is still running in the GUI event Thread. This posting shows how to create a separate Thread: http://forum.java.sun.com/thread.jspa?forumID=57&threadID=621226
camickra at 2007-7-12 18:11:41 > top of Java-index,Desktop,Core GUI APIs...