You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by snapper <jc...@snapdragonmedical.com> on 2007/04/26 22:58:58 UTC

JSVGScrollPane.resizeScrollBars() 2 bugs and 1 fix

I am reporting 2 bugs related to batik scrollbars in batik 1.6 and also in
1.7.

Scrollbar Bug #1. RecenterOnResize timing error.
-----------------------------------------------
2 different event listeners run when you resize.

JSVGScrollPane.ScrollListener.componentResized() runs first.
This is when the scrollbar visibility and position is calculated.

JGVTComponent.componentResized() runs second.
This is when the RecenterOnResize code executes.

The problem occurs because the scrollbars are calculated correctly (almost
correctly, see Scrollbar Bug #2 below)
when the first listener runs.
But when the recenter code runs from the second listener, the scrollbar
calculations become incorrect.
In other words, perhaps if the code from these two listeners were executed
in reverse order, then the scrollbars would be correct.

This bug causes some wierd behavior in the scrollbars. For example, at a
particular window size and canvas size and document size and scale,
the horizontal scrollbar will appear to toggle on and off with each click on
the vertical scrollbar.
The doc will scale up and down slightly as each time the horizontal
scrollbar appears or disappears to account for the different avail height.
The result is "absolutely unacceptable" UI for production release.

The fix for us right now is to never user the RecenterOnResize true.

The other issue with RencenterOnResize is that it changes the scale (zoom)
factor depending on the size of the window.
That is not a bug but it does make a big difference to the user when they
resize.
We are thinking the user does not want a scale change when they resize the
window.


Scrollbar Bug #2. Scrollbar appears when not required.
------------------------------------------------------
At some window sizes, after a resize, the horizontal scrollbar will appear
when not needed.
This is predictable and repeatable.
Resize the window until it does not need a scrollbar, and then slowly resize
smaller in several steps.
When you get close the size where a scrollbar is needed, the scrollbar will
appear too soon.
When you click on the scrollbar, it quickly disappears, as if to say "Oops,
I did not mean to be there.. You didn't see that!"
Also you can get a horizontal scrollbar that appears after resizing to very
large, when it does not need to be there.
It also quickly disappears when clicked on.

The fix for this bug is to remove the section of code that modifies the maxW
and maxH in
JSVGScrollPane.resizeScrollBars().

I can't see why the author coded the change to maxW and maxH which are the
page dimensions of the svg.
I removed these changes so the maxW and maxH are unchanged and the bug is
fixed.
Using this new fix, the scrollbars have never appeared when not required,
and no other problems were noticed.

Here is the exact code I used in the fixed method:

    /**
     * Overrides the batik method to fix a bug where the horizontal
scrollbar
     * appears when not necessary after the window is resized. 
     */
    protected void resizeScrollBars()
    {
        ignoreScrollChange = true;

        checkAndSetViewBoxRect();
        if (viewBox == null) return;

        AffineTransform vbt = canvas.getViewBoxTransform();
        if (vbt == null) vbt = new AffineTransform();

        Rectangle r2d = vbt.createTransformedShape(viewBox).getBounds();

        // compute translation
        int maxW = r2d.width;
        int maxH = r2d.height;
        int tx = 0, ty = 0;

        //CHANGED THIS PART so no change to maxW or maxH ever.
        //If x is negative then set the x translation to that amount as a
positive.
        //If x is positive then ignore it.
        //Same for y.
        if(r2d.x<0)
        	tx-=r2d.x;
        if(r2d.y<0)
        	ty-=r2d.y;
        
        vertical.setValue(ty);
        horizontal.setValue(tx);

//        System.out.println("------------------------");
//        System.out.println("canvas w="+canvas.getWidth());
//        System.out.println("page   w="+maxW);
//        System.out.println("canvas h="+canvas.getHeight());
//        System.out.println("page   h="+maxH);
        
        // Changing scrollbar visibility may change the
        // canvas's dimensions so get the end result.
        Dimension vpSize = updateScrollbarVisibility
            (tx, ty, maxW, maxH);

        // set scroll params
        vertical.  setValues(ty, vpSize.height, 0, maxH);
        horizontal.setValues(tx, vpSize.width,  0, maxW);
		
        // set block scroll; this should be equal to a full 'page', 
        // minus a small amount to keep a portion in view
        // that small amount is 10%.
        vertical.  setBlockIncrement( (int) (0.9f * vpSize.height) );
        horizontal.setBlockIncrement( (int) (0.9f * vpSize.width) );
		
        // set unit scroll. This is arbitrary, but we define
        // it to be 20% of the current viewport. 
        vertical.  setUnitIncrement( (int) (0.2f * vpSize.height) );
        horizontal.setUnitIncrement( (int) (0.2f * vpSize.width) );
		
        ignoreScrollChange = false;
    }


I could probably find a fix for the first bug, but my time is often limited,
so I am content for now to simply never use RencenterOnResize.

I welcome comments or corrections to these findings.

-- 
View this message in context: http://www.nabble.com/JSVGScrollPane.resizeScrollBars%28%29-2-bugs-and-1-fix-tf3654168.html#a10208703
Sent from the Batik - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org