[vtkusers] Java remove vtkImageViewer2 not working
Jim Peterson
jimcp at cox.net
Fri Dec 3 18:52:54 EST 2010
Jonathan,
I am really just a hobbiest programmer of vtk with Java, so if someone
more involved directly with imaging and the standard processes involved
wants to comment, you are welcome.
Are the slice orientations arbitrary or do they use the
setSliceOrientationxx methods? I think the general solution we are
arriving at is to expose the vtk components to a level that allows you
to interact with the vtk elements in your interaction methods rather
than swapping panels at the java level without any vtk interaction.
So instead of switching jpanels, you might set orientations or add
transforms to the vtk objects to achieve the desired result.
I hope that helps,
I think I am out of ideas...
Jim
Jonathan Morra wrote:
> Thanks for the response. Your solution of just switching the inputs
> to the vtkImageViewer2's did work, however I still have two
> outstanding problems.
> 1. In my application I have one vtkImageData, and three
> vtkImageViewer2's, each at a different orientation, so switching the
> inputs doesn't make sense (the inputs are all the same)
> 2. I also have a fourth window which has to be moved around as well
> which is composed of three vtkImagePlaneWidgets.
>
> Here is a method that I'm currently using to do the rotation,
> hopefully this'll make my situation more clear.
>
> public void rotateImagesCounterclockwise() {
> // In this example, all of the panel variables are JPanel's
> and all of the old Components are actually
> // an extension of JPanel that contains either a
> vtkImageViewer2 or a vtkImagePlane widget. Ideally,
> // I shouldn't be concerned with what the old panels are
> Component oldCenter = centerPanel.getComponent(0);
> Component oldUpperRight = upperRightPanel.getComponent(0);
> Component oldCenterRight = centerRightPanel.getComponent(0);
> Component oldBottomRight = bottomRightPanel.getComponent(0);
>
> centerPanel.remove(oldCenter);
> upperRightPanel.remove(oldUpperRight);
> centerRightPanel.remove(oldCenterRight);
> bottomRightPanel.remove(oldBottomRight);
>
> centerPanel.add(oldUpperRight, BorderLayout.CENTER, 0);
> upperRightPanel.add(oldCenterRight, BorderLayout.CENTER, 0);
> centerRightPanel.add(oldBottomRight, BorderLayout.CENTER, 0);
> bottomRightPanel.add(oldCenter, BorderLayout.CENTER, 0);
>
> validate();
> repaint();
> }
>
> Thoughts?
>
> On Fri, Dec 3, 2010 at 2:54 PM, Jim Peterson <jimcp at cox.net
> <mailto:jimcp at cox.net>> wrote:
>
> Jonathan,
> I am able to reproduce your problem, I made a minor change so that
> one image would be vertical lines and one horizontal, scrolling
> the image sizes as a test of the viewer interactor makes the two
> horizontal line images ambiguous. I still believe we are hitting
> the different interactor window for renderer problem. I believe a
> correct swap would need to be by switching the images being
> rendered, and leave the renderer associated with the frame it was
> created upon. You will notice that the top panel loses its data
> when you zoom. I believe this is the problem noted in this error
> message that would occur in a similar swap using C++:
>
>
> "Attempting to call MakeCurrent for a different
> window"
> " than the one doing the picking, this can causes
> crashes"
> " and/or bad pick results"
>
> My understanding is that the Viewer is an interactor with the
> render window, and my test does show bad pick resullts.
>
> I believe you are trying to simplify VTK Java beyond its limits,
> In all things we should make them as simple as possible, but no
> simpler. I think if you swap the input to the renderwindow instead
> of swapping the panels, you will achieve the same result without
> the vtk errors.
> Maybe Seb can provide some related insight in using the viewer
> approach in Java.
> Hope that helps,
> Jim
>
>
> Jonathan Morra wrote:
>
> I apologize for the length of this example (it's a little
> long), but it is totally self contained and shows my the error
> that I'm having. Please let me know if you need any more
> information, or the tweaks to make what I have work.
>
> import vtk.*;
> import javax.swing.*;
> import java.awt.event.*;
> import java.awt.*;
>
> public class VTKSwingError {
> static {
> System.loadLibrary("vtkCommonJava");
> System.loadLibrary("vtkFilteringJava");
> }
>
> static JPanel topPanel;
> static JPanel bottomPanel;
> static JFrame frame;
>
> // This is just creating two different images so we can
> tell when they're swapped
> public static JPanel createImagePanel(boolean useMod0) {
> vtkImageData image = new vtkImageData();
> image.SetSpacing(1, 1, 1);
> image.SetOrigin(0, 0, 0);
> image.SetExtent(0, 511, 0, 511, 0, 0);
> image.AllocateScalars();
> for (int x=0; x<512; x++) for (int y=0;
> y<512; y++) {
> if ((useMod0 && y%2 == 0) || (!useMod0 && y%2
> == 1))
> image.SetScalarComponentFromDouble(x, y, 0,
> 0, 1);
> }
> }
> vtkRenderWindowPanel renWin = new vtkRenderWindowPanel();
> renWin.setInteractorStyle(new vtkInteractorStyleImage());
> vtkImageViewer2 imageViewer = new vtkImageViewer2();
> imageViewer.SetInput(image);
> imageViewer.SetColorLevel(0.5);
> imageViewer.SetColorWindow(1);
> imageViewer.SetSliceOrientationToXY();
> imageViewer.SetSlice(1);
> imageViewer.SetRenderWindow(renWin.GetRenderWindow());
> imageViewer.GetRenderer().ResetCamera();
>
> JPanel renWinPanel = new JPanel(new BorderLayout());
> renWinPanel.add(renWin, BorderLayout.CENTER);
> return renWinPanel;
> }
>
> public static void main(String[] args) {
> topPanel = new JPanel(new BorderLayout());
> topPanel.setMinimumSize(new Dimension(400, 200));
> topPanel.setPreferredSize(new Dimension(400, 200));
> topPanel.add(createImagePanel(true), BorderLayout.CENTER);
>
> bottomPanel = new JPanel(new BorderLayout());
> bottomPanel.setMinimumSize(new Dimension(400, 200));
> bottomPanel.setPreferredSize(new Dimension(400, 200));
> bottomPanel.add(createImagePanel(false),
> BorderLayout.CENTER);
>
> JButton switchButton = new JButton("Switch Panels");
> switchButton.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> // This is where VTK is going haywire
> Component oldTop = topPanel.getComponent(0);
> Component oldBottom = bottomPanel.getComponent(0);
>
> topPanel.remove(oldTop);
> bottomPanel.remove(oldBottom);
>
> topPanel.add(oldBottom, BorderLayout.CENTER);
>
> bottomPanel.add(oldTop, BorderLayout.CENTER);
> frame.getContentPane().validate();
> frame.getContentPane().repaint();
> }
> });
>
> frame = new JFrame();
> frame.getContentPane().setLayout(new BorderLayout());
> frame.getContentPane().add(topPanel, BorderLayout.NORTH);
> frame.getContentPane().add(bottomPanel,
> BorderLayout.CENTER);
> frame.getContentPane().add(switchButton,
> BorderLayout.SOUTH);
> frame.setSize(400, 400);
> frame.setLocationRelativeTo(null);
> frame.setVisible(true);
> }
> }
>
>
> On Thu, Dec 2, 2010 at 8:10 PM, Jim Peterson <jimcp at cox.net
> <mailto:jimcp at cox.net> <mailto:jimcp at cox.net
> <mailto:jimcp at cox.net>>> wrote:
>
> Jonathan Morra wrote:
>
>
> I have a java swing JPanel that contains another JPanel
> that
> contains a vtkRenderWindowPanel which is hooked up to a
> vtkImageViewer2. In the course of my program I want to
> remove
> the inner JPanel from the outer JPanel with
> JPanel.remove(). I
> then want to add the inner JPanel to a different outer
> JPanel.
> However when I do this VTK throws the following exception
>
> ERROR: In
> ..\..\src\Rendering\vtkWin32OpenGLRenderWindow.cxx,
> line 247
> vtkWin32OpenGLRenderWindow (00000004C8E4830):
> wglMakeCurrent
> failed in MakeCurrent(), error: The handle is invalid.
>
> This seems like a very simple swing operation that I'm
> trying
> to do, but it's failing. Does anyone know what I'm
> doing wrong?
> Thanks
>
> Jonathan,
> you do understand that the vtk classes are JNI interfaces
> to the
> shared library version of vtk. I suspect you are causing
> Java to
> free resources that are still referenced by the memory
> instantiated by the still active structures outside Java in
> vtk.
> Without an example it is pretty hard to try to visualize
> the java
> and native system memory from your description. What you
> are doing
> might be sensible with all java objects, but when JNI
> objects are
> involved memory references may not be as clear as desired.
> are not
> always completely in sync.
> Chances are if you coded the same kind of operation in C++ the
> make current routine would have detected the different
> potential
> interaction source and issued this message: (from the
> MakeCurrent() function in vtkWin32OpenGLRenderWindow.Cxx)
>
> if(this->IsPicking && current)
> {
> vtkErrorMacro("Attempting to call MakeCurrent for a
> different
> window"
> " than the one doing the picking, this can
> causes crashes"
> " and/or bad pick results");
> }
>
> Unless you want to post an example, I would say "If it hurts,
> don't do that".
>
> Hope that helps,
> Jim
>
>
>
>
>
More information about the vtkusers
mailing list