0

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

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Aleksei Nikolaevich
  • 325
  • 3
  • 15
  • 40
  • 2
    Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. – Andrew Thompson Oct 16 '13 at 19:25
  • 1
    `scroll.setBounds(280,30,200,100);` Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). – Andrew Thompson Oct 16 '13 at 19:26
  • @AndrewThompson Could just about copy and paste thoughts comments into an answer ;) – MadProgrammer Oct 16 '13 at 19:45
  • @MadProgrammer That's why I developed ComA (Comment Assistant). ;) ..but this one does not quite yet make an answer, IMO. It is more a choice of 'paste this typical comment and/or vote to close as duplicate'. – Andrew Thompson Oct 16 '13 at 19:48

1 Answers1

1

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.

Caffe Latte
  • 1,693
  • 1
  • 14
  • 32
  • 1
    add Concurency in Swing, LayoutManager and Java Naming Conventions – mKorbel Oct 16 '13 at 19:25
  • not Thread#sleep() lock EDT until sleep ended, in OPs code is there loop dealyed by Thread.sleep, then up to 3seconds isn't JTextArea accesible for mouse and key events on user side – mKorbel Oct 16 '13 at 19:30
  • @mKorbel: I am not sure I understand your first comment, sorry :) About the second comment I don't quite agree with you because `Thread#sleep` causes GUI freeze event without loop, just try `Thread.sleep(10000)` and see what will happen :) Thanks. – Caffe Latte Oct 16 '13 at 19:38
  • 1
    You can use Thread#sleep in a GUI environment, just don't do it within the EDT, use a SwingWorker or Thread instead ;) – MadProgrammer Oct 16 '13 at 19:47
  • @MadProgrammer: Yes, that's in case not touching the GUI :) – Caffe Latte Oct 16 '13 at 19:50