0

I'm not sure what I was wrong in the code below. It doesn't let me update JTextArea from the extraThread. I can see the status value updated in console windows but it doesn't work for the JTextArea.

Errors

java.lang.NullPointerException
    at test.UI$4.run(UI.java:77)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)

Code

package test;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class UI {

    private JFrame frame;
    private JTextArea txtArea;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UI window = new UI();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public UI() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 171, 334);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JTextArea textArea = new JTextArea();
        textArea.setBounds(10, 11, 133, 239);
        frame.getContentPane().add(textArea);

        JButton btnStart = new JButton("Start");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                process();
            }
        });
        btnStart.setBounds(10, 261, 133, 23);
        frame.getContentPane().add(btnStart);
    }

    private void process() {
        Thread extraThread = new Thread(new Runnable() {
            public void run() {
                int i = 0;
                for(;;) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String status = "Cnt " + i;
                    System.out.println(status);
                    updateTextArea(status);
                    i++;
                }
            }
        });
        extraThread.start();
    }

    private void updateTextArea(String i) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                String prev = txtArea.getText();
                txtArea.setText(prev + "\n" + i);   
            }
        });
    }
}
Louis Tran
  • 1,154
  • 1
  • 26
  • 46
  • 1
    You're declaring a local variable, `JTextArea textArea = new JTextArea();` in your `initialize`, which is the `JTextArea` on the screen, which leaves your instance field, `txtArea` `null` – MadProgrammer Mar 18 '17 at 02:02
  • 1
    Avoid using `null` layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify – MadProgrammer Mar 18 '17 at 02:03
  • 1
    You may also find `JTextArea#append` more useful (and more efficient) then `setText` – MadProgrammer Mar 18 '17 at 02:03
  • Thank you @MadProgrammer, problem solved. :) – Louis Tran Mar 18 '17 at 02:14

0 Answers0