java - 为什么更改 JavaFX 组中一个形状的平移属性会在更改组的比例后影响其他形状

标签 java javafx javafx-11

我正在开发一个程序,在该程序中我正在学习如何在 JavaFX 中缩放和移动对象。对于我的程序,我使用 Group并在 Group我有两个Rectangle我有一些Sliders更改 Rectangle 的属性.

出现的问题是当我更改 translateX 时或translateY Rectangle的在程序中,保留 ScaleXScaleY家长 Group除了1之外,它还改变了另一个Rectangle的位置但当比例为1时,不会出现这个问题。

这是我的程序:

在我的程序中,我有两个 Rectagleab我正在使用 SlideraTranslateX & aTranslateYbTranslateX & bTranslateY更改矩形的translateX 和translateY ab分别。我正在使用另一个 Sliderscale更改scaleX & scaleY名为 group 的组其中包含 ab 。当我更改矩形的平移属性 a 时,问题再次不会发生。和b保持 scaleX 的比例( scaleY & group )但是当我更改它们(矩形 ab )的平移属性时,除了一个矩形的更改平移属性之外,保持比例的平移属性也会以相反的变化方向更改另一个矩形的位置。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Example extends Application{
    
    private Group group;
    
    public static void main(String... arguments){launch(arguments);}
    
    @Override public void start(Stage primaryStage){
        Rectangle a = new Rectangle(200, 200, Color.WHITE);
        Rectangle b = new Rectangle(200, 200, Color.SKYBLUE);
        a.setStroke(Color.BLACK);
        b.setStroke(Color.MAGENTA);
        group = new Group(a, b);
        
        Slider aTranslateX = new Slider(-1600, 1600, 20);
        Slider aTranslateY = new Slider(-1600, 1600, 20);
        Slider bTranslateX = new Slider(-1600, 1600, 20);
        Slider bTranslateY = new Slider(-1600, 1600, 20);
        Slider scale = new Slider(0, 12, 1);
        
        aTranslateX.valueProperty().addListener((o, l, c) -> {
            if(c != null) b.setTranslateX(c.doubleValue());
        });
        aTranslateY.valueProperty().addListener((o, l, c) -> {
            if(c != null) b.setTranslateY(c.doubleValue());
        });
        bTranslateX.valueProperty().addListener((o, l, c) -> {
            if(c != null) a.setTranslateX(c.doubleValue());
        });
        bTranslateY.valueProperty().addListener((o, l, c) -> {
            if(c != null) a.setTranslateY(c.doubleValue());
        });
        scale.valueProperty().addListener((o, l, c) -> {
            if(c != null){
                group.setScaleX(c.doubleValue());
                group.setScaleY(c.doubleValue());
            }
        });
        
        aTranslateX.setMinWidth(200);
        aTranslateY.setMinWidth(200);
        bTranslateX.setMinWidth(200);
        bTranslateY.setMinWidth(200);
        scale.setMinWidth(200);
        
        Label[] labels = new Label[5];
        for(int x = 0; x < labels.length; x++){
            labels[x] = new Label();
            labels[x].setMinWidth(150);
        }
        
        labels[0].setText("Rectangle A Translate X: ");
        labels[1].setText("Rectangle A Translate Y: ");
        labels[2].setText("Rectangle B Translate X: ");
        labels[3].setText("Rectangle B Translate Y: ");
        labels[4].setText("Scale of Group: ");
        
        VBox top = new VBox(10,
                            new HBox(8, labels[0], aTranslateX, labels[1], aTranslateY),
                            new HBox(8, labels[2], bTranslateX, labels[3], bTranslateY),
                            new HBox(8, labels[4], scale));
        
        top.setPadding(new Insets(12));
        top.setStyle("-fx-background-color: #fefefe");
        
        Pane pane = new Pane(group);
        
        BorderPane root = new BorderPane(pane);
        root.setTop(top);
        
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(1280);
        primaryStage.setHeight(700);
        primaryStage.show();
    }
    
}

如何解决此问题,或者当组的比例不是默认值时更改任何对象的平移属性的正确方法是什么?

最佳答案

Group 在计算其大小时包括子级的变换。由于通过 scaleX/scaleY 属性进行缩放的枢轴点是节点的中心,因此更改平移属性可能会导致枢轴点的位置发生变化,从而导致节点的移动该组的所有 child 。如果您不希望这样做,请使用 Pane(不包括大小计算中的转换)而不是 Group 或使用 Scale使用 (0,0) 作为轴心点而不是 scaleX/scaleY 属性进行变换:

Scale groupScale = new Scale();
group.getTransforms().add(groupScale);
groupScale.xProperty().bind(scale.valueProperty());
groupScale.yProperty().bind(scale.valueProperty());

关于java - 为什么更改 JavaFX 组中一个形状的平移属性会在更改组的比例后影响其他形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54344748/

相关文章:

java - javafx多线程如何顺序执行?

java - Maven 和 Eclipse 之间启动 JavaFX 11 应用程序的不同行为

java - 如何创建单例 OkHtpp 类并处理以前的请求

java - 如何编辑 native Java 类

java - 如何使用 maven 创建基于 spring 的可执行 jar?

java - 安装在 Windows 中的字体未显示在 SceneBuilder 中

java - 无法在 IntelliJ-IDEA 中访问 JavaFX 类 "WebPage"

java - 少了一步? loadLibrary() 的参数需要填写什么

java - 将 TXT 文件拖放到 TextArea 中

java - 无法实例化 JavaFX 项目中的类字段