marylin17 marylin17 - 1 year ago 81
Java Question

Thread JFrame needs to update JTextPane

I have following code. I need to update JTextPane object when result variable changes. Result variable changes properly, it's tested. This code works as thread. I really doesn't have idea how to solve it, maybe any eventlistener would be good there?

public class GeneralShopFrame implements Runnable, Observer{
private double result = 0 ;
JFrame jf = new JFrame();
JPanel buttonPanel = new JPanel();
JTextPane jtp = new JTextPane();
public void run() {
String[] tab = { "Data_0.txt", "0" } ;
GeneralShopThread gst = new GeneralShopThread(tab);
Runnable r = gst;
Thread t = new Thread(r);

GeneralShopFrame gsf = new GeneralShopFrame();

jtp.setText("Current value of result is " + result); //I NEED UPDATE IT


buttonPanel.setPreferredSize(new Dimension(400, 200));

jf.add(buttonPanel, BorderLayout.CENTER);

public GeneralShopFrame(String[] args) {

public void update(Observable o, Object arg) {

result = (double) arg;

Answer Source

You should call setText(...) on the JTextPane from within the update method, taking care to be sure that it is called on the Swing event thread, e.g., from within a Runnable that is queued on the event thread using SwingUtilities.invokeLater(...). e.g.,

// code not tested
public void update(Observable o, Object arg) {
    SwingUtilities.invokeLater(() -> {
        result = (double) arg;
        jtp.setText("Current value of result is " + result);

But you state that it doesn't work, and your code shows why: you're creating another GeneralShopFrame object within your run method above, one that is not displayed, and because of this, you're notifying the wrong GeneralShopFrame object of changes to an observable. Don't do this. Instead perhaps pass the current GeneralShopFrame object or this into this call:

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download