Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.help > #2335 > unrolled thread

Need simple example of how to safely pass data from worker to EDT swing threads.

Started bykwiateks@gmail.com
First post2012-12-06 07:07 -0800
Last post2012-12-06 15:03 -0800
Articles 6 — 6 participants

Back to article view | Back to comp.lang.java.help


Contents

  Need simple example of how to safely pass data from worker to EDT swing threads. kwiateks@gmail.com - 2012-12-06 07:07 -0800
    Re: Need simple example of how to safely pass data from worker to EDT swing threads. Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-06 10:29 -0500
      Re: Need simple example of how to safely pass data from worker to EDT swing threads. kedward777@gmail.com - 2012-12-06 09:09 -0800
    Re: Need simple example of how to safely pass data from worker to EDT   swing threads. Nigel Wade <nmw@ion.le.ac.uk> - 2012-12-06 17:27 +0000
      Re: Need simple example of how to safely pass data from worker to EDT   swing threads. Lew <lewbloch@gmail.com> - 2012-12-06 11:10 -0800
    Re: Need simple example of how to safely pass data from worker to EDT swing threads. Roedy Green <see_website@mindprod.com.invalid> - 2012-12-06 15:03 -0800

#2335 — Need simple example of how to safely pass data from worker to EDT swing threads.

Fromkwiateks@gmail.com
Date2012-12-06 07:07 -0800
SubjectNeed simple example of how to safely pass data from worker to EDT swing threads.
Message-ID<118db2e0-86dc-4d6b-aabb-ba68ee8c2f53@googlegroups.com>
Hello Kinds Sirs,

I need a simple runnable example of a swing application that has a GUI with a jcombobox filled with a long list of name/value objects (eg 3000 employee names and numbers). There is also a worker process that reads in a record from a file/database, and then updates the gui jcombo box so that the employee item is "selected".

I was able to write something using  java map and employee objects to set the selected item in the jcombo box, but if I invoke setSelectedItem in the worker thread, I get odd results/delays.

See below snippets... how should the worker thread pass the employee object back to the gui for it to setSelectedItem?
....
empBuffer=  new Employee(id, lastName );
map.put(empBuffer.getId()+"",empBuffer ); 
model.addAll(map.values()); 
Collections.sort(model); 
myComboBox1.setModel(new javax.swing.DefaultComboBoxModel(model));
....
emp = (Employee) map.get(myData.getEmployeeNum()); 
myComboBox1.setSelectedItem(emp);

[toc] | [next] | [standalone]


#2336

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2012-12-06 10:29 -0500
Message-ID<k9qdk0$790$1@dont-email.me>
In reply to#2335
On 12/6/2012 10:07 AM, kwiateks@gmail.com wrote:
> Hello Kinds Sirs,
>
> I need a simple runnable example of a swing application that has a GUI with a jcombobox filled with a long list of name/value objects (eg 3000 employee names and numbers). There is also a worker process that reads in a record from a file/database, and then updates the gui jcombo box so that the employee item is "selected".
>
> I was able to write something using  java map and employee objects to set the selected item in the jcombo box, but if I invoke setSelectedItem in the worker thread, I get odd results/delays.
>
> See below snippets... how should the worker thread pass the employee object back to the gui for it to setSelectedItem?

     The snippet seems uninformative, so I'll ignore it and just
tackle the question.  All (or nearly all) manipulation of Swing
components must occur on the Event Dispatch Thread, so you can't
just have the worker thread call the methods of JComboBox.

     When the worker has a result (or intermediate result) and wants
to modify the GUI, one approach is to create a Runnable object that
knows the result and calls methods of JComboBox or whatever.  The
worker then uses the invokeLater() or invokeAndWait() methods
of the SwingUtilities class to tell Swing to execute the Runnable
on the EDT.  When the Runnable actually runs, it's on the EDT and
can safely manipulate the GUI.  Here's an example using a JLabel:

	// Instance variable somewhere in the GUI:
	JLabel label;

	// On the EDT while creating the GUI:
	label = new JLabel("Watch this space");
	someContainer.add(label);
	...

	// On a worker thread:
	final String text = slowAndComplicatedComputation();
	SwingUtilities.invokeLater(new Runnable() {
	    @Override
	    public void run() {
	        label.setText(text);
	    }
	});

     It would not be safe to call label.setText() directly from
the worker thread, but you're not doing that: Swing will execute
the Runnable on the EDT, where label.setText() can operate happily.

     The on-line Tutorial has a readable explanation of this and of
other ways to coordinate the activities of worker threads.  See
<http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html>

-- 
Eric Sosman
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#2337

