Title: RE: Please help with repaint problem..

Hello -

I'm sorry..I did respond with two attached images.  I will try and send them seperately from this email (perhaps its a firewall issue).  Thanks for the response.


B> I'm building an SVG WYSIWYG editor using batik 1.5 with the jdk
B> 1.3. 

   Which Batik 1.5?  Beta 1, 2, or 3?

   If it's not '3' please upgrade.

It's Beta 3.

B> The user drags SVG shapes onto an SVGCanvas, and can drag, rotate,
B> and scale the shapes.  The code's pretty simple -

B>                     if(selectionManager.isSelected(controlNode))
B> selectionManager.positionSelectionBox(controlNode);

   This is interesting.  How does the selectionManager draw it's
selection box?

The selectionManager draws the selection box through SVG.  It adds a <rect> tag to the SVG and positions it
and resizes it according to the size of the shape.

Here's the code that positions the selection box:

public void positionSelectionBox(Element selectedNode) {
       
        final Element selectionNode = (Element)selectedControls.get(selectedNode);
        if(selectionNode == null)
            return;
    
        // Transforms this selection box:
        PositionManager positionManager = svgCanvas.getPositionManager();
        AffineTransform selectedTranslate = positionManager.getTranslation(selectedNode);
        positionManager.setTranslation(selectionNode, AffineTransform.getTranslateInstance(selectedTranslate.getTranslateX() - 3, selectedTranslate.getTranslateY() - 3));

       
        // Updates the rotation matrix for this selected node
        double angle = positionManager.getAngle(selectedNode);
        AffineTransform selectedScale   = positionManager.getScale(selectedNode);
        String controlName              = selectedNode.getAttribute(ATTR_ID);
        Control selectedControl         = svgCanvas.getIDManager().getControlForID(controlName);
        Dimension selectedNodeBounds    = selectedControl.getControlSize();
       
        // Calculates the origin of the seleciton box:
        double selectionWidth   = selectedNodeBounds.getWidth()  * selectedScale.getScaleX();
        double selectionHeight  = selectedNodeBounds.getHeight() * selectedScale.getScaleY();
        double selectionOriginX = selectionWidth / 2;
        double selectionOriginY = selectionHeight / 2;
       
        AffineTransform selectionRotation = AffineTransform.getRotateInstance(angle, selectionOriginX + 3, selectionOriginY + 3);

        positionManager.setRotation(selectionNode, selectionRotation);
       
        // Now we resize the selection box by calling javascript:
        String selectionControlName = selectionControl.getControlName();
        String selectionNodeID      = selectionNode.getAttribute(ATTR_ID);
       
        // Now we need to generate the location and the size of the selection box:
        String resizeCommand      = "update('" + selectionControlName + "', '" + selectionNodeID + "', '" + (selectionWidth + 6) + "', '" + (selectionHeight + 6) + "')";

        Interpreter interpreter   = svgCanvas.getBridgeContext().getInterpreter(SVG_SCRIPT_TYPE_ECMASCRIPT);
       
        // Try to set the control selection box's shape:
        try {
            PinpointControlUtils.setTransform(selectionNode, positionManager.buildMatrix(selectionNode));
            interpreter.evaluate(resizeCommand);
        }
        catch(Exception e) {
            System.out.println("Error resizing the selection box!");
            e.printStackTrace();
        }
       
    }

The selection boxes are positions through java (by setting the transform) and resized through javascript...one of the important aspects of the program is that we dynamically append javascript functions to the SVG and call them from the program.

                   
B>   public static void setTransform(Element controlNode,
B>                                   AffineTransform transform) {
        [...]
B>     controlNode.setAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE,
B>      matrixTransform);
       
     Just as an FYI, I do this all the time through ECMA script.  So
there is something else that is effecting behaviour.  One thing just
occured to me, does this stuff have filters?  We don't properly
account for filters in our bounds calculations right now.


No I'm not using any filters.


B> This is the code that gets called when I want to move a shape
B> around on the canvas...it works, but it seems to me that there's an
B> error with the dirty rect caclulations, because when the canvas
B> gets repainted, I see little splotches of the shapes all around the
B> canvas.  I don't know what's going on.  The problem only occurs
B> when repaint is called.

   Sure, but repaint being called is very common, as it happens when
