This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 173997 - Wiget has wrong location after resize
Summary: Wiget has wrong location after resize
Status: NEW
Alias: None
Product: platform
Classification: Unclassified
Component: Graph (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: issues@platform
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-10-07 16:57 UTC by runa
Modified: 2010-04-01 14:50 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Project Attached (522.84 KB, application/x-compressed)
2009-10-07 16:58 UTC, runa
Details
Video file (5.92 MB, application/x-compressed)
2009-10-07 16:59 UTC, runa
Details
Screendump (4.46 KB, text/plain)
2009-10-07 17:00 UTC, runa
Details

Note You need to log in before you can comment on or make changes to this bug.
Description runa 2009-10-07 16:57:37 UTC
Entering this for external customer from the Sun Developer Expert Assistance
program:

I need to be able to move & resize the green square and ask for the coordinates of this widget while and after it has
been moved or resized as I need to do further coordinate transformation into a different domain.

To test what is going on I write out the value of the widget.getLocation() before the move and after the move. One test
I do is to move the widget to the upper left corner where I know the coordinates returned must be 0,0. THIS WORKS. (see
screendump below where I have moved the widget to the upper left corner and the coordinates returned after move action
is 0,0 which is correct.

Now, move the widget back and now try to resize the widget using the top left resize button and resize the upper left
corner of the widget to fit the upper left corner of the Scene. I use the Resize Strategy to be able to track the
coordinates while resizing and the ResizeProvider to get the final coordinates after resizing is finish. If you look at
the screendump you will see that the coordinates returned from the resized widget after resizing are the SAME as the one
before resizing - which is the problem ! I.e. if you resize with for example upper left corner and than ask the widget
for its widget.getLocation() you do not get the correct coordinates.

You can see I write out the temporary coordinates while resizing and when converting to Scence coordinates they are
correct. But, when I reach the resizingFinished() method the coordinates written out are the same as the start
coordinate before resizing was initiated. 

If I move the Widget to the upper left corner and after than resize it using the lower right Resize button I get the
same result as you do (as the widget even after resize is not chaning it's location (defined as the upper left croner)).
But - the problem is, when using the upper left resize button the problem with the final location is happening.


a) Location is OK when resizing using lower right resize button

b) Location stays the same when using upper left resize button - NOT ok. In the screendump the start and finish
location is the same. Attached the screendump.

Please go to http://forums.netbeans.org/topic18097.html which describes the problem and has screendumps and a fully
functional code sniplet showing the problem.

Attached the Project and Avi video of what we do to make sure we operate it in the same way
Comment 1 runa 2009-10-07 16:58:42 UTC
Created attachment 89036 [details]
Project Attached
Comment 2 runa 2009-10-07 16:59:36 UTC
Created attachment 89037 [details]
Video file
Comment 3 runa 2009-10-07 17:00:42 UTC
Created attachment 89038 [details]
Screendump
Comment 4 bruehlicke 2009-10-14 15:28:05 UTC
Getting more and more confused.

replacing the line   widget.setPreferredSize(new Dimension(100,100));   with the line  widget.setPreferredBounds(new
Rectangle(50, 50, 100, 100));  in the "attachedNodeWidget" method in the attached demo NB project will result in that
the Move action is now showing the netgative move in pixels instead of the expected 0,0.

I tried to debug into the Visual API MoveAction and realized that the reason for this is that the drahSceneLocation is
getting wrong in the mousePressed method. The value of this is dependent on the size of the insets ! I.e. if I sleetc a
resize border with size 10 and press the mouse in the very top left corner of my widget which has location 50, 50 it is
returning 60,60 as event.getPoint() !!  As the widget is in a mainLayer and the mainLayer has same coordinate space as
the Scene the local coordinates in the mainLayer correspond to the Scene coordinates.

.... hmmm .... total confusion ....
Comment 5 bruehlicke 2009-10-16 05:19:51 UTC
After some debugging I have the following workaround

1) When creating the Widget use setPreferredBounds(new Rectangle(0,0,100,100));
2) When asking for the Coordinates after resize use widget.getPreferredBounds and convert this to Scene coordinates.
Then get the x and y of the converted Bounds - they will be correct

The coordinates returned are the outside coordinates of the Widgets including the insets.

It is still a mystery for me that the getPreferredLocation and that guy converted to Scene coordinates is not giving the
needed coordinates. So the rule here is: stick to the preferredBounds.

The code below will consistently print out the expected coordinates in the Scene coordinate system. 

B-)




package demos;

