[prev in list] [next in list] [prev in thread] [next in thread]
List: vtkusers
Subject: Re: [vtkusers] Java multi-thread and model Observer
From: Sebastien Jourdain via vtkusers <vtkusers () vtk ! org>
Date: 2019-02-22 18:08:33
Message-ID: CABObKxe4Kk8cTM5xFYYLnwE5RYRgW_aOW2ez3nbWv6__aW3x7g () mail ! gmail ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
Hi Jean-Max,
I'm not sure to follow all the details of your implementation or why you
still have the use of a Timer.
The only things that you need to worry about is that any rendering action
(addActor/removeActor, update when actor connected, render) MUST BE in the
EDT.
HTH,
Seb
On Thu, Feb 21, 2019 at 2:19 AM Jean-Max Redonnet <jmax.red@gmail.com>
wrote:
> Hello everyone !
>
> I'm using vtk throught its java wrapper and I'm setting up a versatile
> viewer that can display an existing model and update display when this
> model is updated (and it will be continously updated).
>
> My Model is built around few classes: VtkObject that is the ancestor of
> many other classes like VtkSurface, VtkCurve, etc... and VtkModel that
> basically contains a list of VtkObjects and maintain Listeners. All these
> classes are of my own (please note uppercase "V" on VtkObject)
>
>
> public class VtkObject{
> protected final PropertyChangeSupport pcs = new
> PropertyChangeSupport(this);
> protected List<vtkActor> actors = new ArrayList<vtkActor>();
> ...
> }
>
> public class VtkSurface extends VtkObject {
> private vtkActor surfActor;
> ...
> }
>
> public class VtkModel implements PropertyChangeListener{
> protected List<VtkObject> objects;
> protected PropertyChangeSupport support;
> ...
> }
>
> For the viewer itself I wrote a VtkPanel that is mostly inspired by the
> example provided by SĂ©bastien Jourdain (
> https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java
> )
>
> I just make this panel model-aware implementing PropertyChangeListener:
>
> @Override
> public void propertyChange(PropertyChangeEvent evt) {
> if (evt.getPropertyName() == "AddedObject") {
> System.out.println("Added Object");
> VtkObject o = (VtkObject) evt.getNewValue();
> if(o.getActors().size()>0)
> exec.submit(new PipelineBuilder(o));
> }
> if (evt.getPropertyName() == "UpdatedObject") {
> System.out.println("Updated Object");
> VtkObject o = (VtkObject) evt.getNewValue();
> if(o.getActors().size()>0)
> exec.submit(new PipelineBuilder(o));
> }
> }
>
> and slithly modify PipelineBuilder to make it able to manage VtkObjects
> that may contain several vtkActors
>
> public class PipelineBuilder implements Callable<vtkActor> {
> private int counter;
> private List<vtkActor> actors;
>
> public PipelineBuilder(VtkObject o) {
> actors = o.getActors();
> counter = 0;
> }
>
> @Override
> public vtkActor call() throws Exception {
> counter++;
> if (counter < actors.size() + 1)
> return actors.get(counter - 1);
> return null;
> }
> }
>
> Also, workers are setup to continously search for new actors:
>
> private void setupWorkers() {
> // Add actor thread: Consume the working queue and add the actor
> into
> // the render inside the EDT thread
> final AddActorRunnable adderRunnable = new AddActorRunnable();
> adderRunnable.setRenderer(panel3d);
> new Thread() {
> public void run() {
> while (true) {
> try {
> adderRunnable.setActor(exec.take().get());
> SwingUtilities.invokeAndWait(adderRunnable);
> panel3d.repaint();
> } catch (InterruptedException e) {
> return;
> } catch (ExecutionException e) {
> e.printStackTrace();
> } catch (InvocationTargetException e) {
> e.printStackTrace();
> }
> }
> };
> }.start();
> }
>
>
> Here is the test class I use:
>
> public class TestVtkPanel {
> public VtkModel model;
>
> public TestVtkPanel() {
> SwingUtilities.invokeLater(new Runnable() {
> public void run() {
> model = getModel();
> VtkPanel panel = new VtkPanel();
> model.addPropertyChangeListener(panel);
>
> JButton exitBtn = new JButton("Quitter");
> exitBtn.addActionListener(new ActionListener() {
>
> public void actionPerformed(ActionEvent e) {
> System.exit(0);
> }
> });
> JFrame f = new JFrame("Vtk Viewer");
> f.getContentPane().setLayout(new BorderLayout());
> f.getContentPane().add(panel, BorderLayout.CENTER);
> f.getContentPane().add(exitBtn, BorderLayout.SOUTH);
>
> f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> f.setSize(800, 600);
> f.setVisible(true);
> f.validate();
>
> panel.startWorking(model);
>
> new Thread(new Runnable() {
> public void run() {
> updateModel();
> }
> }).start();
>
> }
> });
>
> }
>
>
> ...
> }
>
>
>
> All this stuff works fine, but few questions remains.
>
> Is this way to do thing is the best for what I'm trying to achieve ? If a
> vtk guru can give a look to my code, it would be gratefully appreciated.
> Furthermore inside the VtkPanel constructor I tried to put the vtkPanel
> panel3d outside of the Timer but that do not work.
>
> new Timer(1000, new ActionListener() {
>
> public void actionPerformed(ActionEvent e) {
> if (nbSeconds++ < 1) {
> panel3d.resetCamera();
> }
> // Run GC in local thread (EDT)
> ...
> }
>
> I can't figure out why. Any hint on this point may help me to understand
> multithreading.
>
> Thanks for your help.
>
> jMax
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Search the list archives at: http://markmail.org/search/?q=vtkusers
>
> Follow this link to subscribe/unsubscribe:
> https://vtk.org/mailman/listinfo/vtkusers
>
[Attachment #5 (text/html)]
<div dir="ltr">Hi Jean-Max,<div><br></div><div>I'm not sure to follow all the \
details of your implementation or why you still have the use of a \
Timer.</div><div>The only things that you need to worry about is that any rendering \
action (addActor/removeActor, update when actor connected, render) MUST BE in the \
EDT.</div><div><br></div><div>HTH,</div><div><br></div><div>Seb</div></div><br><div \
class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 21, 2019 at 2:19 AM \
Jean-Max Redonnet <<a href="mailto:jmax.red@gmail.com">jmax.red@gmail.com</a>> \
wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div \
dir="ltr">Hello everyone !<br><br>I'm using vtk throught its java wrapper and \
I'm setting up a versatile viewer that can display an existing model and update \
display when this model is updated (and it will be continously updated).<br><br>My \
Model is built around few classes: VtkObject that is the ancestor of many other \
classes like VtkSurface, VtkCurve, etc... and VtkModel that basically contains a list \
of VtkObjects and maintain Listeners. All these classes are of my own (please note \
uppercase "V" on VtkObject)<br><br><br>public class VtkObject{<br> \
protected final PropertyChangeSupport pcs = new PropertyChangeSupport(this);<br> \
protected List<vtkActor> actors = new ArrayList<vtkActor>();<br> \
...<br>}<br><br>public class VtkSurface extends VtkObject {<br> private vtkActor \
surfActor;<br> ...<br>}<br><br>public class VtkModel implements \
PropertyChangeListener{<br> protected List<VtkObject> objects;<br> \
protected PropertyChangeSupport support;<br> ...<br>}<br><br>For the viewer itself \
I wrote a VtkPanel that is mostly inspired by the example provided by Sébastien \
Jourdain (<a href="https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java" \
target="_blank">https://github.com/Kitware/VTK/blob/master/Wrapping/Java/vtk/sample/Demo.java</a>)<br><br>I \
just make this panel model-aware implementing PropertyChangeListener:<br><br> \
@Override<br> public void propertyChange(PropertyChangeEvent evt) {<br> if \
(evt.getPropertyName() == "AddedObject") {<br> \
System.out.println("Added Object");<br> VtkObject o = \
(VtkObject) evt.getNewValue();<br> if(o.getActors().size()>0)<br> \
exec.submit(new PipelineBuilder(o));<br> }<br> if \
(evt.getPropertyName() == "UpdatedObject") {<br> \
System.out.println("Updated Object");<br> VtkObject o = \
(VtkObject) evt.getNewValue();<br> if(o.getActors().size()>0)<br> \
exec.submit(new PipelineBuilder(o));<br> }<br> }<br><br>and slithly modify \
PipelineBuilder to make it able to manage VtkObjects that may contain several \
vtkActors<br><br> public class PipelineBuilder implements Callable<vtkActor> \
{<br> private int counter;<br> private List<vtkActor> \
actors;<br><br> public PipelineBuilder(VtkObject o) {<br> actors = \
o.getActors();<br> counter = 0;<br> }<br><br> @Override<br> \
public vtkActor call() throws Exception {<br> counter++;<br> if \
(counter < actors.size() + 1)<br> return actors.get(counter - \
1);<br> return null;<br> }<br> }<br><br>Also, workers are setup \
to continously search for new actors:<br><br> private void setupWorkers() {<br> \
// Add actor thread: Consume the working queue and add the actor into<br> // \
the render inside the EDT thread<br> final AddActorRunnable adderRunnable = \
new AddActorRunnable();<br> adderRunnable.setRenderer(panel3d);<br> new \
Thread() {<br> public void run() {<br> while (true) {<br> \
try {<br> adderRunnable.setActor(exec.take().get());<br> \
SwingUtilities.invokeAndWait(adderRunnable);<br> \
panel3d.repaint();<br> } catch (InterruptedException e) {<br> \
return;<br> } catch (ExecutionException e) {<br> \
e.printStackTrace();<br> } catch (InvocationTargetException e) \
{<br> e.printStackTrace();<br> }<br> \
}<br> };<br> }.start();<br> }<br><br><br>Here is the test class \
I use:<br><br>public class TestVtkPanel {<br> public VtkModel model;<br><br> \
public TestVtkPanel() {<br> SwingUtilities.invokeLater(new Runnable() {<br> \
public void run() {<br> model = getModel();<br> \
VtkPanel panel = new VtkPanel();<br> \
model.addPropertyChangeListener(panel);<br><br> JButton exitBtn = new \
JButton("Quitter");<br> exitBtn.addActionListener(new \
ActionListener() {<br><br> public void actionPerformed(ActionEvent \
e) {<br> System.exit(0);<br> }<br> \
});<br> JFrame f = new JFrame("Vtk Viewer");<br> \
f.getContentPane().setLayout(new BorderLayout());<br> \
f.getContentPane().add(panel, BorderLayout.CENTER);<br> \
f.getContentPane().add(exitBtn, BorderLayout.SOUTH);<br><br> \
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br> f.setSize(800, \
600);<br> f.setVisible(true);<br> f.validate();<br><br> \
panel.startWorking(model);<br><br> new Thread(new Runnable() {<br> \
public void run() {<br> updateModel();<br> \
}<br> }).start();<br><br> }<br> });<br><br> } \
<br> <br><br> ...<br> }<br> <br> <br> <br>All this stuff works fine, \
but few questions remains.<br><br>Is this way to do thing is the best for what \
I'm trying to achieve ? If a vtk guru can give a look to my code, it would be \
gratefully appreciated. Furthermore inside the VtkPanel constructor I tried to put \
the vtkPanel panel3d outside of the Timer but that do not work.<br><br> new \
Timer(1000, new ActionListener() {<br><br> public void \
actionPerformed(ActionEvent e) {<br> if (nbSeconds++ < 1) {<br> \
panel3d.resetCamera();<br> }<br> // Run GC in local \
thread (EDT)<br> ...<br> }<br> <br>I can't figure out why. Any \
hint on this point may help me to understand multithreading.<br><br>Thanks for your \
help.<br><br></div><div>jMax</div></div> \
_______________________________________________<br> Powered by <a \
href="http://www.kitware.com" rel="noreferrer" \
target="_blank">www.kitware.com</a><br> <br>
Visit other Kitware open-source projects at <a \
href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" \
target="_blank">http://www.kitware.com/opensource/opensource.html</a><br> <br>
Please keep messages on-topic and check the VTK FAQ at: <a \
href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer" \
target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br> <br>
Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" \
rel="noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br> <br>
Follow this link to subscribe/unsubscribe:<br>
<a href="https://vtk.org/mailman/listinfo/vtkusers" rel="noreferrer" \
target="_blank">https://vtk.org/mailman/listinfo/vtkusers</a><br> </blockquote></div>
_______________________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
Search the list archives at: http://markmail.org/search/?q=vtkusers
Follow this link to subscribe/unsubscribe:
https://vtk.org/mailman/listinfo/vtkusers
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic