2

我正在尝试在 javafx 中对我的节点进行平移/缩放鼠标操作

对于那些知道它的人来说,行为应与 CATIA V5 中的一样:
- 按下中间按钮,您将“平移”,视图将跟随您的移动
- 按住中间按钮,按下第三个按钮,您将“旋转” "(此处未使用,在 3D 中有用)
- 按住中间按钮,松开第三个按钮,您将“ZOOMING”,上下移动时视图会放大和缩小

不幸的是,一旦我进入 ZOOMING 状态,javafx 似乎不再触发 MouseDragged 或 MouveMoved。

好像第三个按钮释放对触发的事件有影响。

这是我的代码:
缩放功能会影响我的“ViewTab”中的“contentGroup”一个小状态“manipulationState”确保行为之间的切换

我可以进入 ZOOM 状态,但是在鼠标移动时,既不调用onMouseDragged也不onMouseMoved调用。因此moveZoom()永远不会被调用。

有没有办法在 mousemove 上获取事件?谢谢你的帮助。

import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.control.Tab;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;


public class ViewTab extends Tab {

    private final double ZOOMFACTOR = 1;
    double contentGroupScale = 1.0;
    double pressedContentGroupScale;
    private double pressedX, pressedY, initialX, initialY;
    private Group contentGroup;

    private enum ManipulationState {

        IDLE, PAN, ROTATE, ZOOM
    }
    private ManipulationState manipulationState;

    ViewTab() {
        TitleNode rootNode = Tools.loadTree();
        //create view
        AbstractView rootView = OakweaverPresenterFactory.createView(rootNode, null);
        setText("Tree");
        contentGroup = new Group();
        contentGroup.getChildren().add(rootView);
        createZoomFunctions();

        setContent(contentGroup);
    }

    public void createZoomFunctions() {
        enterIdle();
        contentGroup.setScaleX(contentGroupScale);
        contentGroup.setScaleY(contentGroupScale);

        contentGroup.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                switch (manipulationState) {
                    case IDLE:
                        if (event.getButton() == MouseButton.MIDDLE) {
                            enterPan(event);
                        }
                        break;
                    case PAN:
                        if (event.getButton() == MouseButton.SECONDARY) {
                            enterRotate(event);
                        }
                        break;
                    case ROTATE:

                        break;
                    case ZOOM:
                        if (event.getButton() == MouseButton.SECONDARY) {
                            enterRotate(event);
                        }
                        break;
                }
            }
        });

        contentGroup.setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                switch (manipulationState) {
                    case IDLE:

                        break;
                    case PAN:
                        if (event.getButton() == MouseButton.MIDDLE) {
                            enterIdle();
                        }

                        break;
                    case ROTATE:
                        if (event.getButton() == MouseButton.MIDDLE) {
                            enterIdle();
                        }
                        if (event.getButton() == MouseButton.SECONDARY) {
                            enterZoom(event);
                        }
                        break;
                    case ZOOM:
                        if (event.getButton() == MouseButton.MIDDLE) {
                            enterIdle();
                        }
                        break;
                }

            }
        });

        contentGroup.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                System.out.println("draged");

                switch (manipulationState) {
                    case IDLE:
                        break;
                    case PAN:
                        movePan(event);
                        break;
                    case ROTATE:
                        moveRotate(event);
                        break;
                    case ZOOM:
                        moveZoom(event);
                        break;
                }
            }
        });

        //note: javafx does not fire anymore mousemoved or mousedragged when we have made a "zooming" manipulation with the buttons
        contentGroup.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                System.out.println("moved");

                switch (manipulationState) {
                    case IDLE:
                        break;
                    case PAN:
                        movePan(event);
                        break;
                    case ROTATE:
                        moveRotate(event);
                        break;
                    case ZOOM:
                        moveZoom(event);
                        break;
                }
            }
        });

        contentGroup.setMouseTransparent(
                false);
    }

    public void enterIdle() {
        manipulationState = ManipulationState.IDLE;
        contentGroup.setCursor(Cursor.DEFAULT);

        System.out.println(manipulationState);

    }

    public void enterPan(MouseEvent event) {

        manipulationState = ManipulationState.PAN;
        pressedX = event.getSceneX();
        pressedY = event.getSceneY();
        initialX = contentGroup.getTranslateX();
        initialY = contentGroup.getTranslateY();
        contentGroup.setCursor(Cursor.MOVE);
        System.out.println(manipulationState);

    }

    public void enterRotate(MouseEvent event) {
        manipulationState = ManipulationState.ROTATE;
        contentGroup.setCursor(Cursor.DEFAULT);
        System.out.println(manipulationState);
    }

    public void enterZoom(MouseEvent event) {
        manipulationState = ManipulationState.ZOOM;
        pressedX = event.getSceneX();
        pressedY = event.getSceneY();
        initialX = contentGroup.getTranslateX();
        initialY = contentGroup.getTranslateY();
        pressedContentGroupScale = contentGroupScale;

        contentGroup.setCursor(Cursor.V_RESIZE);
        System.out.println(manipulationState);

    }

    public void movePan(MouseEvent event) {
        contentGroup.setTranslateX(initialX + (event.getSceneX() - pressedX));
        contentGroup.setTranslateY(initialY + (event.getSceneY() - pressedY));
    }

    public void moveRotate(MouseEvent event) {
    }

    public void moveZoom(MouseEvent event) {
        contentGroupScale = pressedContentGroupScale * Math.exp(ZOOMFACTOR * (event.getSceneY() - pressedY));

        contentGroup.setScaleX(contentGroupScale);
        contentGroup.setScaleY(contentGroupScale);
    }
}
4

0 回答 0