[vtkusers] vtk + JAVA Swing

Richard.Bridge at tessella.com Richard.Bridge at tessella.com
Fri May 9 06:49:18 EDT 2003


John,

I had this problem too with vtkPanel using multiple instances in a Swing 
MDI. The way I got around it was to create a new set of swing classes for 
JInternalFrame, JDesktopPane (which is a layered pane), JMenu etc so that 
I could have the vtkPanel sat on a dialog owned by the desktopframe to 
keep it on top, synchronised to the position of JPanel sat on the 
JInternalFrame (so it looked like it was on the Panel), and wrote a 
function in the desktopPane to check for overlaps with other windows. 
Whenever my vtkPanel should be partly covered by a swingcomponent I hide 
the dialog with the vtkPanel on it and display a message on the JPanel 
underneath instead. Its not perfect but it looks pretty good for the 
majority of the time and certainly looks a lot better than drawing through 
the lightweight components.

Rich







Jeff Lee <jeff at cdnorthamerica.com>
Sent by: 
vtkusers-admin at public.kitware.com
08/05/2003 09:01 AST

 
        To:     John Biddiscombe <john.biddiscombe at mirada-solutions.com>
        cc:     vtkusers at public.kitware.com
        Subject:        Re: [vtkusers] vtk + JAVA Swing


Hi John,
Here is a modified vtkPanel which shows a popup menu when invoked with
<SHIFT>-MB1.  You can diff this vtkPanel against cvs to see what I
added, but it is pretty straightforward.  I quoted our previous message
for the mailing list.

John Biddiscombe wrote:

> Does anyone know if the JAVA vtkPanel control can be made to work by
> deriving it from a JComponent rather than a Canvas class.


There are ways to do this that would involve sacrifice of hardware
acceleration - basically replacing the native render window with an
image of the render window contents.  Interaction will be slow, and you
would need to render offscreen.  A compromise might be to only do this
when the user tries to invoke a widget which will be displayed on top of
the render window.

> I want to put the panel into a JLayeredPane and place other
> (lightweight) controls over the top.


a render window inside a JComponent will always be on-top, except for
the case where JPopupMenu.setLightWeightPopupEnabled(false) is called,
which allows menus/popups to be displayed as heavyweight, thus obeying
z-order when displayed atop another heavyweight component (see modified
vtkPanel).  What types of controls do you intend to use? -Jeff

> Currently it overwrites anything else in the same screen space
> (Presumably blitting on top of anything drawn using native swing-type
> code).
>
> thanks
>
> JB
>


package vtk;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class vtkPanel extends Canvas implements
MouseListener,
MouseMotionListener,
KeyListener
{
protected vtkRenderWindow rw = new vtkRenderWindow();
protected vtkRenderer ren = new vtkRenderer();
protected vtkCamera cam = null;
protected vtkLight lgt = new vtkLight();
protected int lastX;
protected int lastY;
protected int windowset = 0;
protected int lightingset = 0;
protected int LightFollowCamera = 1;
protected int InteractionMode = 1;
protected boolean rendering = false;
protected WindowObservable windowSetObservable = new WindowObservable();
private final JPopupMenu viewMenu = new JPopupMenu();

static {
System.loadLibrary("vtkCommonJava");
System.loadLibrary("vtkFilteringJava");
System.loadLibrary("vtkIOJava");
System.loadLibrary("vtkImagingJava");
System.loadLibrary("vtkGraphicsJava");
System.loadLibrary("vtkRenderingJava");
try {
System.loadLibrary("vtkHybridJava");
} catch (Throwable e) {
System.out.println("cannot load vtkHybrid, skipping...");
}
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
}

protected native int RenderCreate(vtkRenderWindow id0);
protected native int Lock();
protected native int UnLock();

public vtkPanel()
{
rw.AddRenderer(ren);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
super.setSize(200,200);
rw.SetSize(200,200);
addWindowSetObserver(new WindowSetObserver());
JMenuItem testMenuItem = new JMenuItem(new AbstractAction("do test") {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "tested.");
}
});
JMenu testMenu = new JMenu("test");
testMenu.add(testMenuItem);
viewMenu.add(testMenu);
}

public void Report() {

// must be performed on awt event thread
Runnable updateAComponent = new Runnable() {
public void run() {
Lock();
System.out.println("direct rendering = " + (rw.IsDirect()==1));
System.out.println("opengl supported = " + (rw.SupportsOpenGL()==1));
System.out.println("report = " + rw.ReportCapabilities());
UnLock();
}
};

SwingUtilities.invokeLater(updateAComponent);

}

