首页 文章

如何获取另一个UI界面的场景 - Javafx 8

提问于
浏览
0

我是JavafX的新手 . 我想通过第二个GUI更改我的第一个GUI的CSS文件 .

我有以下代码:

Main1.java

package javafxapplication3.a;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main1 extends Application{

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = null;
        try {
            root = FXMLLoader.load(getClass().getResource("/main1.fxml"));
        } catch (Exception e) {
        }

        String css = Main1.class.getResource("/main1.css").toExternalForm();
        Scene scene = new Scene(root, 400, 400);
        scene.getStylesheets().clear();
        scene.getStylesheets().add(css);
        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.setTitle("JCal");
        primaryStage.show();
    }

}

Main1Controller.java

package javafxapplication3.a;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class Main1Controller {

    @FXML
    private Button button1;

    public void initialize() {

        button1.setOnAction(value -> {
            Stage primaryStage = new Stage(); 
        Parent root = null;
        try {
            root = FXMLLoader.load(getClass().getResource("/main2.fxml"));
        } catch (Exception e) {
        }

        Scene scene = new Scene(root, 400, 400);
        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.setTitle("JCal");
        primaryStage.show();
        });

    }
}

main1.fxml

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication3.a.Main1Controller">
   <children>
      <Button fx:id="button1" layoutX="271.0" layoutY="173.0" mnemonicParsing="false" text="Main-1" />
   </children>
</AnchorPane>

main2.fxml

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication3.a.Main2Controller">
   <children>
      <Button fx:id="button" layoutX="271.0" layoutY="173.0" mnemonicParsing="false" text="Main-2" />
   </children>
</AnchorPane>

在FXML中我有一个名为 button1 的按钮,当我点击它时,它会打开一个新的GUI,其中有另一个按钮,名为 button . 最后我想要做的是,当我点击第二个按钮时,即 button 主GUI中按钮的颜色应该改变应该改变 .

我确实尝试了this示例中显示的控制器,但这个dint帮助了我 .

我是否需要创建第二个控制器并一起创建一个新的舞台和场景?或者有其他替代方法吗?

1 回答

  • 0

    main2.fxml 的控制器中,提供一个机制,用于设置按下按钮时要执行的操作 . 例如:

    public class Main2Controller {
    
        @FXML
        private Button button ;
    
        private Runnable buttonAction = () -> {} ; // do nothing by default
    
        public void setButtonAction(Runnable action) {
            this.buttonAction = action ;
        }
    
        public void initialize() {
            button.setOnAction(e -> buttonAction.run());
        }
    }
    

    现在在 Main1Controller 中,您可以在加载FXML时检索控制器,并设置按钮操作:

    button1.setOnAction(value -> {
        Stage primaryStage = new Stage(); 
        Parent root = null;
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/main2.fxml"));
            root = loader.load();
            Main2Controller controller = loader.getController();
            controller.setButtonAction(() -> {
                // perform button action here...
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setResizable(false);
        primaryStage.setScene(scene);
        primaryStage.setTitle("JCal");
        primaryStage.show();
    });
    

    另一种方法是让两个控制器都可以访问相同的可观察状态,例如: ObjectProperty<Color> . 如果您在一个控制器中有很多操作影响其他地方的状态,那么这种方法可能会更好(您只需将所有数据捆绑到您传递的单个"model"类中) . 这看起来像:

    public class Main1Controller {
    
        private final ObjectProperty<Color> color = new SimpleObjectProperty<>();
    
        @FXML
        private Button button1;
    
        public void initialize() {
    
            color.addListener((obs, oldColor, newColor) -> {
                String style = String.format("-fx-background-color: #%02x%02x%02x;",
                    (int) (newColor.getRed() * 255),
                    (int) (newColor.getGreen() * 255),
                    (int) (newColor.getBlue() * 255));
                button1.setStyle(style);
            });
    
            button1.setOnAction(value -> {
                Stage primaryStage = new Stage(); 
                Parent root = null;
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/main2.fxml"));
                root = loader.load();
                Main2Controller controller = loader.getController();
                controller.setColorModel(color);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Scene scene = new Scene(root, 400, 400);
            primaryStage.setResizable(false);
            primaryStage.setScene(scene);
            primaryStage.setTitle("JCal");
            primaryStage.show();
            });
    
        }
    }
    

    和Main2Controller看起来像

    public class Main2Controller {
    
        @FXML
        private Button button ;
    
        private ObjectProperty<Color> colorModel = new SimpleObjectProperty<>();
    
        public void setColorModel(ObjectProperty<Color> color) {
            this.colorModel = color ;
        }
    
    
        public void initialize() {
            button.setOnAction(e -> {
                colorModel.set(/* some color */);
            });
        }
    }
    

相关问题