[vtkusers] Java multi-thread and model Observer

Sebastien Jourdain sebastien.jourdain at kitware.com
Mon Mar 4 11:15:34 EST 2019


You can do it via an invokeLater or anything that will schedule the
execution in the EDT.

On Mon, Mar 4, 2019 at 7:02 AM Jean-Max Redonnet <jmax.red at gmail.com> wrote:

> Hi Sébastien,
>
> Thanks for your response.
>
> Actually, I don't understand why I still have the use of a Timer, neither.
> But the point is that if I put the panel3d.resetCamera() command outside
> the Timer, it doesn't work :-(.
>
> Hope I can figure out why soon and any hint on this purpose will be really
> appreciated.
>
> Anyway thanks again for your time.
>
> jMax
>
>
>
>
> Le ven. 22 févr. 2019 à 19:09, Sebastien Jourdain <
> sebastien.jourdain at kitware.com> a écrit :
>
>> 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 at 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
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20190304/dbc38d74/attachment.html>


More information about the vtkusers mailing list