我正在尝试在 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);
}
}