]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
VTK.Rendering plug-in + win64 fragment 97/2897/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 13 May 2019 12:06:02 +0000 (15:06 +0300)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 13 May 2019 12:06:02 +0000 (15:06 +0300)
VTK.Rendering allows SWT-based VTK view, without AWT tread.

gitlab #2

Change-Id: Ida8a60eb56c012ea96be874888d0e72559e76204

36 files changed:
vtk.rendering.win32.win32.x86_64/.classpath [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/.project [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/META-INF/MANIFEST.MF [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/README.txt [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/build.properties [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/gluegen-rt.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/joal.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/jocl.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/jogl_cg.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/jogl_desktop.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/jogl_mobile.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/nativewindow_awt.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/nativewindow_win32.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/newt.dll [new file with mode: 0644]
vtk.rendering.win32.win32.x86_64/soft_oal.dll [new file with mode: 0644]
vtk.rendering/.classpath [new file with mode: 0644]
vtk.rendering/.gitignore [new file with mode: 0644]
vtk.rendering/.project [new file with mode: 0644]
vtk.rendering/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
vtk.rendering/META-INF/MANIFEST.MF [new file with mode: 0644]
vtk.rendering/build.properties [new file with mode: 0644]
vtk.rendering/lib/gluegen-rt.jar [new file with mode: 0644]
vtk.rendering/lib/jogl-all.jar [new file with mode: 0644]
vtk.rendering/pom.xml [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/awt/vtkAwtComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/awt/vtkInternalAwtComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/awt/vtkPanelComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/swt/vtkInternalSwtComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/swt/vtkSwtComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/swt/vtkSwtInteractorForwarderDecorator.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/vtkAbstractComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/vtkAbstractEventInterceptor.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/vtkComponent.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/vtkEventInterceptor.java [new file with mode: 0644]
vtk.rendering/src/vtk/rendering/vtkInteractorForwarder.java [new file with mode: 0644]

diff --git a/vtk.rendering.win32.win32.x86_64/.classpath b/vtk.rendering.win32.win32.x86_64/.classpath
new file mode 100644 (file)
index 0000000..eca7bdb
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/vtk.rendering.win32.win32.x86_64/.project b/vtk.rendering.win32.win32.x86_64/.project
new file mode 100644 (file)
index 0000000..5b95169
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>vtk.rendering.win32.win32.x86_64</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/vtk.rendering.win32.win32.x86_64/.settings/org.eclipse.jdt.core.prefs b/vtk.rendering.win32.win32.x86_64/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..0c68a61
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/vtk.rendering.win32.win32.x86_64/META-INF/MANIFEST.MF b/vtk.rendering.win32.win32.x86_64/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..309c36e
--- /dev/null
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: VTK Rendering X86_64
+Bundle-SymbolicName: vtk.rendering.win32.win32.x86_64
+Bundle-Version: 8.2.0.qualifier
+Fragment-Host: vtk.rendering;bundle-version="8.2.0"
+Automatic-Module-Name: vtk.rendering.win32.win32.x86_64
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Eclipse-PlatformFilter: (& (osgi.ws=win32) (osgi.os=win32) (osgi.arch=x86_64))
diff --git a/vtk.rendering.win32.win32.x86_64/README.txt b/vtk.rendering.win32.win32.x86_64/README.txt
new file mode 100644 (file)
index 0000000..47572ee
--- /dev/null
@@ -0,0 +1 @@
+This folder contains deprecated plain native libraries for platform windows-amd64, please use the native JAR files in the jar folder.
diff --git a/vtk.rendering.win32.win32.x86_64/build.properties b/vtk.rendering.win32.win32.x86_64/build.properties
new file mode 100644 (file)
index 0000000..34d2e4d
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/vtk.rendering.win32.win32.x86_64/gluegen-rt.dll b/vtk.rendering.win32.win32.x86_64/gluegen-rt.dll
new file mode 100644 (file)
index 0000000..d02d2cc
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/gluegen-rt.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/joal.dll b/vtk.rendering.win32.win32.x86_64/joal.dll
new file mode 100644 (file)
index 0000000..f07d1a4
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/joal.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/jocl.dll b/vtk.rendering.win32.win32.x86_64/jocl.dll
new file mode 100644 (file)
index 0000000..1f6121a
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/jocl.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/jogl_cg.dll b/vtk.rendering.win32.win32.x86_64/jogl_cg.dll
new file mode 100644 (file)
index 0000000..a4952a4
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/jogl_cg.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/jogl_desktop.dll b/vtk.rendering.win32.win32.x86_64/jogl_desktop.dll
new file mode 100644 (file)
index 0000000..191dc44
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/jogl_desktop.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/jogl_mobile.dll b/vtk.rendering.win32.win32.x86_64/jogl_mobile.dll
new file mode 100644 (file)
index 0000000..9213fd3
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/jogl_mobile.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/nativewindow_awt.dll b/vtk.rendering.win32.win32.x86_64/nativewindow_awt.dll
new file mode 100644 (file)
index 0000000..b73f034
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/nativewindow_awt.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/nativewindow_win32.dll b/vtk.rendering.win32.win32.x86_64/nativewindow_win32.dll
new file mode 100644 (file)
index 0000000..354f22f
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/nativewindow_win32.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/newt.dll b/vtk.rendering.win32.win32.x86_64/newt.dll
new file mode 100644 (file)
index 0000000..cdf227c
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/newt.dll differ
diff --git a/vtk.rendering.win32.win32.x86_64/soft_oal.dll b/vtk.rendering.win32.win32.x86_64/soft_oal.dll
new file mode 100644 (file)
index 0000000..9397425
Binary files /dev/null and b/vtk.rendering.win32.win32.x86_64/soft_oal.dll differ
diff --git a/vtk.rendering/.classpath b/vtk.rendering/.classpath
new file mode 100644 (file)
index 0000000..b9bcee7
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry exported="true" kind="lib" path="lib/gluegen-rt.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/jogl-all.jar"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/vtk.rendering/.gitignore b/vtk.rendering/.gitignore
new file mode 100644 (file)
index 0000000..ae3c172
--- /dev/null
@@ -0,0 +1 @@
+/bin/
diff --git a/vtk.rendering/.project b/vtk.rendering/.project
new file mode 100644 (file)
index 0000000..c698cc6
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>vtk.rendering</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/vtk.rendering/.settings/org.eclipse.jdt.core.prefs b/vtk.rendering/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..0c68a61
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/vtk.rendering/META-INF/MANIFEST.MF b/vtk.rendering/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..6ee0bfe
--- /dev/null
@@ -0,0 +1,140 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: VTK Rendering
+Bundle-SymbolicName: vtk.rendering
+Bundle-Version: 8.2.0.qualifier
+Automatic-Module-Name: vtk.rendering
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.swt;bundle-version="3.106.0",
+ vtk;bundle-version="8.2.0"
+Bundle-ClassPath: lib/jogl-all.jar,
+ .,
+ lib/gluegen-rt.jar
+Export-Package: com.jogamp.common,
+ com.jogamp.common.jvm,
+ com.jogamp.common.net,
+ com.jogamp.common.net.asset,
+ com.jogamp.common.nio,
+ com.jogamp.common.os,
+ com.jogamp.common.type,
+ com.jogamp.common.util,
+ com.jogamp.common.util.awt,
+ com.jogamp.common.util.cache,
+ com.jogamp.common.util.locks,
+ com.jogamp.gluegen.runtime,
+ com.jogamp.gluegen.runtime.opengl,
+ com.jogamp.graph.curve,
+ com.jogamp.graph.curve.opengl,
+ com.jogamp.graph.curve.tess,
+ com.jogamp.graph.font,
+ com.jogamp.graph.geom,
+ com.jogamp.nativewindow,
+ com.jogamp.nativewindow.awt,
+ com.jogamp.nativewindow.egl,
+ com.jogamp.nativewindow.swt,
+ com.jogamp.nativewindow.util,
+ com.jogamp.nativewindow.windows,
+ com.jogamp.nativewindow.x11,
+ com.jogamp.newt,
+ com.jogamp.newt.awt,
+ com.jogamp.newt.awt.applet,
+ com.jogamp.newt.event,
+ com.jogamp.newt.event.awt,
+ com.jogamp.newt.opengl,
+ com.jogamp.newt.opengl.util,
+ com.jogamp.newt.opengl.util.stereo,
+ com.jogamp.newt.swt,
+ com.jogamp.newt.util,
+ com.jogamp.newt.util.applet,
+ com.jogamp.opengl,
+ com.jogamp.opengl.awt,
+ com.jogamp.opengl.egl,
+ com.jogamp.opengl.fixedfunc,
+ com.jogamp.opengl.glu,
+ com.jogamp.opengl.glu.gl2,
+ com.jogamp.opengl.glu.gl2es1,
+ com.jogamp.opengl.math,
+ com.jogamp.opengl.math.geom,
+ com.jogamp.opengl.swt,
+ com.jogamp.opengl.util,
+ com.jogamp.opengl.util.av,
+ com.jogamp.opengl.util.awt,
+ com.jogamp.opengl.util.gl2,
+ com.jogamp.opengl.util.glsl,
+ com.jogamp.opengl.util.glsl.fixedfunc,
+ com.jogamp.opengl.util.glsl.sdk,
+ com.jogamp.opengl.util.packrect,
+ com.jogamp.opengl.util.stereo,
+ com.jogamp.opengl.util.stereo.generic,
+ com.jogamp.opengl.util.texture,
+ com.jogamp.opengl.util.texture.awt,
+ com.jogamp.opengl.util.texture.spi,
+ com.jogamp.opengl.util.texture.spi.awt,
+ jogamp.common,
+ jogamp.common.jvm,
+ jogamp.common.os,
+ jogamp.common.os.elf,
+ jogamp.common.util,
+ jogamp.common.util.locks,
+ jogamp.graph.curve.opengl,
+ jogamp.graph.curve.opengl.shader,
+ jogamp.graph.curve.tess,
+ jogamp.graph.font,
+ jogamp.graph.font.typecast,
+ jogamp.graph.font.typecast.ot,
+ jogamp.graph.font.typecast.ot.mac,
+ jogamp.graph.font.typecast.ot.table,
+ jogamp.graph.font.typecast.t2,
+ jogamp.graph.font.typecast.tt.engine,
+ jogamp.graph.geom.plane,
+ jogamp.nativewindow,
+ jogamp.nativewindow.awt,
+ jogamp.nativewindow.jawt,
+ jogamp.nativewindow.jawt.macosx,
+ jogamp.nativewindow.jawt.windows,
+ jogamp.nativewindow.jawt.x11,
+ jogamp.nativewindow.windows,
+ jogamp.nativewindow.x11,
+ jogamp.nativewindow.x11.awt,
+ jogamp.newt,
+ jogamp.newt.awt,
+ jogamp.newt.awt.event,
+ jogamp.newt.driver,
+ jogamp.newt.driver.awt,
+ jogamp.newt.driver.linux,
+ jogamp.newt.driver.opengl,
+ jogamp.newt.driver.windows,
+ jogamp.newt.driver.x11,
+ jogamp.newt.event,
+ jogamp.newt.swt,
+ jogamp.newt.swt.event,
+ jogamp.opengl,
+ jogamp.opengl.awt,
+ jogamp.opengl.egl,
+ jogamp.opengl.es1,
+ jogamp.opengl.es3,
+ jogamp.opengl.gl2,
+ jogamp.opengl.gl4,
+ jogamp.opengl.glu,
+ jogamp.opengl.glu.error,
+ jogamp.opengl.glu.gl2.nurbs,
+ jogamp.opengl.glu.mipmap,
+ jogamp.opengl.glu.nurbs,
+ jogamp.opengl.glu.registry,
+ jogamp.opengl.glu.tessellator,
+ jogamp.opengl.openal.av,
+ jogamp.opengl.util,
+ jogamp.opengl.util.av,
+ jogamp.opengl.util.av.impl,
+ jogamp.opengl.util.glsl,
+ jogamp.opengl.util.glsl.fixedfunc,
+ jogamp.opengl.util.jpeg,
+ jogamp.opengl.util.pngj,
+ jogamp.opengl.util.pngj.chunks,
+ jogamp.opengl.util.stereo,
+ jogamp.opengl.windows.wgl,
+ jogamp.opengl.windows.wgl.awt,
+ jogamp.opengl.x11.glx,
+ vtk.rendering,
+ vtk.rendering.awt,
+ vtk.rendering.swt
diff --git a/vtk.rendering/build.properties b/vtk.rendering/build.properties
new file mode 100644 (file)
index 0000000..ca7d753
--- /dev/null
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               lib/jogl-all.jar,\
+               lib/gluegen-rt.jar
diff --git a/vtk.rendering/lib/gluegen-rt.jar b/vtk.rendering/lib/gluegen-rt.jar
new file mode 100644 (file)
index 0000000..742fdb2
Binary files /dev/null and b/vtk.rendering/lib/gluegen-rt.jar differ
diff --git a/vtk.rendering/lib/jogl-all.jar b/vtk.rendering/lib/jogl-all.jar
new file mode 100644 (file)
index 0000000..f73174f
Binary files /dev/null and b/vtk.rendering/lib/jogl-all.jar differ
diff --git a/vtk.rendering/pom.xml b/vtk.rendering/pom.xml
new file mode 100644 (file)
index 0000000..6dee25c
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+       xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.simantics.g3d</groupId>
+               <artifactId>org.simantics.g3d.root</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>vtk</artifactId>
+       <packaging>eclipse-plugin</packaging>
+       <version>8.2.0-SNAPSHOT</version>
+
+</project>
\ No newline at end of file
diff --git a/vtk.rendering/src/vtk/rendering/awt/vtkAwtComponent.java b/vtk.rendering/src/vtk/rendering/awt/vtkAwtComponent.java
new file mode 100644 (file)
index 0000000..974a561
--- /dev/null
@@ -0,0 +1,127 @@
+package vtk.rendering.awt;
+
+import java.awt.Canvas;
+import java.awt.Dimension;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+
+import vtk.vtkObject;
+import vtk.vtkRenderWindow;
+import vtk.rendering.vtkAbstractComponent;
+
+/**
+ * Provide AWT based vtk rendering component
+ *
+ * @authors Sebastien Jourdain - sebastien.jourdain@kitware.com
+ *          Joachim Pouderoux - joachim.pouderoux@kitware.com
+ */
+public class vtkAwtComponent extends vtkAbstractComponent<Canvas> {
+  protected vtkInternalAwtComponent uiComponent;
+  protected boolean isWindowCreated;
+  protected Runnable onWindowCreatedCallback;
+
+  public vtkAwtComponent() {
+    this(new vtkRenderWindow());
+  }
+
+  public vtkAwtComponent(vtkRenderWindow renderWindowToUse) {
+    super(renderWindowToUse);
+    this.isWindowCreated = false;
+    this.uiComponent = new vtkInternalAwtComponent(this);
+    this.uiComponent.addComponentListener(new ComponentAdapter() {
+
+      public void componentResized(ComponentEvent arg0) {
+        Dimension size = vtkAwtComponent.this.uiComponent.getSize();
+        vtkAwtComponent.this.setSize(size.width, size.height);
+      }
+    });
+  }
+
+  public void Render() {
+    // Make sure we can render
+    if (inRenderCall || renderer == null || renderWindow == null) {
+      return;
+    }
+
+    // Try to render
+    try {
+      lock.lockInterruptibly();
+      inRenderCall = true;
+
+      // Initialize the window only once
+      if (!isWindowCreated) {
+        uiComponent.RenderCreate(renderWindow);
+        setSize(uiComponent.getWidth(), uiComponent.getHeight());
+        isWindowCreated = true;
+      }
+
+      // Trigger the real render
+      renderWindow.Render();
+
+      // Execute callback if need be
+      if(this.onWindowCreatedCallback != null) {
+        this.onWindowCreatedCallback.run();
+        this.onWindowCreatedCallback = null;
+      }
+    } catch (InterruptedException e) {
+      // Nothing that we can do except skipping execution
+    } finally {
+      lock.unlock();
+      inRenderCall = false;
+    }
+  }
+
+  public Canvas getComponent() {
+    return this.uiComponent;
+  }
+
+  public void Delete() {
+    this.lock.lock();
+
+    // We prevent any further rendering
+    inRenderCall = true;
+
+    if (this.uiComponent.getParent() != null) {
+      this.uiComponent.getParent().remove(this.uiComponent);
+    }
+    super.Delete();
+
+    // On linux we prefer to have a memory leak instead of a crash
+    if (!this.renderWindow.GetClassName().equals("vtkXOpenGLRenderWindow")) {
+      this.renderWindow = null;
+    } else {
+      System.out.println("The renderwindow has been kept around to prevent a crash");
+    }
+    this.lock.unlock();
+    vtkObject.JAVA_OBJECT_MANAGER.gc(false);
+  }
+
+  /**
+   * @return true if the graphical component has been properly set and
+   *         operation can be performed on it.
+   */
+  public boolean isWindowSet() {
+    return this.isWindowCreated;
+  }
+
+  /**
+   * Set a callback that gets called once the window is properly created and can be
+   * customized in its settings.
+   *
+   * Once called the callback will be released.
+   *
+   * @param callback
+   */
+  public void setWindowReadyCallback(Runnable callback) {
+    this.onWindowCreatedCallback = callback;
+  }
+
+  /**
+   * Just allow class in same package to affect inRenderCall boolean
+   *
+   * @param value
+   */
+  protected void updateInRenderCall(boolean value) {
+    this.inRenderCall = value;
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/awt/vtkInternalAwtComponent.java b/vtk.rendering/src/vtk/rendering/awt/vtkInternalAwtComponent.java
new file mode 100644 (file)
index 0000000..08bba08
--- /dev/null
@@ -0,0 +1,41 @@
+package vtk.rendering.awt;
+
+import java.awt.Canvas;
+import java.awt.Graphics;
+
+import vtk.vtkRenderWindow;
+
+public class vtkInternalAwtComponent extends Canvas {
+  protected native int RenderCreate(vtkRenderWindow renderWindow);
+
+  private static final long serialVersionUID = -7756069664577797620L;
+  private vtkAwtComponent parent;
+
+  public vtkInternalAwtComponent(vtkAwtComponent parent) {
+    this.parent = parent;
+    this.addMouseListener(this.parent.getInteractorForwarder());
+    this.addMouseMotionListener(this.parent.getInteractorForwarder());
+    this.addMouseWheelListener(this.parent.getInteractorForwarder());
+    this.addKeyListener(this.parent.getInteractorForwarder());
+  }
+
+  public void addNotify() {
+    super.addNotify();
+    parent.isWindowCreated = false;
+    parent.getRenderWindow().SetForceMakeCurrent();
+    parent.updateInRenderCall(false);
+  }
+
+  public void removeNotify() {
+    parent.updateInRenderCall(true);
+    super.removeNotify();
+  }
+
+  public void paint(Graphics g) {
+    parent.Render();
+  }
+
+  public void update(Graphics g) {
+    parent.Render();
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/awt/vtkPanelComponent.java b/vtk.rendering/src/vtk/rendering/awt/vtkPanelComponent.java
new file mode 100644 (file)
index 0000000..79cbf2a
--- /dev/null
@@ -0,0 +1,128 @@
+package vtk.rendering.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.util.concurrent.locks.ReentrantLock;
+
+import vtk.vtkCamera;
+import vtk.vtkGenericRenderWindowInteractor;
+import vtk.vtkInteractorStyle;
+import vtk.vtkInteractorStyleTrackballCamera;
+import vtk.vtkPanel;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+import vtk.rendering.vtkComponent;
+import vtk.rendering.vtkInteractorForwarder;
+
+/**
+ * Provide AWT based vtk rendering component using the vtkPanel class
+ * while exposing everything as a new rendering component.
+ *
+ * @author Sebastien Jourdain - sebastien.jourdain@kitware.com
+ *
+ * Notes: This class should be replaced down the road by the vtkAwtComponent
+ *        but on some platform such as Windows the vtkAwtComponent
+ *        produce a runtime error regarding invalid pixel format while
+ *        the vtkPanelComponent which use vtkPanel works fine.
+ *        For now, this class provide a good substitute with just a minor overhead.
+ */
+
+public class vtkPanelComponent implements vtkComponent<vtkPanel> {
+  protected vtkPanel panel;
+  protected ReentrantLock lock;
+  protected vtkGenericRenderWindowInteractor windowInteractor;
+  protected vtkInteractorForwarder eventForwarder;
+
+  public vtkPanelComponent() {
+    this.panel = new vtkPanel();
+    this.lock = new ReentrantLock();
+
+    // Init interactor
+    this.windowInteractor = new vtkGenericRenderWindowInteractor();
+    this.windowInteractor.SetRenderWindow(this.panel.GetRenderWindow());
+    this.windowInteractor.TimerEventResetsTimerOff();
+
+    this.windowInteractor.SetSize(200, 200);
+    this.windowInteractor.ConfigureEvent();
+
+    // Update style
+    vtkInteractorStyleTrackballCamera style = new vtkInteractorStyleTrackballCamera();
+    this.windowInteractor.SetInteractorStyle(style);
+
+    // Setup event forwarder
+    this.eventForwarder = new vtkInteractorForwarder(this);
+    this.windowInteractor.AddObserver("CreateTimerEvent", this.eventForwarder, "StartTimer");
+    this.windowInteractor.AddObserver("DestroyTimerEvent", this.eventForwarder, "DestroyTimer");
+
+    // Remove unwanted listeners
+    this.panel.removeKeyListener(this.panel);
+    this.panel.removeMouseListener(this.panel);
+    this.panel.removeMouseMotionListener(this.panel);
+    this.panel.removeMouseWheelListener(this.panel);
+
+    // Add mouse listener that update interactor
+    this.panel.addMouseListener(this.eventForwarder);
+    this.panel.addMouseMotionListener(this.eventForwarder);
+    this.panel.addMouseWheelListener(this.eventForwarder);
+
+    // Make sure we update the light position when interacting
+    this.panel.addMouseMotionListener(new MouseMotionAdapter() {
+      public void mouseDragged(MouseEvent e) {
+        panel.UpdateLight();
+      }
+    });
+  }
+
+  public void resetCamera() {
+    this.panel.resetCamera();
+  }
+
+  public void resetCameraClippingRange() {
+    this.panel.resetCameraClippingRange();
+  }
+
+  public vtkCamera getActiveCamera() {
+    return this.panel.GetRenderer().GetActiveCamera();
+  }
+
+  public vtkRenderer getRenderer() {
+    return this.panel.GetRenderer();
+  }
+
+  public vtkRenderWindow getRenderWindow() {
+    return this.panel.GetRenderWindow();
+  }
+
+  public vtkGenericRenderWindowInteractor getRenderWindowInteractor() {
+    return this.windowInteractor;
+  }
+
+  public void setInteractorStyle(vtkInteractorStyle style) {
+    this.getRenderWindowInteractor().SetInteractorStyle(style);
+  }
+
+  public void setSize(int w, int h) {
+    this.panel.setSize(w, h);
+    this.getRenderWindowInteractor().SetSize(w, h);
+  }
+
+  public vtkPanel getComponent() {
+    return this.panel;
+  }
+
+  public void Delete() {
+    this.panel.Delete();
+  }
+
+  public void Render() {
+    this.panel.Render();
+  }
+
+  public vtkInteractorForwarder getInteractorForwarder() {
+    return this.eventForwarder;
+  }
+
+  public ReentrantLock getVTKLock() {
+    return this.lock;
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/swt/vtkInternalSwtComponent.java b/vtk.rendering/src/vtk/rendering/swt/vtkInternalSwtComponent.java
new file mode 100644 (file)
index 0000000..2d73b3d
--- /dev/null
@@ -0,0 +1,127 @@
+package vtk.rendering.swt;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.GLRunnable;
+import com.jogamp.opengl.swt.GLCanvas;
+
+import vtk.vtkObject;
+
+/**
+ * @author    Joachim Pouderoux - joachim.pouderoux@kitware.com, Kitware SAS 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public class vtkInternalSwtComponent extends GLCanvas implements Listener {
+
+  private vtkSwtComponent parent;
+
+  public static GLCapabilities GetGLCapabilities() {
+    GLCapabilities caps;
+    caps = new GLCapabilities(GLProfile.get(GLProfile.GL2GL3));
+    caps.setDoubleBuffered(true);
+    caps.setHardwareAccelerated(true);
+    caps.setSampleBuffers(false);
+    caps.setNumSamples(4);
+    
+    caps.setAlphaBits(8);
+
+    return caps;
+  }
+
+  public vtkInternalSwtComponent(vtkSwtComponent parent, Composite parentComposite) {
+
+    super(parentComposite, SWT.NO_BACKGROUND, GetGLCapabilities(), null);
+    this.parent = parent;
+
+    vtkSwtInteractorForwarderDecorator forwarder = (vtkSwtInteractorForwarderDecorator) this.parent
+      .getInteractorForwarder();
+
+    this.addMouseListener(forwarder);
+    this.addKeyListener(forwarder);
+    this.addMouseMoveListener(forwarder);
+    this.addMouseTrackListener(forwarder);
+    this.addMouseWheelListener(forwarder);
+
+    this.addListener(SWT.Paint, this);
+    this.addListener(SWT.Close, this);
+    this.addListener(SWT.Dispose, this);
+    this.addListener(SWT.Resize, this);
+
+    this.IntializeRenderWindow();
+  }
+
+  protected void IntializeRenderWindow() {
+
+    // setCurrent(); // need to be done so SetWindowIdFromCurrentContext can
+    // get the current context!
+    // Context is not created until the first draw call. The renderer isn't
+    // initialized until the context is
+    // present.
+    invoke(false, new GLRunnable() {
+
+      @Override
+      public boolean run(GLAutoDrawable arg0) {
+        // This makes this thread (should be the main thread) current
+        getContext().makeCurrent();
+        parent.getRenderWindow().InitializeFromCurrentContext();
+        // Swapping buffers is handled by the vtkSwtComponent
+        parent.getRenderWindow().SwapBuffersOff();
+        return false;
+      }
+    });
+
+    // Swap buffers to trigger context creation
+    swapBuffers();
+    setAutoSwapBufferMode(false);
+  }
+
+  @Override
+  public void update() {
+    super.update();
+    if (isRealized()) {
+      parent.Render();
+    }
+  }
+
+  @Override
+  public void dispose() {
+    this.removeListener(SWT.Paint, this);
+    this.removeListener(SWT.Close, this);
+    this.removeListener(SWT.Dispose, this);
+    this.removeListener(SWT.Resize, this);
+
+    if (getContext().isCurrent()) {
+      getContext().release();
+    }
+    super.dispose();
+  }
+
+  @Override
+  public void handleEvent(Event event) {
+    switch (event.type) {
+    case SWT.Paint:
+      if (isRealized()) {
+        parent.Render();
+      }
+      break;
+    case SWT.Dispose:
+      parent.Delete();
+      vtkObject.JAVA_OBJECT_MANAGER.gc(false);
+      break;
+    case SWT.Close:
+      // System.out.println("closing");
+      break;
+    case SWT.Resize:
+      parent.setSize(getClientArea().width, getClientArea().height);
+      break;
+    }
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/swt/vtkSwtComponent.java b/vtk.rendering/src/vtk/rendering/swt/vtkSwtComponent.java
new file mode 100644 (file)
index 0000000..7d79189
--- /dev/null
@@ -0,0 +1,135 @@
+package vtk.rendering.swt;
+
+import org.eclipse.swt.widgets.Composite;
+
+import com.jogamp.opengl.swt.GLCanvas;
+
+import vtk.vtkRenderWindow;
+import vtk.rendering.vtkAbstractComponent;
+
+/**
+ * Provide SWT based vtk rendering component
+ *
+ * @author    Joachim Pouderoux - joachim.pouderoux@kitware.com, Kitware SAS 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public class vtkSwtComponent extends vtkAbstractComponent<GLCanvas> {
+
+  protected vtkInternalSwtComponent uiComponent;
+  protected boolean isWindowCreated;
+
+  public vtkSwtComponent(Composite parentComposite) {
+    this(new vtkRenderWindow(), parentComposite);
+  }
+
+  public vtkSwtComponent(vtkRenderWindow renderWindowToUse, Composite parentComposite) {
+    super(renderWindowToUse);
+    this.eventForwarder = new vtkSwtInteractorForwarderDecorator(this, this.eventForwarder);
+    this.isWindowCreated = true;
+    this.uiComponent = new vtkInternalSwtComponent(this, parentComposite);
+
+    renderWindow.AddObserver("StartEvent", this, "startEvent");
+    renderWindow.AddObserver("EndEvent", this, "endEvent");
+  }
+
+  /**
+   * Set the size of the VTK component
+   * @param x width
+   * @param y height
+   */
+  @Override
+  public void setSize(int x, int y) {
+    x = x < 1 ? 1 : x;
+    y = y < 1 ? 1 : y;
+    super.setSize(x, y);
+    this.uiComponent.setSize(x, y);
+    this.uiComponent.redraw();
+    this.uiComponent.update();
+  }
+
+  /**
+   * Render the VTK component. Should not be called externally.
+   * Call update() to refresh the window content.
+   */
+  @Override
+  public void Render() {
+    // Make sure we can render
+    if (inRenderCall || renderer == null || renderWindow == null) {
+      return;
+    }
+
+    // Try to render
+    try {
+      lock.lockInterruptibly();
+      inRenderCall = true;
+      // Trigger the real render
+      renderWindow.Render();
+    } catch (InterruptedException e) {
+      // Nothing that we can do except skipping execution
+    } finally {
+      lock.unlock();
+      inRenderCall = false;
+    }
+  }
+
+  /**
+   * Redraw the VTK component
+   */
+  public void update() {
+    this.uiComponent.redraw();
+    this.uiComponent.update();
+  }
+
+  /**
+   * @return the encapsulated SWT component (a GLCanvas instance)
+   * @see vtk.rendering.vtkAbstractComponent#getComponent()
+   */
+  @Override
+  public GLCanvas getComponent() {
+    return this.uiComponent;
+  }
+
+  @Override
+  public void Delete() {
+    this.lock.lock();
+    // We prevent any further rendering
+    this.inRenderCall = true;
+    this.renderWindow = null;
+    super.Delete();
+    this.lock.unlock();
+  }
+
+  /**
+   * @return true if the graphical component has been properly set and
+   *         operation can be performed on it.
+   */
+  public boolean isWindowSet() {
+    return this.isWindowCreated;
+  }
+
+  /**
+   * Just allow class in same package to affect inRenderCall boolean
+   *
+   * @param value
+   */
+  protected void updateInRenderCall(boolean value) {
+    this.inRenderCall = value;
+  }
+
+  /** This method is called by the VTK JNI code. Do not remove. */
+  void startEvent() {
+    if (!getComponent().getContext().isCurrent()) {
+      getComponent().getContext().makeCurrent();
+    }
+  }
+
+  /** This method is called by the VTK JNI code. Do not remove. */
+  void endEvent() {
+    if (getComponent().getContext().isCurrent()) {
+      getComponent().swapBuffers();
+      getComponent().getContext().release();
+    }
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/swt/vtkSwtInteractorForwarderDecorator.java b/vtk.rendering/src/vtk/rendering/swt/vtkSwtInteractorForwarderDecorator.java
new file mode 100644 (file)
index 0000000..2817886
--- /dev/null
@@ -0,0 +1,105 @@
+package vtk.rendering.swt;
+
+import java.awt.Label;
+
+import vtk.rendering.vtkComponent;
+import vtk.rendering.vtkInteractorForwarder;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.MouseWheelListener;
+
+/**
+ * Decorator class used to implement all Mouse/Key SWT listener and convert them
+ * into the vtkInteractorForwarder proper AWT event.
+ *
+ * @author    Joachim Pouderoux - joachim.pouderoux@kitware.com, Kitware SAS 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public class vtkSwtInteractorForwarderDecorator extends vtkInteractorForwarder
+implements MouseListener, MouseMoveListener, MouseTrackListener, MouseWheelListener, KeyListener {
+
+  vtkInteractorForwarder forwarder;
+  Label dummyComponent;
+
+  public vtkSwtInteractorForwarderDecorator(vtkComponent<?> component, vtkInteractorForwarder forwarder) {
+    super(component);
+    dummyComponent = new Label();
+    this.forwarder = forwarder;
+  }
+
+  public static int convertModifiers(int mods) {
+    int modifiers = 0;
+    if ((mods & SWT.SHIFT) != 0) modifiers |= java.awt.Event.SHIFT_MASK;
+    if ((mods & SWT.CTRL) != 0) modifiers |= java.awt.Event.CTRL_MASK;
+    if ((mods & SWT.ALT) != 0) modifiers |= java.awt.Event.ALT_MASK;
+    return modifiers;
+  }
+
+  public java.awt.event.KeyEvent convertKeyEvent(org.eclipse.swt.events.KeyEvent e) {
+    return new java.awt.event.KeyEvent(dummyComponent, 0, (long)e.time, convertModifiers(e.stateMask), e.keyCode, e.character);
+  }
+
+  public java.awt.event.MouseEvent convertMouseEvent(org.eclipse.swt.events.MouseEvent e) {
+    int button = 0;
+    if ((e.button == 1) || (e.stateMask & SWT.BUTTON1) != 0) button = java.awt.event.MouseEvent.BUTTON1;
+    else if ((e.button == 2) || (e.stateMask & SWT.BUTTON2) != 0) button = java.awt.event.MouseEvent.BUTTON2;
+    else if ((e.button == 3) || (e.stateMask & SWT.BUTTON3) != 0) button = java.awt.event.MouseEvent.BUTTON3;
+    return new java.awt.event.MouseEvent(dummyComponent, 0, (long)e.time, convertModifiers(e.stateMask), e.x, e.y, e.count, false, button);
+  }
+
+  public java.awt.event.MouseWheelEvent convertMouseWheelEvent(org.eclipse.swt.events.MouseEvent e) {
+    return new java.awt.event.MouseWheelEvent(dummyComponent, 0, e.time, convertModifiers(e.stateMask), e.x, e.y, 0, false, java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, e.count);
+  }
+
+  public void keyPressed(KeyEvent e) {
+    super.keyPressed(convertKeyEvent(e));
+  }
+
+  public void keyReleased(KeyEvent e) {
+    super.keyReleased(convertKeyEvent(e));
+  }
+
+  public void mouseEnter(MouseEvent e) {
+    super.mouseEntered(convertMouseEvent(e));
+  }
+
+  public void mouseExit(MouseEvent e) {
+    super.mouseExited(convertMouseEvent(e));
+  }
+
+  public void mouseMove(MouseEvent e) {
+    if (((e.stateMask & SWT.BUTTON1) == 0)
+        && ((e.stateMask & SWT.BUTTON2) == 0)
+        && ((e.stateMask & SWT.BUTTON3) == 0)) {
+      super.mouseMoved(convertMouseEvent(e));
+    } else {
+      super.mouseDragged(convertMouseEvent(e));
+    }
+  }
+
+  public void mouseDown(MouseEvent e) {
+    super.mousePressed(convertMouseEvent(e));
+  }
+
+  public void mouseUp(MouseEvent e) {
+    super.mouseReleased(convertMouseEvent(e));
+  }
+
+  public void mouseScrolled(MouseEvent e) {
+    super.mouseWheelMoved(convertMouseWheelEvent(e));
+  }
+
+  public void mouseHover(MouseEvent e) {
+  }
+
+  public void mouseDoubleClick(MouseEvent e) {
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/vtkAbstractComponent.java b/vtk.rendering/src/vtk/rendering/vtkAbstractComponent.java
new file mode 100644 (file)
index 0000000..e68bd46
--- /dev/null
@@ -0,0 +1,181 @@
+package vtk.rendering;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+import vtk.vtkAxesActor;
+import vtk.vtkCamera;
+import vtk.vtkGenericRenderWindowInteractor;
+import vtk.vtkInteractorStyle;
+import vtk.vtkInteractorStyleTrackballCamera;
+import vtk.vtkOrientationMarkerWidget;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+
+/**
+ * Abstract class that bring most of the VTK logic to any rendering component
+ * regardless its origin. (awt, swt, sing, ...)
+ *
+ * @param <T>
+ *            The concrete type of the graphical component that will contains
+ *            the vtkRenderWindow.
+ *
+ * @authors Sebastien Jourdain - sebastien.jourdain@kitware.com, Kitware Inc 2012
+ *          Joachim Pouderoux - joachim.pouderoux@kitware.com, Kitware SAS 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public abstract class vtkAbstractComponent<T> implements vtkComponent<T> {
+  protected vtkRenderWindow renderWindow;
+  protected vtkRenderer renderer;
+  protected vtkCamera camera;
+  protected vtkGenericRenderWindowInteractor windowInteractor;
+  protected vtkInteractorForwarder eventForwarder;
+  protected ReentrantLock lock;
+  protected boolean inRenderCall;
+
+  public vtkAbstractComponent() {
+    this(new vtkRenderWindow());
+  }
+
+  public vtkAbstractComponent(vtkRenderWindow renderWindowToUse) {
+    this.inRenderCall = false;
+    this.renderWindow = renderWindowToUse;
+    this.renderer = new vtkRenderer();
+    this.windowInteractor = new vtkGenericRenderWindowInteractor();
+    this.lock = new ReentrantLock();
+
+    // Init interactor
+    this.windowInteractor.SetRenderWindow(this.renderWindow);
+    this.windowInteractor.TimerEventResetsTimerOff();
+
+    this.windowInteractor.SetSize(200, 200);
+    this.windowInteractor.ConfigureEvent();
+
+    // Update style
+    vtkInteractorStyleTrackballCamera style = new vtkInteractorStyleTrackballCamera();
+    this.windowInteractor.SetInteractorStyle(style);
+
+    // Setup event forwarder
+    this.eventForwarder = new vtkInteractorForwarder(this);
+    this.windowInteractor.AddObserver("CreateTimerEvent", this.eventForwarder, "StartTimer");
+    this.windowInteractor.AddObserver("DestroyTimerEvent", this.eventForwarder, "DestroyTimer");
+
+    // Link renderWindow with renderer
+    this.renderWindow.AddRenderer(this.renderer);
+
+    // Keep camera around to prevent its creation/deletion in Java world
+    this.camera = this.renderer.GetActiveCamera();
+  }
+
+  public ReentrantLock getVTKLock() {
+    return this.lock;
+  }
+
+  public void resetCamera() {
+    if (renderer == null) {
+      return; // Nothing to do we are deleted...
+    }
+
+    try {
+      lock.lockInterruptibly();
+      renderer.ResetCamera();
+    } catch (InterruptedException e) {
+      // Nothing that we can do
+    } finally {
+      this.lock.unlock();
+    }
+  }
+
+  public void resetCameraClippingRange() {
+    if (renderWindow == null) {
+      return; // Nothing to do we are deleted...
+    }
+
+    try {
+      this.lock.lockInterruptibly();
+      renderer.ResetCameraClippingRange();
+    } catch (InterruptedException e) {
+      // Nothing that we can do
+    } finally {
+      this.lock.unlock();
+    }
+  }
+
+  public vtkCamera getActiveCamera() {
+    return this.camera;
+  }
+
+  public vtkRenderer getRenderer() {
+    return this.renderer;
+  }
+
+  public vtkRenderWindow getRenderWindow() {
+    return this.renderWindow;
+  }
+
+  public vtkGenericRenderWindowInteractor getRenderWindowInteractor() {
+    return this.windowInteractor;
+  }
+
+  public void setInteractorStyle(vtkInteractorStyle style) {
+    if (this.windowInteractor != null) {
+      this.lock.lock();
+      this.windowInteractor.SetInteractorStyle(style);
+      this.lock.unlock();
+    }
+  }
+
+  public void setSize(int w, int h) {
+    if (renderWindow == null || windowInteractor == null) {
+      return; // Nothing to do we are deleted...
+    }
+
+    try {
+      lock.lockInterruptibly();
+      renderWindow.SetSize(w, h);
+      windowInteractor.SetSize(w, h);
+    } catch (InterruptedException e) {
+      // Nothing that we can do
+    } finally {
+      this.lock.unlock();
+    }
+  }
+
+  public void Delete() {
+    this.lock.lock();
+    this.renderer = null;
+    this.camera = null;
+    this.windowInteractor = null;
+    // removing the renderWindow is let to the superclass
+    // because in the very special case of an AWT component
+    // under Linux, destroying renderWindow crashes.
+    this.lock.unlock();
+  }
+
+  public vtkInteractorForwarder getInteractorForwarder() {
+    return this.eventForwarder;
+  }
+
+  public abstract T getComponent();
+
+  /**
+   * Generic helper method used to attach orientation axes to a vtkComponent
+   *
+   * @param vtkComponent<?>
+   */
+  public static void attachOrientationAxes(vtkComponent<?> component) {
+    // only build this once, because it creates its own renderer.
+    // Extra renderers causes issues with resetting.
+    vtkAxesActor axes = new vtkAxesActor();
+    vtkOrientationMarkerWidget axesWidget = new vtkOrientationMarkerWidget();
+
+    axesWidget.SetOutlineColor(0.9300, 0.5700, 0.1300);
+    axesWidget.SetOrientationMarker(axes);
+    axesWidget.SetInteractor(component.getRenderWindowInteractor());
+    axesWidget.SetDefaultRenderer(component.getRenderer());
+    axesWidget.SetViewport(0.0, 0.0, .2, .2);
+    axesWidget.EnabledOn();
+    axesWidget.InteractiveOff();
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/vtkAbstractEventInterceptor.java b/vtk.rendering/src/vtk/rendering/vtkAbstractEventInterceptor.java
new file mode 100644 (file)
index 0000000..b63f3e4
--- /dev/null
@@ -0,0 +1,64 @@
+package vtk.rendering;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+
+/**
+ * This class implement vtkEventInterceptor with no event interception at all.
+ *
+ * @see {@link MouseMotionListener} {@link MouseListener} {@link MouseWheelListener}
+ *      {@link KeyListener}
+ *
+ * @author    Sebastien Jourdain - sebastien.jourdain@kitware.com, Kitware Inc 2013
+ */
+
+public class vtkAbstractEventInterceptor implements vtkEventInterceptor {
+
+  public boolean keyPressed(KeyEvent e) {
+    return false;
+  }
+
+  public boolean keyReleased(KeyEvent e) {
+    return false;
+  }
+
+  public boolean keyTyped(KeyEvent e) {
+    return false;
+  }
+
+  public boolean mouseDragged(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseMoved(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseClicked(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseEntered(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseExited(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mousePressed(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseReleased(MouseEvent e) {
+    return false;
+  }
+
+  public boolean mouseWheelMoved(MouseWheelEvent e) {
+    return false;
+  }
+}
diff --git a/vtk.rendering/src/vtk/rendering/vtkComponent.java b/vtk.rendering/src/vtk/rendering/vtkComponent.java
new file mode 100644 (file)
index 0000000..d9d72de
--- /dev/null
@@ -0,0 +1,106 @@
+package vtk.rendering;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+import vtk.vtkCamera;
+import vtk.vtkGenericRenderWindowInteractor;
+import vtk.vtkInteractorStyle;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+
+/**
+ * Generic API for any new VTK based graphical components.
+ *
+ * @param <T>
+ *            The concrete type of the graphical component that will contains
+ *            the vtkRenderWindow.
+ *
+ * @author    Sebastien Jourdain - sebastien.jourdain@kitware.com, Kitware Inc 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+
+public interface vtkComponent<T> {
+
+  /**
+   * @return the lock that is used to prevent concurrency inside this
+   *         rendering component. This lock can also be used outside to make
+   *         sure any VTK processing happen in a save manner.
+   */
+  ReentrantLock getVTKLock();
+
+  /**
+   * Adjust the camera position so any object in the scene will be fully seen.
+   */
+  void resetCamera();
+
+  /**
+   * Update the clipping range of the camera
+   */
+  void resetCameraClippingRange();
+
+  /**
+   * @return the active camera of the renderer
+   */
+  vtkCamera getActiveCamera();
+
+  /**
+   * @return a reference to the Renderer used internally
+   */
+  vtkRenderer getRenderer();
+
+  /**
+   * Useful for screen capture or exporter.
+   *
+   * @return a reference to the RenderWindow used internally
+   */
+  vtkRenderWindow getRenderWindow();
+
+  /**
+   * vtkWindowInteractor is useful if you want to attach 3DWidget into your
+   * view.
+   *
+   * @return a reference to the vtkWindowInteractor used internally
+   */
+  vtkGenericRenderWindowInteractor getRenderWindowInteractor();
+
+  /**
+   * Shortcut method to bind an vtkInteractorStyle to our interactor.
+   *
+   * @param style
+   */
+  void setInteractorStyle(vtkInteractorStyle style);
+
+  /**
+   * Update width and height of the given component
+   *
+   * @param w
+   * @param h
+   */
+  void setSize(int w, int h);
+
+  /**
+   * @return the concrete implementation of the graphical container such as
+   *         java.awt.Canvas / java.swing.JComponent /
+   *         org.eclipse.swt.opengl.GLCanvas
+   */
+  T getComponent();
+
+  /**
+   * Remove any reference from Java to vtkObject to allow the VTK Garbage
+   * collector to free any remaining memory. This is specially needed for
+   * internal hidden reference to vtkObject.
+   */
+  void Delete();
+
+  /**
+   * Request a render.
+   */
+  void Render();
+
+  /**
+   * @return the vtkInteractor Java event converter.
+   */
+  vtkInteractorForwarder getInteractorForwarder();
+}
diff --git a/vtk.rendering/src/vtk/rendering/vtkEventInterceptor.java b/vtk.rendering/src/vtk/rendering/vtkEventInterceptor.java
new file mode 100644 (file)
index 0000000..1f388f4
--- /dev/null
@@ -0,0 +1,111 @@
+package vtk.rendering;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+
+/**
+ * This interface defines what should be implemented to intercept interaction
+ * events and create custom behavior.
+ *
+ * @see {@link MouseMotionListener} {@link MouseListener} {@link MouseWheelListener}
+ *      {@link KeyListener}
+ *
+ * @author    Sebastien Jourdain - sebastien.jourdain@kitware.com, Kitware Inc 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public interface vtkEventInterceptor {
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean keyPressed(KeyEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean keyReleased(KeyEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean keyTyped(KeyEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseDragged(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseMoved(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseClicked(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseEntered(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseExited(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mousePressed(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseReleased(MouseEvent e);
+
+  /**
+   * @param e
+   *            event
+   * @return true if the event has been consumed and should not be forwarded
+   *         to the vtkInteractor
+   */
+  boolean mouseWheelMoved(MouseWheelEvent e);
+}
diff --git a/vtk.rendering/src/vtk/rendering/vtkInteractorForwarder.java b/vtk.rendering/src/vtk/rendering/vtkInteractorForwarder.java
new file mode 100644 (file)
index 0000000..af8a6e3
--- /dev/null
@@ -0,0 +1,389 @@
+package vtk.rendering;
+
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.lang.reflect.Field;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class used to implement all Mouse/Key Java listener and convert them
+ * into the vtkInteractor proper event.
+ *
+ * @authors   Sebastien Jourdain - sebastien.jourdain@kitware.com, Kitware Inc 2012
+ *            Joachim Pouderoux - joachim.pouderoux@kitware.com, Kitware SAS 2012
+ * @copyright This work was supported by CEA/CESTA
+ *            Commissariat a l'Energie Atomique et aux Energies Alternatives,
+ *            15 avenue des Sablieres, CS 60001, 33116 Le Barp, France.
+ */
+public class vtkInteractorForwarder implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener {
+  final public static int MOUSE_BUTTON_1 = 1;
+  final public static int MOUSE_BUTTON_2 = 2;
+  final public static int MOUSE_BUTTON_3 = 4;
+  final public static int MOUSE_MODIFIER_SHIFT = 1;
+  final public static int MOUSE_MODIFIER_CTRL = 2;
+  final public static int MOUSE_MODIFIER_ALT = 4;
+
+  private int lastX;
+  private int lastY;
+  private int ctrlPressed;
+  private int shiftPressed;
+  private vtkComponent<?> component;
+  private double updateRate, updateRateRelease;
+  private double scaleFactor = 1;
+  private ScheduledExecutorService scheduler;
+  private Runnable eventTick;
+  private vtkEventInterceptor eventInterceptor;
+
+  public vtkInteractorForwarder(vtkComponent<?> component) {
+    this.component = component;
+    this.lastX = this.lastY = this.ctrlPressed = 0;
+    this.updateRate = 5.0;
+    this.updateRateRelease = 0.01;
+    this.scaleFactor = vtkInteractorForwarder.getDisplayScale();
+
+    this.eventTick = new Runnable() {
+
+      public void run() {
+        vtkInteractorForwarder.this.component.getVTKLock().lock();
+        vtkInteractorForwarder.this.component.getRenderWindowInteractor().TimerEvent();
+        vtkInteractorForwarder.this.component.getVTKLock().unlock();
+      }
+    };
+
+    // Schedule time events
+    this.scheduler = Executors.newSingleThreadScheduledExecutor();
+  }
+
+  /**
+   * Provide a custom event interceptor
+   *
+   * @param eventInterceptor
+   */
+  public void setEventInterceptor(vtkEventInterceptor eventInterceptor) {
+    this.eventInterceptor = eventInterceptor;
+  }
+
+  /**
+   * @return the custom event interceptor if any otherwise return null
+   */
+  public vtkEventInterceptor getEventInterceptor() {
+    return eventInterceptor;
+  }
+
+  /**
+   * Method called by VTK to start a timer
+   */
+  public void StartTimer() {
+    this.scheduler.scheduleAtFixedRate(this.eventTick, 10, 10, TimeUnit.MILLISECONDS);
+  }
+
+  /**
+   * Method called by VTK to stop a timer
+   */
+  public void DestroyTimer() {
+    this.scheduler.shutdown();
+  }
+
+  /**
+   * Allow the user to change the update rate
+   *
+   * @param updateRate
+   * @param updateRateRelease
+   */
+  public void setUpdateRate(double updateRate, double updateRateRelease) {
+    this.updateRate = updateRate;
+    this.updateRateRelease = updateRateRelease;
+  }
+
+  /**
+   * @return the update rate that is currently used
+   */
+  public double getUpdateRate() {
+    return updateRate;
+  }
+
+  /**
+   * @return the update rate after release that is currently used
+   */
+  public double getUpdateRateRelease() {
+    return updateRateRelease;
+  }
+
+  public void mousePressed(MouseEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mousePressed(e)) {
+      return;
+    }
+
+    // Update scale factor if needed
+    this.scaleFactor = 1;
+    if (e.getComponent().getGraphicsConfiguration() != null) {
+      this.scaleFactor = vtkInteractorForwarder.getGraphicDeviceScale(e.getComponent().getGraphicsConfiguration().getDevice());
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRate);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+      switch (e.getButton()) {
+      case MouseEvent.BUTTON3:
+        component.getRenderWindowInteractor().RightButtonPressEvent();
+        break;
+      case MouseEvent.BUTTON2:
+        component.getRenderWindowInteractor().MiddleButtonPressEvent();
+        break;
+      case MouseEvent.BUTTON1:
+      default:
+        component.getRenderWindowInteractor().LeftButtonPressEvent();
+        break;
+      }
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void mouseReleased(MouseEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseReleased(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+      switch (e.getButton()) {
+      case MouseEvent.BUTTON3:
+        component.getRenderWindowInteractor().RightButtonReleaseEvent();
+        break;
+      case MouseEvent.BUTTON2:
+        component.getRenderWindowInteractor().MiddleButtonReleaseEvent();
+        break;
+      case MouseEvent.BUTTON1:
+      default:
+        component.getRenderWindowInteractor().LeftButtonReleaseEvent();
+        break;
+      }
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void mouseMoved(MouseEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseMoved(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+      component.getRenderWindowInteractor().MouseMoveEvent();
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void mouseDragged(MouseEvent e) {
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseDragged(e)) {
+      return;
+    }
+
+    this.mouseMoved(e);
+  }
+
+  public void mouseEntered(MouseEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseEntered(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+      component.getRenderWindowInteractor().EnterEvent();
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void mouseExited(MouseEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseExited(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+      component.getRenderWindowInteractor().LeaveEvent();
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void mouseClicked(MouseEvent e) {
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseClicked(e)) {
+      return;
+    }
+  }
+
+  public void mouseWheelMoved(MouseWheelEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.mouseWheelMoved(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      lastX = (int)(e.getX() * scaleFactor);
+      lastY = (int)(e.getY() * scaleFactor);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      if (e.getWheelRotation() > 0) {
+        component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+        component.getRenderWindowInteractor().MouseWheelBackwardEvent();
+      }
+      else if (e.getWheelRotation() < 0) {
+        component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, '0', 0, "0");
+        component.getRenderWindowInteractor().MouseWheelForwardEvent();
+      }
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void keyPressed(KeyEvent e) {
+    if (component == null || component.getRenderer() == null) {
+      return;
+    }
+
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.keyPressed(e)) {
+      return;
+    }
+
+    try {
+      component.getVTKLock().lockInterruptibly();
+      component.getRenderWindow().SetDesiredUpdateRate(this.updateRateRelease);
+      ctrlPressed = (e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK ? 1 : 0;
+      shiftPressed = (e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK ? 1 : 0;
+      char keyChar = e.getKeyChar();
+      component.getRenderWindowInteractor().SetEventInformationFlipY(lastX, lastY, ctrlPressed, shiftPressed, keyChar, 0, String.valueOf(keyChar));
+      component.getRenderWindowInteractor().KeyPressEvent();
+      component.getRenderWindowInteractor().CharEvent();
+    } catch (InterruptedException interupt) {
+      // Nothing to do
+    } finally {
+      component.getVTKLock().unlock();
+    }
+  }
+
+  public void keyReleased(KeyEvent e) {
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.keyReleased(e)) {
+      return;
+    }
+  }
+
+  public void keyTyped(KeyEvent e) {
+    // Allow user to override some behavior
+    if (this.eventInterceptor != null && this.eventInterceptor.keyTyped(e)) {
+      return;
+    }
+  }
+
+  public static int getDisplayScale() {
+    GraphicsDevice graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+    return getGraphicDeviceScale(graphicsDevice);
+  }
+
+  public static int getGraphicDeviceScale(GraphicsDevice device) {
+    try {
+      Field field = device.getClass().getDeclaredField("scale");
+      if (field != null) {
+          field.setAccessible(true);
+          Object scale = field.get(device);
+          if (scale instanceof Integer) {
+            return ((Integer) scale).intValue();
+          }
+          System.out.println("Invalid scale type: " + scale);
+      }
+    } catch (Exception e) {
+      // Don't care, at least we tried.
+    }
+    return 1;
+  }
+}