[vtkusers] Java remove vtkImageViewer2 not working

Jonathan Morra jonmorra at gmail.com
Fri Dec 3 18:28:46 EST 2010


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> 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>> 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
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20101203/30ae77d7/attachment.htm>


More information about the vtkusers mailing list