ever another window damages part of the Java window, or when the
window is resized.  Even when you pan in the Canvas it is redrawing
the entire offscreen buffer.  None of these cause the dirty bits to be
displayed in straight Squiggle. 

   Are you using Double Buffered rendering or single buffered (if you
don't do anything, by default JSVGCanvas has double buffering off).


Well this is why it's such a huge problem =)!  These canvas's are inside JInternalFrames,
and every time the user clicks on another frame the other frames get repainted and you see
the problem.

I have found a temporary solution..but it's certainly not how I'd like to do it:

        public void mouseReleased(MouseEvent e) {
           
           if(renderer != null && isDragging) {
               
                final int width                 = (int)getBounds().getWidth();
                final int height                = (int)getBounds().getHeight();
                final PinpointSVGCanvas canvas  = this;
                final ImageRenderer renderer    = this.renderer;
               
                // Put this at the end of the queue so that we repaint when the dragging is done!
                UpdateManager updateManager = bridgeContext.getUpdateManager();
            RunnableQueue runnableQueue = updateManager.getUpdateRunnableQueue();
            try {
                runnableQueue.invokeLater(new Runnable() {
                    public void run() {
                        renderer.clearOffScreen();
                        renderer.repaint(new Rectangle(0, 0, width, height));
                        canvas.repaint();
                    }
                });
            }
            catch(Exception exc) {
                System.err.println("Error repainting image!");
                exc.printStackTrace();
            }
           
            }
        }

This works alright, but if repaint is called before the dragging is done, the damaged image is displayed until
the queue reaches this Runnable.



B> Somebody suggested that perhaps its a size issue, but I am setting
B> the dimension of the SVG to be more than large enough.  While
B> debugging, I've proven that it's the renderer.getOffScreen() that's
B> causing the problem.  This is the image that's all jumbled
B> up....before repaint is called, I'm assuming the rendering system
B> is only updating the part of the screen that's been changed..but
B> the underlying buffer is not repainted properly.

   If you are using single buffer it generally is not a good idea to
just call renderer.getOffScreen() as you are likely to get the buffer
in the middle of a rendering request (which will have some dirty bits
in it although they should only one frames worth of dirty bits, you
seem to be describing more than that).

Well in the constructor I am calling

setDoubleBuffered(true);
setDoubleBufferedRendering(true);

So unless those aren't working the system should be double buffered.

B> Please, I'd appreciate any suggestions or help anybody can offer
B> me.  I've spent a significant amount of time trying to fix this and
B> haven't made any progress.

   As I pointed out in my other message most of what you have
described is done all the time without the side effects you have. So
to help you we need to know more about your code.  In particular I'd
be curious to know more about your selectionManager.  Does it plug
into Batik's overlay framework?  Is it another SVG element that is
moved around (if so how? are filters involved?)

The SelectionManager is another SVG element that is moved around, but filters are not involved.  It's just an SVG document that's plugged in:

<svg width="50" height="50">
        <g id="Selection">                     
                <rect id="nwRotate" x="-8" y="-8" width="16" height="16" style="fill: red; fill-opacity: 0;" />
                <rect id="swRotate" x="-8" y="42" width="16" height="16" style="fill: red; fill-opacity: 0;" />
                <rect id="neRotate" x="42" y="-8" width="16" height="16" style="fill: red; fill-opacity: 0;" />
                <rect id="seRotate" x="42" y="42" width="16" height="16" style="fill: red; fill-opacity: 0;" />
                <rect id="mainRect" x="0" y="0" width="50" height="50" style="fill: none; stroke: black; stroke-width: 2;" />

                <rect id="nwBox" x="-2" y="-2" width="5" height="5" style="fill: black;" />
                <rect id="wBox" x="-2" y="22" width="5" height="5" style="fill: black;" />
                <rect id="swBox" x="-2" y="48" width="5" height="5" style="fill: black;" />
                <rect id="nBox" x="22" y="-2" width="5" height="5" style="fill: black;" />
                <rect id="sBox" x="22" y="48" width="5" height="5" style="fill: black;" />
                <rect id="neBox" x="48" y="-2" width="5" height="5" style="fill: black;" />
                <rect id="eBox" x="48" y="22" width="5" height="5" style="fill: black;" />
                <rect id="seBox" x="48" y="48" width="5" height="5" style="fill: black;" />
        </g>
</svg>

But the error occurs when I use the selection manager and when I don't.  So I don't think that's the problem.

Thanks again..I'll try and send  the image in a seperate email since it didn't work last time.

- Mike Braude

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
------------------------------------------------------------------------------------------------------------------------------------------------------------

Notice: This e-mail message, together with any attachments, contains information of Andover Controls Corporation and or Andover Controls LTD. which may be confidential, proprietary, copyrighted and/or legally privileged. This Email is intended solely for the use of the individual or entity named on the message. If you are not the intended recipient, and have received this message in error, please immediately return this by e-mail and then delete it.

==============================================================================


Reply via email to