This discussion is archived
14 Replies Latest reply: Mar 22, 2013 9:06 AM by KonradZuse RSS

Best way to MouseDrag multiple objects around a scene.

KonradZuse Explorer
Currently Being Moderated
So I am having a little trouble trying to drag 3 Box's in a scene.

Originally I had it set up where each was relocated to an x,y translated Z and set to a HWD. Then I figured I would, instead of the mouse click on the box itself, be in the root. From there I would look through all of the root.getChildren() then made that see if it contained the x,y position.


Then from knowing which of my root Children I clicked I did root.getChildren.get(current).setOnDragged to figure out which one was dragged.

The code itself worked except for finding which box I was on.

The issue I find is that I onyl have getX, getSceneX, and getScreenX. X, and SceneX produce the same value, and ScreenX is useless. I tried then to do event.getX() - root.getLayoutX() to make the contains function to work, but it wasn't working and would require me to change up more things. getLayoutX() was = 0 since I didn't set the root location, only the locations of the box's.

From there I kept wondering if there was a better way. Then I thought maybe to loop through every element in my root or in an arrayList(Which is what I used, but realized the root.getchildren should work like the original) but the problem is it keeps only registering the last one in the list, so it just loops and that's it.

So what I want to know is, what would be the best way to figure out what object I'm in?

Originally I use the contains(Swing) but Swing is different, and now especially since we can register mouseEvents to each node, shouldn't we know exactly which one we are on, just by looping through each of them? I figure that's easier than having to check every single mouse position contained within, especially if I have 10000 things to check?

