[vtkusers] Java multi-thread and model Observer
Sebastien Jourdain
sebastien.jourdain at kitware.com
Fri Feb 22 13:08:33 EST 2019
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/20190222/4a5c5ec6/attachment.html>
More information about the vtkusers
mailing list