Fromkedward777@gmail.com
Date2012-12-06 09:09 -0800
Message-ID<f47dd7a1-53b2-465e-a082-49adc790d3e6@googlegroups.com>
In reply to#2336
> 
>      When the worker has a result (or intermediate result) and wants
> 
> to modify the GUI, one approach is to create a Runnable object that
> 
> knows the result and calls methods of JComboBox or whatever.  The
> 
> worker then uses the invokeLater() or invokeAndWait() methods
> 
> of the SwingUtilities class to tell Swing to execute the Runnable
> 
> on the EDT.  When the Runnable actually runs, it's on the EDT and
> 
> can safely manipulate the GUI.  Here's an example using a JLabel:
> 
> 
> 
> 	// Instance variable somewhere in the GUI:
> 
> 	JLabel label;
> 
> 
> 
> 	// On the EDT while creating the GUI:
> 
> 	label = new JLabel("Watch this space");
> 
> 	someContainer.add(label);
> 
> 	...
> 
> 
> 
> 	// On a worker thread:
> 
> 	final String text = slowAndComplicatedComputation();
> 
> 	SwingUtilities.invokeLater(new Runnable() {
> 
> 	    @Override
> 
> 	    public void run() {
> 
> 	        label.setText(text);
> 
> 	    }
> 
> 	});
> 
> 
> 
>      It would not be safe to call label.setText() directly from
> 
> the worker thread, but you're not doing that: Swing will execute
> 
> the Runnable on the EDT, where label.setText() can operate happily.
> 
> 
> 
>      The on-line Tutorial has a readable explanation of this and of
> 
> other ways to coordinate the activities of worker threads.  See
> 
> <http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html>
> 

Thank you Eric! It worked perfectly. I am learning lots. Thanks for your patience!

[toc] | [prev] | [next] | [standalone]


#2338 — Re: Need simple example of how to safely pass data from worker to EDT swing threads.

FromNigel Wade <nmw@ion.le.ac.uk>
Date2012-12-06 17:27 +0000
SubjectRe: Need simple example of how to safely pass data from worker to EDT swing threads.
Message-ID<aic2rrF431U1@mid.individual.net>
In reply to#2335
On 06/12/12 15:07, kwiateks@gmail.com wrote:
> Hello Kinds Sirs,
>
> I need a simple runnable example of a swing application that has a GUI with a jcombobox filled with a long list of name/value objects (eg 3000 employee names and numbers). There is also a worker process that reads in a record from a file/database, and then updates the gui jcombo box so that the employee item is "selected".
>
> I was able to write something using  java map and employee objects to set the selected item in the jcombo box, but if I invoke setSelectedItem in the worker thread, I get odd results/delays.
>
> See below snippets... how should the worker thread pass the employee object back to the gui for it to setSelectedItem?
> ....
> empBuffer=  new Employee(id, lastName );
> map.put(empBuffer.getId()+"",empBuffer );
> model.addAll(map.values());
> Collections.sort(model);
> myComboBox1.setModel(new javax.swing.DefaultComboBoxModel(model));
> ....
> emp = (Employee) map.get(myData.getEmployeeNum());
> myComboBox1.setSelectedItem(emp);


Use SwingWorker and its publish()/process() and done() methods. Use 
publish() in the background thread to add each element to a list of 
objects to be processed by process(). In process() (which runs on the 
EDT) add the elements to the JComboBox model. In done() select the 
element you want in the JComboBox model.

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Although this may not solve the problem you were previously having, 
which is most likely caused by having too many objects in the JComboBox. 
You will still have the same number of objects in the JComboBox when 
SwingWorker.done() is completed.

When you open the JComboBox the EDT has to render all 3000 objects into 
the popup list.

[toc] | [prev] | [next] | [standalone]


#2340 — Re: Need simple example of how to safely pass data from worker to EDT swing threads.

FromLew <lewbloch@gmail.com>
Date2012-12-06 11:10 -0800
SubjectRe: Need simple example of how to safely pass data from worker to EDT swing threads.
Message-ID<848c30ed-2727-429e-a1ba-d85133a755ff@googlegroups.com>
In reply to#2338
Nigel Wade wrote:
> Although this may not solve the problem you were previously having, 
> which is most likely caused by having too many objects in the JComboBox. 
> You will still have the same number of objects in the JComboBox when 
> SwingWorker.done() is completed.
> 
> When you open the JComboBox the EDT has to render all 3000 objects into 
> the popup list.

Unless one needs all 3000 or 5000 entries on screen at the same time, it might 
not be necessary to fetch them all into the GUI widget at once. There is a technique
called "windowing" or "cursoring" (to verb some nouns). 

For such a small number of items via I/O as yours, you can pull them into an abstract 
model that feeds the GUI model, say a map or list or other collection. When the screen 
needs a view into that abstract model, let's say items k through k+99 inclusive, you 
feed those items into the GUI model along with some housekeeping variables to locate 
where the window is within the complete data structure. (Via the techniques others 
have already described to keep GUI on the EDT and non-GUI off the EDT.)

So the GUI only knows about a manageable number of entries at any one time. This will 
work if copying small amounts of data into the GUI model is faster than displaying 
large amounts at once in the GUI model.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#2344

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-12-06 15:03 -0800
Message-ID<e192c8dsk3d0tn0vqlkf1409qe5tf2rg79@4ax.com>
In reply to#2335
http://mindprod.com/jgloss/swingthreads.html
-- 
Roedy Green Canadian Mind Products http://mindprod.com
Students who hire or con others to do their homework are as foolish 
as couch potatoes who hire others to go to the gym for them. 

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.help


csiph-web