为什么更改 JavaFX 组中一个形状的翻译属性会影响更改组缩放后的其他形状



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

发生的问题是,当我更改程序中RectangletranslateXtranslateY时,将父GroupScaleXScaleY保持在 1 之外,它也改变了另一个Rectangle的位置,但是当比例为 1 时,不会出现此问题。

这是我的程序:

在我的程序中,我有两个Rectagle,分别称为ab,我Slider正在使用名为aTranslateX&aTranslateYbTranslateX&bTranslateY分别更改Rectagles的translateX和translateYab。我正在使用另一个名为scaleSlider来更改名为group的组的scaleXscaleY,其中包含ab。同样,当我更改矩形a的平移属性并b保持group的比例(scaleX&scaleY)时,问题不会发生,但是当我更改它们的(矩形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属性进行缩放的枢轴点是节点的中心,因此更改平移属性可能会导致枢轴点的位置发生变化,从而导致组的所有子项移动。如果您不希望这样做,请使用Pane(在大小计算中不包括变换)而不是Group或使用(0,0)作为枢轴点的Scale变换而不是scaleX/scaleY属性:

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

最新更新