JavaFX ImageView旋转更改拖放

时间:2018-02-28 18:03:30

标签: java javafx

所以我有一个可以使用鼠标拖放的ImageView,并通过单击按钮旋转90度。这些都可以独立完成(因此可以旋转或移动ImageView,而不是两者都可以)。当我旋转ImageView并尝试移动它时,它似乎随机移动。

我使用以下方式旋转ImageView:

imageView.setRotate(90);

这导致我正在谈论的看似随意的动作。

我还尝试使用以下方式旋转ImageView:

imageView.getTransforms().add(new Rotate(rotation, position + (width / 2), position + (height / 2));

位置是屏幕上的图像位置。宽度和高度是ImageView的宽度和高度。

这在很大程度上起作用(ImageView不再以意想不到的方式移动),但是现在它可以被移动并放置在Pane(javafx.scene.layout.Pane)的边界之外,这是它的父节点。

ImageView保持在界限内的方式是:

imageView.setOnMouseDragged(new EventHandler<MouseEvent>(){
            public void handle(MouseEvent e) {
                if(!e.isPrimaryButtonDown()) return;

                ImageView iv = (ImageView) e.getSource();

                if(e.getX() > iv.getParent().getTranslateX()) iv.setX(e.getX());
                if(e.getY() > iv.getParent().getTranslateY()) iv.setY(e.getY());
            }
        });

父母对此是前面提到的Pane。这可以正常工作,直到ImageView旋转。

我不知道从哪里去,所以我很感激任何帮助。感谢。

编辑原始问题:

使用第二种旋转方法:

imageView.getTransforms().add(new Rotate(rotation, position + (width / 2), position + (height / 2));

除了x和y的平移改变我旋转ImageView这个方法之外,这个方法也是有用的。例如,如果我将鼠标移动到旋转90度的图像上,那么我的MouseDraggedEvent中e.getX()的位置不会改变,但e.getY()会减少。这表明e.getX()和e.getY()的方式依赖于ImageView的旋转。

有没有办法旋转而不影响ImageView的x和y坐标?

1 个答案:

答案 0 :(得分:1)

e.getX()e.getY()位于图像视图的坐标系中;旋转后,该坐标系仍然是图像视图的局部。因此,您需要将图像视图的x坐标设置为旋转后实际上与y坐标有关的东西(以某种非平凡的方式)。

您应该通过计算鼠标相对于固定值移动的数量来计算拖动:例如现场。

这是一个有效的SSCCE(双击旋转):

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ImageTransformTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        ImageView arrow = new ImageView(createImage());
        Pane pane = new Pane(arrow);
        pane.setMinSize(600,  600);

        new Dragger(arrow) ;
        arrow.setOnMouseClicked(e -> {
            if (e.getClickCount() == 2) {
                arrow.setRotate(arrow.getRotate() + 90);
            }
        });

        Scene scene = new Scene(pane) ;
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class Dragger {
        private double x ;
        private double y ;
        Dragger(ImageView imageView) {
            imageView.setOnMousePressed(e -> {
                x = e.getSceneX();
                y = e.getSceneY();
            });
            imageView.setOnMouseDragged(e -> {
                double deltaX = e.getSceneX() - x ;
                double deltaY = e.getSceneY() - y ;
                imageView.setX(imageView.getX() + deltaX);
                imageView.setY(imageView.getY() + deltaY);
                x = e.getSceneX() ;
                y = e.getSceneY() ;
            });
        }
    }

    private Image createImage() {
        WritableImage image = new WritableImage(100, 100);
        for (int y = 0 ; y < 40 ; y++) {
            for (int x = 0 ; x < 50 - 50 * y / 40 ; x++) {
                image.getPixelWriter().setColor(x, y, Color.TRANSPARENT);
            }
            for (int x = 50 - 50 * y / 40 ; x < 50 + 50 * y / 40 ; x ++) {
                image.getPixelWriter().setColor(x, y, Color.BLUE);
            }
            for (int x = 50 + 50 * y ; x < 100 ; x++) {
                image.getPixelWriter().setColor(x, y, Color.TRANSPARENT);
            }
        }
        for (int y = 40 ; y < 100 ; y++) {
            for (int x = 0 ; x < 100 ; x++) {
                image.getPixelWriter().setColor(x, y, x < 30 || x > 70 ? Color.TRANSPARENT : Color.BLUE);
            }
        }

        return image ;
    }

    public static void main(String[] args) {
        launch(args);
    }
}