[vtkusers] Java multi-thread and model Observer
Jean-Max Redonnet
jmax.red at gmail.com
Thu Feb 21 04:19:17 EST 2019
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20190221/8b50e039/attachment.html>
More information about the vtkusers
mailing list