AffineTransform question

Hi

The method below draws a circle in the centre of a JPanel placed on a single JFrame.

    private void paintCircle_Test(Graphics2D g2)
    {
       Rectangle   panelBounds   = this.getBounds();   // identical to panel.getVisibleRect()
        int         panelTopLeftX = panelBounds.x;      // (0,0) since top left of panel and not top left of app frame
        int         panelTopLeftY = panelBounds.y;
        int         panelWidth    = panelBounds.width;
        int         panelHeight   = panelBounds.height;

        // circle
        double circleRadius = 250.0;
        double circleDiameter = 2.0 * circleRadius;
        java.awt.geom.Ellipse2D.Double jcircle = new java.awt.geom.Ellipse2D.Double(0,0,circleDiameter,circleDiameter);

        // save original transform
        AffineTransform origTransform = g2.getTransform();

        AffineTransform tx = AffineTransform.getTranslateInstance(panelWidth/2-circleRadius, panelHeight/2-circleRadius); // alternative static method of creating transform

        g2.setTransform(tx);

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,      RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2.setColor(Color.BLACK);
        g2.draw(jcircle);
        g2.fill(jcircle);
        // restore original transform
        g2.setTransform( origTransform );
    }

However, in my application I setup the following split station:

    private void setupStation()
    {
        mDockingStation = new SplitDockStation();

        // model tree
        mModelTreeDockable = new ColourDockable( "Model Tree", Color.RED, 2.5f );

        // 2d and 3d model views
        RenderPanel2D renderPanel2D = new RenderPanel2D("RenderPanel2D");
        renderPanel2D.mid = 5;
        mModel2DViewDockable = new ColourDockable(renderPanel2D, "Model 2D View", Color.YELLOW, 2.5f );
        JPanel renderPanel3D = new RenderPanel3D();
        mModel3DViewDockable = new ColourDockable(renderPanel3D, "Model 3D View", Color.CYAN, 2.5f );

        SplitDockGrid dockGrid = new SplitDockGrid();
        dockGrid.addDockable( 0, 0, 20, 100, mModelTreeDockable );
        dockGrid.setSelected( 0, 0, 20, 100, mModelTreeDockable );

        dockGrid.addDockable( 20, 0, 80, 100, mModel2DViewDockable, mModel3DViewDockable );
        dockGrid.setSelected( 20, 0, 80, 100, mModel2DViewDockable ); // note that (x,y,width,height) must match addDockable()

        mDockingStation.dropTree( dockGrid.toTree() );

        mDockingController.add( mDockingStation );
    }

If I attempt to use the method that draws a circle in the centre of one of my split station panels then it is not positioned correctly.

There’s clearly an offset that I’m not accounting for due to the left-hand split pane but I’m not sure how to correctly determine the offset.

Has anyone else encountered this problem?

Thanks for any help.

Graham

Hi again

If I use the Graphics2D of the panel itself then drawing to the panel is as expected and correctly positioned:

    private void paintCircle_Test(Graphics2D g2)
    {
        //...
        Graphics2D g2Panel = (Graphics2D)this.getGraphics();

        Graphics2D graphics = g2Panel;
        //...
        AffineTransform origTransform = graphics.getTransform();
    }

However, if I now use the panel Graphics2D instead of the one passed to the panel’s paintComponent() [which appears to the main frame Graphics] now I don’t see the panel shapes???

The only way I can get to see the panel shapes is by dragging the spline pane bar and when I release the bar the circle shape disappears.

This is the most confusing and frustrating thing!

Graham

This is not related to DockingFrames, but to false use of the Graphics2D-API. The problem is your call to “setTransform” which overrides the existing transformation. If you use “transform” instead, the existing and the new transformation get combined, and that is exactly what you need:

//        Remove this evil line...
//        g2.setTransform(tx);

//        ... and replace it with:
        g2.transform( tx );```

The way how setTransform should be used (if necessary) is also emphasized in the corresponding Doc: setTransform Documentation (namely it may be used to restore the initial transform after a sequence of changes)