javafx でノードのパン/ズーム マウス操作をしようとしています。
知っている人にとっては、CATIA V5 の動作と同じになります。
- 中央のボタンを押すと、「パン」になり、ビューが動きに従います。
- 中央のボタンを押したまま、3 番目のボタンを押すと、「回転」になります。 " (ここでは使用しません。3D で役立ちます)
- 中央のボタンを押したまま、3 番目のボタンを放します。「ズーム」になり、上下に移動するとビューがズームインおよびズームアウトします。
残念ながら、ZOOMING 状態に入ると、javafx はもう MouseDragged または MouveMoved を起動しないようです。
あたかも 3 回目のボタン リリースが発生したイベントに影響を与えたかのように。
ここに私のコードがあります:
ズーム機能は私の「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);
}
}