Search code examples
javaswingjtextareathread-sleep

How to force JTextArea to be editable and clickable and flush output immidiately?


I have two classes. The main class:

public class TestJTA {


        public static JTextArea text;

        public static void main(String [] args) {
            Runnable r = new Runnable() {
                public void run() {
                                        createGUI();
                 }

            } ;
    javax.swing.SwingUtilities.invokeLater(r);
        }

    public static  void createGUI() throws IOException {

        JFrame j = new JFrame("C5er");
        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ActionListener al = new ActionListener() {
            @SuppressWarnings("deprecation")
            public void actionPerformed (ActionEvent e ) {
                try {
                    PrintToJTA.startPrinting();
              } catch (Exception ex) {}
            }
        }
        ;
        j.setLayout(null);

        text = new JTextArea();
        JScrollPane scroll = new JScrollPane(text);
        scroll.setBounds(280,30,200,100);
        j.add(scroll);


        JButton b = new JButton("Start");
        b.setBounds(100,20,80,30);
        b.addActionListener(al);
        j.add(b);


        j.setSize(600,250);
        j.setVisible(true);
        j.setLocationRelativeTo(null);
        j.getContentPane().setBackground(Color.white);
    }

}

The secondary class is:

public class PrintToJTA {
public static void startPrinting () throws InterruptedException {
    for (int i = 0; i < 10 ; i++) {
        TestJTA.text.append("hello\n");
Thread.sleep(300);
    }
}
}

When I click start, the textArea FREEZES ... and becomes non clickable ... and only after some time I get the output. How can I make my JTextArea to be clickable, editable all the time and flush output immidiately? I need it to be clickable during the Thread.sleep wait


Solution

  • Okey, that's the right time study SwingTimer.

    Thread#sleep() usually uses with Command line, but with GUI, it's highly recommended to use SwingTimers:

    public class PrintToJTA {
    private final int delay = 20;
    private int counter;
    private javax.swing.Timer timer;
    private JTextArea area;
    {timer = new javax.swing.Timer(delay,getTimerAction());}
    
    public void startPrinting (JTextArea textArea) throws InterruptedException {
           //....
           area = textArea;
           timer.start();
        }
    private ActionListener getTimerAction(){
      return new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            if(++counter >= 10)
               timer.stop();
            area.appent("Hello\n");
    
         }
    };
    
    }
    

    And call it like that

    //....
    new PrintToJTA().startPrinting(text );
    //...
    

    NOTE: I didn't compile this code.