0

I have a simple JAVA program with gui that just increments int variable and displays its value in JLabel. I create new thread for proper(thread-safe) updating JLabel by calling inside it EventQueue.invokeLater() with Runnable class which run method simply does

EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            label.setText("" + number);
        }
    });

When i run program, as expected label's number starts to grow rapidly from 1 to about 5000 but then it starts to slow down and i'm starting to see such label's updates like 100255, 173735, 235678 and big pauses between them with blocked GUI. But when i compile without using EventQueue.invokeLater(), just calling directly label.setText("" + number); everything works fine and perfect and i can see how each number of my label is changing extremely fast. But of course i realize in that case my method isn't thread-safe.

What's the problem? It seems to me that EventQueue works slow or something.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Artem Novikov
  • 4,087
  • 1
  • 27
  • 33

1 Answers1

3

Probably, the event queue is being choked up. You may want to look at coalescing the events to remove redundant entries when you are queuing event faster than they can be dequeued and actioned.

Every time an event is added to the queue, the existing events are queried to see if they merge the new event with themselves. As the queue backs up, more and more events have to be so queried, and the system gets progressively further behind. This is useful for mouse events, but in a simple (and artificial) case like this it can be detrimental.

Having said that, I vaguely recall that the GUI code is optimized to not attempt coalescing events that don't override the appropriate method, so your problem may be just a simple backlog.

Instead of calling setText directly, you could create a custom event for setting text on a component, implement coalescing for it and use that instead so that at any given time only the most recent text is pending. If you do this and you want to set the text based on what was previously set it's better to retain the value and always set the GUI widget from that rather than recalling the GUI widget's current value with getText. Otherwise merging is much more difficult.

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
  • Thanks for answer! But what do you mean by coalescing the events? Are events label.setText("hello") and label.setText("goodbye") considered to be the same? And i still dont get why at the begining all seems to be alright but then it get worse, though all process goes very like at the beginning. Just increment, queue, updating label. – Artem Novikov Sep 25 '13 at 19:42
  • Could EventQueue work slowly if it contains too many items? And are there any ways to check whether EventQueue contains any items? – Artem Novikov Sep 25 '13 at 19:44
  • Coalescing setText events is as simple as retaining the most recent for a given component (IOW, a setText always replaces a pending setText for the same component), since the text entirely replaces what was there before. – Lawrence Dol Sep 25 '13 at 19:48
  • Yes, any queue can work slowly when it reaches some arbitrary threshold, depending on how the queue operates and is being used. For example, adding an object to the start of an array-based queue with 1 B entries will take much longer than adding to the end because the array elements must be shifted. Likewise, if each add involves searching existing entries, then adds with an empty queue will be faster than adds when there is 1 B items already on the queue. You get the idea. – Lawrence Dol Sep 25 '13 at 19:51
  • It's entirely likely that the GUI event queue is designed to be optimized for having rapid throughput of a relatively small number of events pending at any one time. – Lawrence Dol Sep 25 '13 at 19:53
  • Yes, i get you. But what if we have some queue like this: 1) number.setText("ab"); 2) result.setText(number.getText() + "cd"); 3) number.setText("ef"). Will any of these merged? As i understand you the first and third one will be merged? – Artem Novikov Sep 25 '13 at 19:59