0

I want to display program flow to the user in form of comments in a JTextField. Only the last message ("complete") is shown. How can I make each message appear when I call setText()?

private class CalculateButtonHandler implements ActionListener {
    public void actionPerformed(ActionEvent e) {            
        String keyValue = keywordTF.getText();
        currentTF.setText("calling 1");
        methodCall1();
        currentTF.setText("calling 2");
        methodCall2();
        currentTF.setText("calling 3");
        methodCall3();
        currentTF.setText("complete");
    }
}
thejartender
  • 9,339
  • 6
  • 34
  • 51
ArpitM
  • 3
  • 1

2 Answers2

2

The reason is that the EDT has no time to repaint the text field since your methodCall* method is running on the EDT.

If you want to show progress of a heavy task you should perform the heavy work on a worker thread and update the UI on the EDT. Typically this is achieved by using a SwingWorker or using SwingUtilities#invokeLater from the worker thread.

The 'Concurrency in Swing' tutorial contains more information

Robin
  • 36,233
  • 5
  • 47
  • 99
  • The task is not heavy at all. It is only broken into smaller methods. I just want to display "This method now" sort of thing in the Textfield. Is there any simpler alternative? I don't want to introduce threads. Thanks!! – ArpitM May 15 '12 at 16:19
  • 1
    @user396501 If those are really small, even if you would split it the updates of the text will happen so quickly you would never see it. You could just append text iso replace as suggested by Ben Lawry. And just to be clear, with heavy I mean everything that lasts more then 100ms and not only computations that take minutes and more to complete – Robin May 15 '12 at 16:26
  • The task IS heavy in that it's performing computation within the EDT - this means that the UI cannot update itself because it's busy performing the work of your method calls. When your method calls complete, the UI will update itself, but by then, it's too late. – CodeBlind May 15 '12 at 16:30
  • Yes I think I get it. Thanks a lot for your help. Cheers! – ArpitM May 15 '12 at 16:53
  • With the help of responses from Ben Lawry and Robin, I was able to do the solution. This stackflow link also helped [link](http://stackoverflow.com/questions/782265/how-do-i-use-swingworker-in-java) – ArpitM May 15 '12 at 20:26
0

Try:

String keyValue = keywordTF.getText();

currentTF.setText("calling 1");
methodCall1();
currentTF.setText(currentTF.getText()+"\ncalling 2");
methodCall2();
currentTF.setText(currentTF.getText()+"\ncalling 3");
methodCall3();
currentTF.setText(currentTF.getText()+"\ncomplete");

Not terribly efficient, but it will get the job done.

Also

It'd be a lot better to use a JTextArea. JTextField is meant primarily for displaying one line of text, but it sounds like you want to keep more of a log... perhaps? If you still want to use a JTextField, then replace the "\n" characters in the calls to setText() with some other appropriate delimiter.

CodeBlind
  • 4,519
  • 1
  • 24
  • 36
  • I changed it to JTextArea. Now all the statements "call 1" "call 2" etc are coming together at the last ie only at the termination of the java application. All messed up! any help? Thanks!! – ArpitM May 15 '12 at 16:21
  • Ah hah, that makes sense now - when I originally posted my answer, your code didn't show that you had made the call inside the `actionPerformed(ActionEvent ae)` implementation. @Robin is correct to say that the reason you aren't seeing any updates until the method calls are finished is because you are performing computation in the Event Dispatch Thread. You need to run those methods in another thread if you want to update the UI while those methods are running. – CodeBlind May 15 '12 at 16:28