代码之家  ›  专栏  ›  技术社区  ›  CorellianAle

JavaFX如何将节点居中到ImageView(setPreserveRation==true)?

  •  0
  • CorellianAle  · 技术社区  · 6 年前

    我有一个 resizable ImageView 图像的某些部分应该是可点击的。 我的想法是创建一个 GridPane 这将充当覆盖,并在其中放置几个透明按钮,这样当用户单击图像的某个部分时,他实际上会触发图像上的隐藏按钮:

    <!-- parent that resizes from time to time -->
    <StackPane>
    
        <StackPane>
    
            <!-- background image, preserves ration -->
            <ImageView/>
    
            <!-- overlay with transparent buttons -->
            <!-- should be positionion exactly the same as Image inside ImageView -->
            <GridPane>
                <!- buttons here, columns == rows -->
            </GridPane>
    
        </StackPane>
    
    </StackPane>
    

        StackPane stackPane_wrapper = new StackPane();
        stackPane_wrapper.setAlignment(Pos.CENTER);
    
        //menu wheel
        WrappedImageView imageView_wheel = new WrappedImageView();
        imageView_wheel.setImage(new Image("images/menu-wheel.png"));
        imageView_wheel.setPreserveRatio(true);
        stackPane_wrapper.getChildren().add(imageView_wheel);
    
        GridPane gridPane_overlay = new GridPane();
        stackPane_wrapper.getChildren().add(gridPane_overlay);
    
        int size = 20;
    
        for (int i = 0; i < size; ++i)
        {
            ColumnConstraints columnConstraints = new ColumnConstraints();
            columnConstraints.setPercentWidth(100.0d / size);
            gridPane_overlay.getColumnConstraints().add(columnConstraints);
    
            RowConstraints rowConstraints = new RowConstraints();
            rowConstraints.setPercentHeight(100.0d / size);
            gridPane_overlay.getRowConstraints().add(rowConstraints);
        }
    
        Button button = new Button();
        button.setText("test");
        //... set style to make this button transparent
        gridPane_overlay.add(button, 3, 5, 2, 4);
    

    我的问题是我无法放置 gridPane_overlay Image 在…内 图片框 . 形象 imageView_wheel 不断地调整大小和改变它的位置,这是完全好的,但我不知道如何分配它的大小和位置给 网格覆盖

    更新:

    好像 getParentInParent.getWidth() getParentInParent.getHeight() 返回文件的正确大小 形象 在…内 WrappedImageView ,现在我需要得到它的位置,并将大小和位置分配给网格。

    基于这些评论,我提出了以下解决方案;

    /**
     *
     * @param bounds bounds of image - result of {@link WrappedImageView#localToScene(Bounds)} from {@link WrappedImageView#getBoundsInLocal()}
     * @param x click X - {@link MouseEvent#getSceneX()} minus {@link Bounds#getMinX()}
     * @param y click Y - {@link MouseEvent#getSceneY()} minus {@link Bounds#getMinY()}
     * @return
     */
    private int determineClick(Bounds bounds, double x, double y)
    {
        double centerX = bounds.getWidth() / 2;
        double centerY = bounds.getHeight() / 2;
    
        double angle = Math.toDegrees(Math.atan2(x - centerX, y - centerY));
    
        Point2D center = new Point2D(centerX, centerY);
        Point2D click = new Point2D(x, y);
        double distance = center.distance(click);
    
        double diameter = centerX;
        boolean isInner = distance < diameter * 0.6;
    
        //-90 -> -135
        if (angle <= -90 && angle > -135)
        {
            if (isInner)
            {
                return 10;
            }
    
            return 0;
        }
    
        //-135 -> -180/180
        if (angle <= -135 && angle > -180)
        {
            if (isInner)
            {
                return 11;
            }
    
            return 1;
        }
    
        //-180/180 -> 135
        if (angle <= 180 && angle > 135)
        {
            if (isInner)
            {
                return 12;
            }
    
            return 2;
        }
    
        //135 -> 90
        if (angle <= 135 && angle > 90)
        {
            if (isInner)
            {
                return 13;
            }
    
            return 3;
        }
    
        //90 -> 45
        if (angle <= 90 && angle > 45)
        {
            if (isInner)
            {
                return 14;
            }
    
            return 4;
        }
    
        //45 -> -0/0
        if (angle <= 45 && angle > 0)
        {
            if (isInner)
            {
                return 15;
            }
    
            return 5;
        }
    
        //-0/0 -> -45
        if (angle <= 0 && angle > -45)
        {
            if (isInner)
            {
                return 16;
            }
    
            return 6;
        }
    
        //-45 -> -90
        if (angle <= -45 && angle > -90)
        {
            if (isInner)
            {
                return 17;
            }
    
            return 7;
        }
    
        throw new RuntimeException("Unable to determine point coordinates");
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Sai Dandem    6 年前

    imageView_wheel.setOnMouseClicked(e -> {
        Bounds bounds = imageView_wheel.localToScene(imageView_wheel.getBoundsInLocal());
        double x = e.getSceneX()-bounds.getMinX();
        double y = e.getSceneY()-bounds.getMinY();
        System.out.println("Clicked at :: "+x+","+y);
        // Now you know at what point in the image bounds is clicked, compute your logic as per your needs..
    });