(JavaFX) 无法将 3D 对象分组并围绕设定的枢轴旋转它们
(JavaFX) Trouble Grouping 3D Objects and rotating them around a set pivot
在 JavaFX 中,我想将我在 scenebuilder 中创建的几个 3D 对象分组,并将此组用作对象以进行适当的旋转和变换。但是,对对象进行分组或对其进行翻译会导致分组的任何对象消失。
这是应用程序 class,我在其中从 'main' 控制器 class 访问对象并尝试分组...
public class MusicGeneratorGUI extends Application { // implements ActionListener
@FXML
private void initialize(){
}
@Override
public void start(Stage mainStage) throws IOException {
//Loading controller
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
Parent root = loader.load();
Main main = loader.getController();
//Creating application window...
Scene scene = new Scene(root);
mainStage.setScene(scene);
mainStage.setTitle("APPLICATION_NAME");
mainStage.show();
//Attempting an object grouping...
Group iconGroup = new Group();
iconGroup.getChildren().add(main.icon);
iconGroup.getChildren().add(main.icon1);
iconGroup.getChildren().add(main.icon2);
iconGroup.getChildren().add(main.icon3);
iconGroup.getChildren().add(main.icon4);
iconGroup.getChildren().add(main.icon5);
//Even attempting rotation on a single object causes this disappearing...
//main.icon.translateXProperty().set(250);
//main.icon.translateYProperty().set(300);
//main.icon.translateZProperty().set(-1200);
//Rotate rotate = new Rotate(65, new Point3D(1,0,0));
//main.icon.getTransforms().add(rotate);
}
public static void main(String[] args)
{
launch(args);
}
}
这就是这些对象在 'main' 控制器中实例化的方式 class...
public class Main implements Initializable {
@FXML public Sphere icon;
@FXML public Cylinder icon1;
@FXML public Cylinder icon2;
@FXML public Cylinder icon3;
@FXML public Cylinder icon4;
@FXML public Cylinder icon5;
}
这是 FXML 文件...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.PerspectiveCamera?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Cylinder?>
<?import javafx.scene.shape.Sphere?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" style="-fx-background-color: #feccff;" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main">
<children>
<PerspectiveCamera fx:id="camera" layoutX="249.0" layoutY="274.0" />
<MenuBar maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="500.0" style="-fx-background-color: #a9e8d2; -fx-use-system-menu-bar: #cba9e8;">
<menus>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="Welcome Guide" />
<MenuItem mnemonicParsing="false" text="Contact Us" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Customise">
<items>
<MenuItem mnemonicParsing="false" text="Key" />
<MenuItem mnemonicParsing="false" text="Time Signature" />
<MenuItem mnemonicParsing="false" text="Instruments" />
</items>
</Menu>
<Menu disable="true" mnemonicParsing="false" text="Key">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets left="20.0" top="25.0" />
</padding>
</MenuBar>
<Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
<Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
<Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
<Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
</children>
</AnchorPane>
除了您将图标移动到组节点而不是在任何地方渲染组节点之外,您实施的几乎是正确的。以下是使其工作的更改。
给 main.fxml 中的 AnchorPane 一个 fx:id
<AnchorPane fx:id="root" maxHeight="-Infinity"....
在Main.java
中包含实例变量
@FXML public AnchorPane root;
在 MusicGeneratorGUI.java
的根节点中包含 iconGroup
Group iconGroup = new Group();
iconGroup.getChildren().add(main.icon);
iconGroup.getChildren().add(main.icon1);
iconGroup.getChildren().add(main.icon2);
iconGroup.getChildren().add(main.icon3);
iconGroup.getChildren().add(main.icon4);
iconGroup.getChildren().add(main.icon5);
main.root.getChildren().add(iconGroup); // You are missing this line
或者您可以将它们分组在 fxml 本身中并处理组 id,并且可以摆脱所有上述代码。
<Group fx:id="iconGroup">
<Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
<Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
<Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
<Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
</Group>
在 JavaFX 中,我想将我在 scenebuilder 中创建的几个 3D 对象分组,并将此组用作对象以进行适当的旋转和变换。但是,对对象进行分组或对其进行翻译会导致分组的任何对象消失。
这是应用程序 class,我在其中从 'main' 控制器 class 访问对象并尝试分组...
public class MusicGeneratorGUI extends Application { // implements ActionListener
@FXML
private void initialize(){
}
@Override
public void start(Stage mainStage) throws IOException {
//Loading controller
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
Parent root = loader.load();
Main main = loader.getController();
//Creating application window...
Scene scene = new Scene(root);
mainStage.setScene(scene);
mainStage.setTitle("APPLICATION_NAME");
mainStage.show();
//Attempting an object grouping...
Group iconGroup = new Group();
iconGroup.getChildren().add(main.icon);
iconGroup.getChildren().add(main.icon1);
iconGroup.getChildren().add(main.icon2);
iconGroup.getChildren().add(main.icon3);
iconGroup.getChildren().add(main.icon4);
iconGroup.getChildren().add(main.icon5);
//Even attempting rotation on a single object causes this disappearing...
//main.icon.translateXProperty().set(250);
//main.icon.translateYProperty().set(300);
//main.icon.translateZProperty().set(-1200);
//Rotate rotate = new Rotate(65, new Point3D(1,0,0));
//main.icon.getTransforms().add(rotate);
}
public static void main(String[] args)
{
launch(args);
}
}
这就是这些对象在 'main' 控制器中实例化的方式 class...
public class Main implements Initializable {
@FXML public Sphere icon;
@FXML public Cylinder icon1;
@FXML public Cylinder icon2;
@FXML public Cylinder icon3;
@FXML public Cylinder icon4;
@FXML public Cylinder icon5;
}
这是 FXML 文件...
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.PerspectiveCamera?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Cylinder?>
<?import javafx.scene.shape.Sphere?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" style="-fx-background-color: #feccff;" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main">
<children>
<PerspectiveCamera fx:id="camera" layoutX="249.0" layoutY="274.0" />
<MenuBar maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="500.0" style="-fx-background-color: #a9e8d2; -fx-use-system-menu-bar: #cba9e8;">
<menus>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="Welcome Guide" />
<MenuItem mnemonicParsing="false" text="Contact Us" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Customise">
<items>
<MenuItem mnemonicParsing="false" text="Key" />
<MenuItem mnemonicParsing="false" text="Time Signature" />
<MenuItem mnemonicParsing="false" text="Instruments" />
</items>
</Menu>
<Menu disable="true" mnemonicParsing="false" text="Key">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets left="20.0" top="25.0" />
</padding>
</MenuBar>
<Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
<Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
<Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
<Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
</children>
</AnchorPane>
除了您将图标移动到组节点而不是在任何地方渲染组节点之外,您实施的几乎是正确的。以下是使其工作的更改。
给 main.fxml 中的 AnchorPane 一个 fx:id
<AnchorPane fx:id="root" maxHeight="-Infinity"....
在Main.java
中包含实例变量@FXML public AnchorPane root;
在 MusicGeneratorGUI.java
的根节点中包含 iconGroupGroup iconGroup = new Group();
iconGroup.getChildren().add(main.icon);
iconGroup.getChildren().add(main.icon1);
iconGroup.getChildren().add(main.icon2);
iconGroup.getChildren().add(main.icon3);
iconGroup.getChildren().add(main.icon4);
iconGroup.getChildren().add(main.icon5);
main.root.getChildren().add(iconGroup); // You are missing this line
或者您可以将它们分组在 fxml 本身中并处理组 id,并且可以摆脱所有上述代码。
<Group fx:id="iconGroup">
<Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
<Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
<Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
<Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
<Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
</Group>