public vtkRenderer GetRenderer()
{
return ren;
}

public vtkRenderWindow GetRenderWindow()
{
return rw;
}

public void addWindowSetObserver(Observer obs) {
windowSetObservable.addObserver(obs);
}

public void removeWindowSetObserver(Observer obs) {
windowSetObservable.deleteObserver(obs);
}

public void setSize(int x, int y)
{
super.setSize(x,y);
if (windowset == 1)
{
Lock();
rw.SetSize(x,y);
UnLock();
}
}

public void addNotify()
{
super.addNotify();
windowset = 0;
rw.SetForceMakeCurrent();
rendering = false;
}

public void removeNotify()
{
rendering = true;
super.removeNotify();
}

public synchronized void Render()
{
if (!rendering)
{
rendering = true;
if (ren.VisibleActorCount() == 0) {rendering = false; return;}
if (rw != null)
{
if (windowset == 0)
{
// set the window id and the active camera
cam = ren.GetActiveCamera();
if (lightingset == 0) {
ren.AddLight(lgt);
lgt.SetPosition(cam.GetPosition());
lgt.SetFocalPoint(cam.GetFocalPoint());
lightingset = 1;
}
RenderCreate(rw);
Lock();
rw.SetSize(getWidth(), getHeight());
UnLock();
windowset = 1;
// notify observers that we have a renderwindow created
windowSetObservable.notifyObservers();
}
Lock();
rw.Render();
UnLock();
rendering = false;
}
}
}

public boolean isWindowSet()
{
return (this.windowset==1);
}

public void paint(Graphics g)
{
this.Render();
}

public void update(Graphics g) {
paint(g);
}

public void LightFollowCameraOn()
{
this.LightFollowCamera = 1;
}

public void LightFollowCameraOff()
{
this.LightFollowCamera = 0;
}

public void InteractionModeRotate()
{
this.InteractionMode = 1;
}

public void InteractionModeTranslate()
{
this.InteractionMode = 2;
}

public void InteractionModeZoom()
{
this.InteractionMode = 3;
}

public void UpdateLight()
{
lgt.SetPosition(cam.GetPosition());
lgt.SetFocalPoint(cam.GetFocalPoint());
}

public void resetCameraClippingRange() {
Lock();
ren.ResetCameraClippingRange();
UnLock();
}

public void resetCamera() {
Lock();
ren.ResetCamera();
UnLock();
}

public void mouseClicked(MouseEvent e) {

}

public void mousePressed(MouseEvent e)
{
if (ren.VisibleActorCount() == 0) return;
rw.SetDesiredUpdateRate(5.0);
lastX = e.getX();
lastY = e.getY();
if ((e.getModifiers()==(InputEvent.BUTTON3_MASK | InputEvent.SHIFT_MASK)))
{
viewMenu.show(this, e.getX(),e.getY());
}
if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||
(e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))
{
InteractionModeTranslate();
}
else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
{
InteractionModeZoom();
}
else
{
InteractionModeRotate();
}
}

public void mouseReleased(MouseEvent e)
{
rw.SetDesiredUpdateRate(0.01);
}

public void mouseEntered(MouseEvent e)
{
this.requestFocus();
}

public void mouseExited(MouseEvent e) {}

public void mouseMoved(MouseEvent e)
{
lastX = e.getX();
lastY = e.getY();
}


public void mouseDragged(MouseEvent e)
{
if (ren.VisibleActorCount() == 0) return;
int x = e.getX();
int y = e.getY();
// rotate
if (this.InteractionMode == 1)
{
cam.Azimuth(lastX - x);
cam.Elevation(y - lastY);
cam.OrthogonalizeViewUp();
resetCameraClippingRange();
if (this.LightFollowCamera == 1)
{
lgt.SetPosition(cam.GetPosition());
lgt.SetFocalPoint(cam.GetFocalPoint());
}
}
// translate
if (this.InteractionMode == 2)
{
double  FPoint[];
double  PPoint[];
double  APoint[] = new double[3];
double  RPoint[];
double focalDepth;

// get the current focal point and position
FPoint = cam.GetFocalPoint();
PPoint = cam.GetPosition();

// calculate the focal depth since we'll be using it a lot
ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
ren.WorldToDisplay();
focalDepth = ren.GetDisplayPoint()[2];

APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
APoint[2] = focalDepth;
ren.SetDisplayPoint(APoint);
ren.DisplayToWorld();
RPoint = ren.GetWorldPoint();
if (RPoint[3] != 0.0)
{
RPoint[0] = RPoint[0]/RPoint[3];
RPoint[1] = RPoint[1]/RPoint[3];
RPoint[2] = RPoint[2]/RPoint[3];
}

/*
* Compute a translation vector, moving everything 1/2
* the distance to the cursor. (Arbitrary scale factor)
*/
cam.SetFocalPoint(
(FPoint[0]-RPoint[0])/2.0 + FPoint[0],
(FPoint[1]-RPoint[1])/2.0 + FPoint[1],
(FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
cam.SetPosition(
(FPoint[0]-RPoint[0])/2.0 + PPoint[0],
(FPoint[1]-RPoint[1])/2.0 + PPoint[1],
(FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
resetCameraClippingRange();
}
// zoom
if (this.InteractionMode == 3)
{
double zoomFactor;
double clippingRange[];

zoomFactor = Math.pow(1.02,(y - lastY));
if (cam.GetParallelProjection() == 1)
{
cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
}
else
{
cam.Dolly(zoomFactor);
resetCameraClippingRange();
}
}
lastX = x;
lastY = y;
this.Render();
}

public void keyTyped(KeyEvent e) {}

public void keyPressed(KeyEvent e)
{
if (ren.VisibleActorCount() == 0) return;
char keyChar = e.getKeyChar();

if ('r' == keyChar)
{
resetCamera();
this.Render();
}
if ('u' == keyChar)
{
pickActor(lastX, lastY);
}
if ('w' == keyChar)
{
vtkActorCollection ac;
vtkActor anActor;
vtkActor aPart;
int i, j;

ac = ren.GetActors();
ac.InitTraversal();
for (i = 0; i < ac.GetNumberOfItems(); i++)
{
anActor = ac.GetNextActor();
anActor.InitPartTraversal();
for (j = 0; j < anActor.GetNumberOfParts(); j++)
{
aPart = anActor.GetNextPart();
aPart.GetProperty().SetRepresentationToWireframe();
}
}
this.Render();
}
if ('s' == keyChar)
{
vtkActorCollection ac;
vtkActor anActor;
vtkActor aPart;
int i, j;

ac = ren.GetActors();
ac.InitTraversal();
for (i = 0; i < ac.GetNumberOfItems(); i++)
{
anActor = ac.GetNextActor();
anActor.InitPartTraversal();
for (j = 0; j < anActor.GetNumberOfParts(); j++)
{
aPart = anActor.GetNextPart();
aPart.GetProperty().SetRepresentationToSurface();
}
}
this.Render();
}
}

public void HardCopy(String filename, int mag) {

Lock();

vtkWindowToImageFilter w2if = new vtkWindowToImageFilter();
w2if.SetInput(rw);

w2if.SetMagnification(mag);
w2if.Update();

vtkTIFFWriter writer = new vtkTIFFWriter();
writer.SetInput(w2if.GetOutput());
writer.SetFileName(filename);
writer.Write();

UnLock();
}

public void pickActor(int x, int y) {

vtkPropPicker picker = new vtkPropPicker();

Lock();
picker.PickProp(x, rw.GetSize()[1] - y , ren);
UnLock();

if (picker.GetActor() != null)
System.out.println(picker.GetActor().GetClassName());
}

public void keyReleased(KeyEvent e) {}

private class WindowObservable extends Observable {

public void notifyObservers() {
this.setChanged();
super.notifyObservers();
}

public void notifyObservers(Object message) {
this.setChanged();
super.notifyObservers(message);
}

public boolean hasObservers() {
return 0 < super.countObservers();
}
}

private class WindowSetObserver implements Observer {

public void update(Observable o, Object arg) {
// we know the window is set, so changes to the render window size
// will actually take place
//       if (getWidth() > 0 && getHeight() > 0)
//         rw.SetSize(getWidth(), getHeight());
}

}

}




This message is confidential and may be privileged. It is intended for the 
addressee(s) only. Access to this message by anyone else is unauthorized 
and strictly prohibited. If you have received this message in error, 
please inform the sender immediately.

TESSELLA   Richard.Bridge at tessella.com
__/__/__/  Tessella Support Services plc
__/__/__/  3 Vineyard Chambers, ABINGDON, OX14 3PX, England
__/__/__/  Tel: (44)(0)1235-555511  Fax: (44)(0)1235-553301
           www.tessella.com
           Registered in England No. 1466429
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20030509/7b785f18/attachment.htm>


More information about the vtkusers mailing list