Edited by: KonradZuse on Mar 18, 2013 8:05 PM
  • 1. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    I'm on a Mac, so I don't have access to the 3D shapes yet.

    As I understand it, the only way (currently) to move 3D shapes is to change their translateX, translateY, and translateZ properties. So you'll need to update those properties in response to the mouse events.

    I would strongly advocate for registering a mouse handler with each individual shape. This keeps the code a lot cleaner (no iterating through lists of child nodes, etc) and also makes it easy to turn the dragging on/off for a given shape.

    There are a ton of strategies: my preferred is to have a handler class that tracks the last known mouse position relative to something fixed (e.g. the Scene), and updates the translation for the shape when the mouse is dragged.

    Here's an example with 2D shapes. I think this will work with 3D shapes, though I have no way to test:
    import javafx.application.Application;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Polygon;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.event.EventHandler;
    
    public class DraggingShapes extends Application {
    
      @Override
      public void start(Stage primaryStage) {
        Pane root = new Pane();
        Circle circle = new Circle(100, Color.AQUAMARINE.deriveColor(0, 1, 1, 0.6));
        Rectangle rect = new Rectangle(200, 100, Color.CORAL.deriveColor(0, 1, 1, 0.6));
        Polygon triangle = new Polygon(-86.6, 150, 86.6, 150, 0, 0);
        triangle.setFill(Color.BLANCHEDALMOND.deriveColor(0, 1, 1, 0.6));
        circle.addEventHandler(MouseEvent.ANY, new DragShapeHandler());
        rect.addEventHandler(MouseEvent.ANY, new DragShapeHandler());
        triangle.addEventHandler(MouseEvent.ANY, new DragShapeHandler());
        translate(circle, 200, 200);
        translate(rect, 360, 100);
        translate(triangle, 280, 400);
        root.getChildren().addAll(circle, rect, triangle);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
      }
    
      private void translate(Node n, double x, double y) {
        n.setTranslateX(x);
        n.setTranslateY(y);
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    
      class DragShapeHandler implements EventHandler<MouseEvent> {
    
        private double sceneAnchorX;
        private double sceneAnchorY;
    
        @Override
        public void handle(MouseEvent event) {
          if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
            sceneAnchorX = event.getSceneX();
            sceneAnchorY = event.getSceneY();
          } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
            double x = event.getSceneX();
            double y = event.getSceneY();
            Node node = (Node) event.getSource();
            node.setTranslateX(node.getTranslateX() + x - sceneAnchorX);
            node.setTranslateY(node.getTranslateY() + y - sceneAnchorY);
            sceneAnchorX = x;
            sceneAnchorY = y;
          }
        }
      }
    }
  • 2. Re: Best way to MouseDrag multiple objects around a scene.
    shakir.gusaroff Expert
    Currently Being Moderated
    I slightly modified your code for 3D.
    - added a pointlight
    - added a phong material
    - the rectangle changed to a box
    - the circle changed to a sphere
    - add scene.setCamera(new PerspectiveCamera(false));
    Without the last line it is not working.
    I tested it with javafx8.0 build 80 Netbean7.3


    import javafx.application.Application;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Polygon;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.PerspectiveCamera;
    import javafx.scene.PointLight;
    import javafx.scene.paint.PhongMaterial;
    import javafx.scene.shape.Box;
    import javafx.scene.shape.DrawMode;
    import javafx.scene.shape.Sphere;
    
    public class DraggingShapes3D extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            PointLight pointLight = new PointLight(Color.ANTIQUEWHITE);     
            pointLight.setTranslateX(800);     
            pointLight.setTranslateY(-100);   
            pointLight.setTranslateZ(-1000); 
    
    
            PhongMaterial material = new PhongMaterial();
            material.setDiffuseColor(Color.LIGHTGRAY);
            material.setSpecularColor(Color.rgb(30, 30, 30));
           
            Box box = new Box(200, 200, 200);
            box.setMaterial(material); 
            box.setTranslateX(100);
            box.setTranslateY(100);
            box.setDrawMode(DrawMode.FILL); 
            
            
            box.addEventHandler(MouseEvent.ANY, new DragShapeHandler());
    
            Group root = new Group();
            
            Sphere sphere = new Sphere(100);
            sphere.setTranslateX(400);
            sphere.setTranslateY(100);
            sphere.setMaterial(material);
            sphere.addEventHandler(MouseEvent.ANY, new DragShapeHandler());
    
          
           
            root.getChildren().addAll(box, sphere);
             root.getChildren().addAll(pointLight);
            
            Scene scene = new Scene(root, 800, 800, true);
            scene.setCamera(new PerspectiveCamera(false)); 
            primaryStage.setScene(scene);
            primaryStage.show();
        }
       
        public static void main(String[] args) {
            launch(args);
        }
    
        class DragShapeHandler implements EventHandler<MouseEvent> {
    
            private double sceneAnchorX;
            private double sceneAnchorY;
    
            @Override
            public void handle(MouseEvent event) {
                if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
                    sceneAnchorX = event.getSceneX();
                    sceneAnchorY = event.getSceneY();
                } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                    double x = event.getSceneX();
                    double y = event.getSceneY();
                    Node node = (Node) event.getSource();
                    node.setTranslateX(node.getTranslateX() + x - sceneAnchorX);
                    node.setTranslateY(node.getTranslateY() + y - sceneAnchorY);
                    sceneAnchorX = x;
                    sceneAnchorY = y;
                }
            }
        }
    }
  • 3. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    Thanks for the help!


    I can currently drag a box, so there is no issue on that, just that I have multiple boxes and I need to be able to drag them each without knowing the total.

    I can have 1000 boxes, or 5 boxes, I cannot register a mouse event to each, so I figured I would loop through, then I realized after I posted this I could use the function "Mouse_ENTERED" or "Mouse_PRESSED" field and then move each individual, but that would still be looping through each one and then finding which is which.

    I do see your example below does make some sense.


    I never have seen sphere.addEventHandler(MouseEvent.ANY, new DragShapeHandler()); so thanks for that tip.

    It seems from that the "DragShapeHandler" basically will get the source node and then move it? So we really don't need to know which one.

    It makes alot of sense that you are making it a new node and just dragging it as such. so I could creater an array of Box's add them all, and I would only need to figure out the click point, to get the box, then it would know to drag it hmm...
  • 4. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    KonradZuse wrote:
    Thanks for the help!


    I can currently drag a box, so there is no issue on that, just that I have multiple boxes and I need to be able to drag them each without knowing the total.

    I can have 1000 boxes, or 5 boxes, I cannot register a mouse event to each,
    Why not?
    so I figured I would loop through, then I realized after I posted this I could use the function "Mouse_ENTERED" or "Mouse_PRESSED" field and then move each individual, but that would still be looping through each one and then finding which is which.

    I do see your example below does make some sense.


    I never have seen sphere.addEventHandler(MouseEvent.ANY, new DragShapeHandler()); so thanks for that tip.
    Buy you could also do
    DragShapeHandler handler = new DragShapeHandler();
    box.setOnMousePressed(handler);
    box.setOnMouseDragged(handler);
    if you prefer the convenience methods. (It's important you pass the same reference for both.)

    >
    It seems from that the "DragShapeHandler" basically will get the source node and then move it? So we really don't need to know which one.
    Correct-ish. It uses event.getSource() to figure out the source of the event (i.e. the node on which the event occurred). But you could just as well define a field in the DragShapeHandler class with the node that was to be moved:
      class DragShapeHandler implements EventHandler<MouseEvent> {
     
        private double sceneAnchorX;
        private double sceneAnchorY;
    
        private final Node nodeToMove ;
    
        DragShapeHandler(Node node) {
           this.nodeToMove = node ;
        } 
     
        @Override
        public void handle(MouseEvent event) {
          if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
            sceneAnchorX = event.getSceneX();
            sceneAnchorY = event.getSceneY();
          } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
            double x = event.getSceneX();
            double y = event.getSceneY();
            nodeToMove.setTranslateX(node.getTranslateX() + x - sceneAnchorX);
            nodeToMove.setTranslateY(node.getTranslateY() + y - sceneAnchorY);
            sceneAnchorX = x;
            sceneAnchorY = y;
          }
        }
      }
    and then:
    ...
    box.addEventHandler(MouseEvent.ANY, new DragShapeHandler(box));
    ...
    sphere.addEventHandler(MouseEvent.ANY, new DragShapeHandler(sphere));
    I marginally prefer the getSource(), I think, as the box.addEventHandler(..., new DragShapeHandler(box)); is a little unnatural. Arguably, though, that version is more robust (it's more typesafe as you are forced to specify a Node to drag, whereas the source of the event could in theory be any object).

    >
    It makes alot of sense that you are making it a new node and just dragging it as such. so I could creater an array of Box's add them all, and I would only need to figure out the click point, to get the box, then it would know to drag it hmm...
    You don't really need to "get the box", as above. Just register a handler with any node you want to be able to drag, and the handler will drag it.
  • 5. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    Sorry I didn't read your input at first, just what was spoken, so I meant to erase it. I figure I could loop through every box "when it's first created" or "during creation" to add the event handlers.


    The second part you said i'm not sure I need to do, since you seem to just use the handler itself, and not needing to add it to each by doing

    DragShapeHandler handler = new DragShapeHandler();
    box.setOnMousePressed(handler);
    box.setOnMouseDragged(handler)

    ??


    Yeah basically any node that is clicked I will know about,that's what I was looking for thanks so much!


    Yeah creating the dragHandler I think is the easiest step, because I don't want to be dragging random things. I also don't think anything is really "unnatural" as certain things require tweaks and changes from the original :), but yeah the box adding a box is funny :P.


    This code is very helpful in many ways, and I have learned a lot, thanks so much to everyone on OTN, I cannot stress enough how pleasant it is here, compared to some other sites....(ranch).

    Also just to make sure it should be
         nodeToMove.setTranslateX(nodeToMove.getTranslateX() + x - sceneAnchorX);
            nodeToMove.setTranslateY(nodeToMove.getTranslateY() + y - sceneAnchorY); 
    
    instead of 
    
            nodeToMove.setTranslateX(node.getTranslateX() + x - sceneAnchorX);
            nodeToMove.setTranslateY(node.getTranslateY() + y - sceneAnchorY);
    I found 1 issue that I'm trying to figure out now.

    Basically I have added some items into 1 group, then added the first group into another group, and set the event handle to the first group, as well as the contents of that group.

    f.addEventHandler(MouseEvent.ANY, new DragShapeHandler(f));
    e.addEventHandler(MouseEvent.ANY, new DragShapeHandler(e));
    c.addEventHandler(MouseEvent.ANY, new DragShapeHandler(c));

    shelf.setMaterial(blue);




    Group s1 = new Group (shelf,f,c,e);
    Group root = new Group(s1);
    s1.addEventHandler(MouseEvent.ANY, new DragShapeHandler(s1));

    What is happening is if I click on the s1 part it's fine, but if I click one of the box's everything moves, and the box moves at a rate twice as far.

    I just fixed this by doing shelf.addEventHandler(MouseEvent.ANY, new DragShapeHandler(s1)); seeing as I want to only grab the shelf, not any point within the group, so it worked out.

    But I might run into an issue later on, so I guess I will have to set it to only allow 1 node at a time (I guess 2 nodes were choosen and altered at the same time)


    Also I'm interesting in why you used the translate approach? I've seen normally you set the layout, but maybe in this case it's different, or maybe translating is better?
    Edited by: KonradZuse on Mar 20, 2013 5:01 PM

    Edited by: KonradZuse on Mar 20, 2013 5:04 PM

    Edited by: KonradZuse on Mar 20, 2013 5:42 PM

    Edited by: KonradZuse on Mar 20, 2013 6:05 PM
  • 6. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    This code is very helpful in many ways, and I have learned a lot, thanks so much to everyone on OTN, I cannot stress enough how pleasant it is here, compared to some other sites....(ranch).
    +1 to that.
    Also just to make sure it should be
         nodeToMove.setTranslateX(nodeToMove.getTranslateX() + x - sceneAnchorX);
    nodeToMove.setTranslateY(nodeToMove.getTranslateY() + y - sceneAnchorY); 
    
    instead of 
    
    nodeToMove.setTranslateX(node.getTranslateX() + x - sceneAnchorX);
    nodeToMove.setTranslateY(node.getTranslateY() + y - sceneAnchorY);
    Yes, sorry. Good catch.
  • 7. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    KonradZuse wrote:
    I found 1 issue that I'm trying to figure out now.

    Basically I have added some items into 1 group, then added the first group into another group, and set the event handle to the first group, as well as the contents of that group.

    f.addEventHandler(MouseEvent.ANY, new DragShapeHandler(f));
    e.addEventHandler(MouseEvent.ANY, new DragShapeHandler(e));
    c.addEventHandler(MouseEvent.ANY, new DragShapeHandler(c));

    shelf.setMaterial(blue);

    Group s1 = new Group (shelf,f,c,e);
    Group root = new Group(s1);
    s1.addEventHandler(MouseEvent.ANY, new DragShapeHandler(s1));

    What is happening is if I click on the s1 part it's fine, but if I click one of the box's everything moves, and the box moves at a rate twice as far.
    If you apply a translation to a Group, it effectively applies the translation to all elements of the group. Since the handler is registered with both the group and the box, it's applying the translation to the group (propagating it to it's children) and also to the box. So the box gets two translations.

    If you add the line
    event.consume();
    in the handler's handle(...) method, it will prevent the event from being handled by multiple nodes; and should be handled by the box only if you click on the box. (Change addEventHandler(...) to addEventFilter(...) and it will be handled only by the Group.) See the [url http://docs.oracle.com/javafx/2/events/jfxpub-events.htm]Event Handling tutorial, which is pretty good.
    Also I'm interesting in why you used the translate approach? I've seen normally you set the layout, but maybe in this case it's different, or maybe translating is better?
    Ah, no particularly good reason. I wasn't fully certain if layoutX and layoutY behaved as expected with Shape3D objects; I was pretty sure the translate properties did; and I had no way of testing.
  • 8. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    James_D wrote:
    KonradZuse wrote:
    I found 1 issue that I'm trying to figure out now.

    Basically I have added some items into 1 group, then added the first group into another group, and set the event handle to the first group, as well as the contents of that group.

    f.addEventHandler(MouseEvent.ANY, new DragShapeHandler(f));
    e.addEventHandler(MouseEvent.ANY, new DragShapeHandler(e));
    c.addEventHandler(MouseEvent.ANY, new DragShapeHandler(c));

    shelf.setMaterial(blue);

    Group s1 = new Group (shelf,f,c,e);
    Group root = new Group(s1);
    s1.addEventHandler(MouseEvent.ANY, new DragShapeHandler(s1));

    What is happening is if I click on the s1 part it's fine, but if I click one of the box's everything moves, and the box moves at a rate twice as far.
    If you apply a translation to a Group, it effectively applies the translation to all elements of the group. Since the handler is registered with both the group and the box, it's applying the translation to the group (propagating it to it's children) and also to the box. So the box gets two translations.

    If you add the line
    event.consume();
    in the handler's handle(...) method, it will prevent the event from being handled by multiple nodes; and should be handled by the box only if you click on the box. (Change addEventHandler(...) to addEventFilter(...) and it will be handled only by the Group.) See the [url http://docs.oracle.com/javafx/2/events/jfxpub-events.htm]Event Handling tutorial, which is pretty good.
    Also I'm interesting in why you used the translate approach? I've seen normally you set the layout, but maybe in this case it's different, or maybe translating is better?
    Ah, no particularly good reason. I wasn't fully certain if layoutX and layoutY behaved as expected with Shape3D objects; I was pretty sure the translate properties did; and I had no way of testing.
    Oh yeah I was going to ask what consume() meant, so all it does is "consume" the event after it's triggered, so it doesn't get used again? Anything else?

    Also not too sure what we are doing by changing it to Filter? That's to make sure it's used for the group? I'm confused.

    The code works fine if when I changed it to a shelf click, since I want the shelf to ONLY to be clickable to move everything, while the box's themselves are able to move by themselves with no problems, which wont move it all :).

    I will check out the tut, thanks, I appreciate it.

    Also yeah the setting of the layout works, I wish there was a layout Z tho >(. I guess it doesn't matter since there is translate, but still.....

    I'll keep the code as it is, since it works and you trust it :).

    Edited by: KonradZuse on Mar 21, 2013 1:20 PM
  • 9. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    Read [url http://docs.oracle.com/javafx/2/events/processing.htm]Processing Events, particularly the section "Event Delivery Process" onwards. Basically, an event is delivered from the Stage down the scene graph (parent to child) and passed to any EventFilters on the way. Then it is delivered back up the scene graph (child to parent), being passed to any EventHandlers on the way back. The consume() method basically terminates its propagation.

    So if you use EventHandlers, the box will receive it before the group. If you consume() the event, the group won't receive it.

    On the other hand, if you use EventFilters, the group will receive it before the box. If you consume() it in this case, the box won't receive it.
  • 10. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    Oh, I see what you meant, thanks!


    Also I am trying to mix in some KeyEvents now. I realized the DragHandler is just mouseEvents and I'm not sure if I could mix them both(you can only implement one interface at a time right)?

    So I was thinking maybe having a boolean field to signify both a key press and the mouse click? Basically if the press like shift or control, and then drag, I was to rotate not translate :).
  • 11. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    KonradZuse wrote:
    Oh, I see what you meant, thanks!
    You're welcome.

    >
    Also I am trying to mix in some KeyEvents now. I realized the DragHandler is just mouseEvents and I'm not sure if I could mix them both(you can only implement one interface at a time right)?
    For completeness, I'll answer these as stated, but note that below there's a much easier way to do what you want.

    You can register both a handler for mouse events and a handler for key events with the same node. Just use setOnMouseDragged(...) and setOnKeyPressed(...). If you like, you can actually write a class that implements both:
    class DragShapeHandler implements EventHandler<Event> {
      @Override
      public void handle(Event event) {
        if (event.getType() == MouseEvent.MOUSE_DRAGGED) {
         // ...
        } else if (event.getType() == KeyEvent.KEY_PRESSED) {
         // ...
        }
      }
    }
    Then you could do
    DragShapeHandler dragHandler = new DragShapeHandler();
    box.setOnMousePresseD(dragHandler);
    box.setOnMouseDragged(dragHandler);
    box.setOnKeyPressed(dragHandler);
    but I don't think you need to do any of this...
    So I was thinking maybe having a boolean field to signify both a key press and the mouse click? Basically if the press like shift or control, and then drag, I was to rotate not translate :).
    The MouseEvent has methods to detect if the modifier keys are pressed. So you can just use the drag handler as before and do
    class DragShapeHandler implements EventHandler<MouseEvent> {
     
      @Override
      public void handle(MouseEvent event) {
        // ...
        if (event.getType() == MouseEvent.MOUSE_DRAGGED) {
          if (event.isShiftDown()) {
            // rotate
          } else {
            // translate
          }
        }
      }
    }
    There are also methods isControlDown(), isAltDown(), isMetaDown(), isShortcutDown(). The last one is the "shortcut" key, which is the control key on Windows and the command (meta) key on Mac.
  • 12. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    You're the man, not only do you answer the question stated, but give multiple answers :D.

    I did notice "isShiftDown" and such after posting this, but the javadoc was broken >(.

    so we couldn't do what we had before

    >
    box.addEventHandler(MouseEvent.any, dragHandler);
    box.addEventHandler(KeyEvent.any, dragHandler);
    >


    I also did notice about the implementation of EventHandler, except I had to have something inside <>, which I didn't think about "Event" itself :P.


    Well I do appreciate both, because I might need to use other keys besides alt, shift, and control, but I doubt it, since that's plenty :).



    Thanks again for everything!

    One last thing and I'll stop bothering you :P


    from the Sphere and Box example
      scene.setOnMousePressed((MouseEvent event) -> {
                anchorX = event.getSceneX();
                anchorY = event.getSceneY();
                anchorAngle = parent.getRotate();
                System.out.println(parent.getRotate());
            });
     
            scene.setOnMouseDragged((MouseEvent event) -> {
                parent.setRotate(anchorAngle + anchorX -  event.getSceneX());
    
                        parent.setRotationAxis(Rotate.X_AXIS);
    
            });
    They use the xAxis to rotate, but I want to be able to rotate at any angle.

    Originally when I would edit this code it seemed like both pieces were needed, and I'm not sure why it would be.

    The Axis seems like it's only going to be on X, Y, or Z, and then the Rotation is based on the point at which we are rotating around?

    Is there a way I can rotate at any angle, or for now it's just X, Y, and Z?

    Edited by: KonradZuse on Mar 21, 2013 6:23 PM
  • 13. Re: Best way to MouseDrag multiple objects around a scene.
    James_D Guru
    Currently Being Moderated
    setRotate(..) will set the angle of rotation about any axis. The axis is defined by setRotationAxis(...). The setRotationAxis(...) takes a Point3D object which defines a 3D vector through the center of the Node (so the pivot point is fixed at the center of the Node). So you can do setRotationAxis(new Point3D(x, y, z)); to rotate about an arbitrary axis.

    If you want a pivot point other than the center of the node, you can do
    Rotate rotate = new Rotate();
    rotate.setPivotX(...);
    rotate.setPivotY(...);
    rotate.setPivotX(...);
    rotate.setAxis(new Point3D(...));
    rotate.setAngle(...);
    node.getTransforms().add(rotate);
    You can then update the angle of rotation with rotate.setAngle(...) at any time. (Or similarly for any of the other properties.).
  • 14. Re: Best way to MouseDrag multiple objects around a scene.
    KonradZuse Explorer
    Currently Being Moderated
    Actually, not that I think about it, I think I asked this question once, and i believe JSmith said I would have to also manipulate the camera? It doesn't seem like that would be the same.

    Also is setRotate() and rotate.setAngle() the same thing?



    I think all I really need to do is have the rotation axis set as x and y, and when switching the "angle" all I would need to do is specify x and y +/-

    I got this to work someish.
     scene.setOnMousePressed((MouseEvent event) -> {
                anchorX = event.getSceneX();
                anchorY = event.getSceneY();
                anchorAngle = parent.getRotate();
                System.out.println(parent.getRotate());
            });
     
            scene.setOnMouseDragged((MouseEvent event) ->
            {
                        
    
                    parent.setRotationAxis(new Point3D(anchorX,anchorY,0));
                    parent.setRotate(anchorAngle+ anchorY -  event.getSceneY());
                 //   parent.setRotate(anchorAngle+ anchorX -  event.getSceneX());
                    
                    System.out.println(parent.getRotate() + "anchor x");
    
                            anchorX = event.getSceneX();
                anchorY = event.getSceneY();
                  //      parent.setRotationAxis(new Point3D(anchorX,anchorY,0));
                        
    anchorAngle = parent.getRotate();
            });
    It can rotate around if I want, except it doesn't rotate" correctly" Basically if I movie it left, it wont go left, etc, but if I move the mouse int he right way, it will move around.

    Edited by: KonradZuse on Mar 22, 2013 9:05 AM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points