import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.MoveProvider;
import org.netbeans.api.visual.action.MoveStrategy;
import org.netbeans.api.visual.action.ResizeProvider;
import org.netbeans.api.visual.action.ResizeProvider.ControlPoint;
import org.netbeans.api.visual.action.ResizeStrategy;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.border.Border;
import org.netbeans.api.visual.border.BorderFactory;
import org.netbeans.api.visual.model.ObjectScene;
import org.netbeans.api.visual.widget.ImageWidget;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Widget;


public class ResizeCoordObjectScene3 extends ObjectScene {

    private ImageWidget imageLayer;
    private Image img;
    private LayerWidget _mainLayer;
    private Border _resizeBorder = BorderFactory.createResizeBorder(10, Color.GREEN, false);  // true => Resize squares
inside the widget
    private MoveStrategy moveStrategy = new MultiMoveProvider();
    private WidgetAction moveAction = ActionFactory.createMoveAction(moveStrategy, new MultiMoveProvider());
    private ResizeStrategy strategy = new MultiResizeStrategy();
    private ResizeProvider provider = new MultiResizeProvider();
    private WidgetAction resizeAction = ActionFactory.createResizeAction(strategy, provider);
    private ArrayList<Widget> widgetList = new ArrayList();

    public ResizeCoordObjectScene3() {

        img = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
        imageLayer = new ImageWidget(this, img);
        imageLayer.setPreferredLocation(new Point(0, 0));
        addChild(imageLayer);
        validate();

        _mainLayer = new LayerWidget(this);
        _mainLayer.setCheckClipping(true);
        _mainLayer.setPreferredBounds(new Rectangle(0, 0, img.getWidth(null), img.getHeight(null)));
        addChild(_mainLayer);

        attachNodeWidget("Box").setPreferredLocation(new Point(50, 50));
        validate();


    }

    protected Widget attachNodeWidget(String node) {
        Widget widget = new Widget(this);
        widget.setOpaque(false);
        _mainLayer.addChild(widget);
        widget.setOpaque(false);
        widget.setBorder(_resizeBorder);
//        widget.setPreferredSize(new Dimension(100, 100));
        widget.setPreferredBounds(new Rectangle(0,0,100,100));
        widget.setVisible(true);
        widget.getActions().addAction(resizeAction);
        widget.getActions().addAction(moveAction);
        widgetList.add(widget);

        return widget;
    }

    private class MultiResizeStrategy implements ResizeStrategy {

        public Rectangle boundsSuggested(Widget widget, Rectangle originalBounds, Rectangle suggestedBounds,
ControlPoint controlPoint) {

            suggestedBounds = widget.convertLocalToScene(suggestedBounds);

            Point suggestedLocation = null;
            suggestedLocation = new Point(suggestedBounds.x, suggestedBounds.y);
            System.out.println("Resizing Location : " + suggestedLocation+ " Hash = "+widget.hashCode());
          
            suggestedBounds = widget.convertSceneToLocal (suggestedBounds);
            
            return suggestedBounds;
        }
    }

    private class MultiResizeProvider implements ResizeProvider {

        public void resizingStarted(Widget widget) {
            System.out.println("Resize finish PrefBounds   Scene:
"+widget.convertLocalToScene(widget.getPreferredBounds()));
        }

        public void resizingFinished(Widget widget) {
            System.out.println("Resize finish PrefBounds   Scene:
"+widget.convertLocalToScene(widget.getPreferredBounds()));

        }
    }

    private class MultiMoveProvider implements MoveProvider, MoveStrategy {

        private Point original;

        public void movementStarted(Widget widget) {
            System.out.println("Move start Location: "+widget.convertLocalToScene(widget.getPreferredBounds()));
        }

        public void movementFinished(Widget widget) {
            ResizeCoordObjectScene3.this.validate();
//            System.out.println("Move finish PrefLocati   Scene :
"+widget.convertLocalToScene(widget.getPreferredLocation()));
            System.out.println("Move finish PrefBounds   Scene : "+widget.convertLocalToScene(widget.getPreferredBounds()));
//            System.out.println("Move finish PrefBounds   Local : "+widget.getPreferredBounds());
            original = null;
        }

        public Point getOriginalLocation(Widget widget) {
            original = widget.getPreferredLocation();
            return original;
        }

        public void setNewLocation(Widget widget, Point location) {
            // location is in Scene coordinates
            System.out.println("Calling setNewLocation Point = "+location);
            widget.setPreferredLocation(location);
        }

        public Point locationSuggested(Widget widget, Point originalPoint, Point suggested) {
            System.out.println("Move locationSuggested orig: "+originalPoint + ", suggested Scene : "+ suggested);
            return suggested;
        }
    }

    public static void main(String[] args) {
        SceneSupport.show(new ResizeCoordObjectScene3());
    }
}