Re: Java multi-thread and model Observer
Sebastien Jourdain via vtkusers <[email protected]> Fri, 22 Feb 2019 11:08:33 -0700
| Newsgroups | gmane.comp.lib.vtk.user |
|---|---|
| Message-ID | <CABObKxe4Kk8cTM5xFYYLnwE5RYRgW_aOW2ez3nbWv6__aW3x7g@mail.gmail.com> |
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 <[email protected]> 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 > _______________________________________________ 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