【问题标题】:javafx window switching with button back and forthjavafx窗口用按钮来回切换
【发布时间】:2018-09-24 09:49:42
【问题描述】:

我遇到了麻烦,因为我在各自的 Java 类中都有 2 个窗格,我想要一个按钮来打开页面上的另一个(所以使用按钮从一个窗格转到另一个窗格),但它没有'似乎真的不起作用。 我刚开始在我的学校编码。任何帮助都会很棒。

这是我在我的主类上使用的代码,如果需要它的主类中的窗格名称和我的次要中的根,则辅助称为 panle2.java。

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        Pane pane = new HBox(10);
        pane.setPadding(new Insets(5, 5, 5, 5));
        Image image = new Image("picachu_pok__mon-logo-D361BD95C6-seeklogo.com.png");
        pane.getChildren().add(new ImageView(image));

        Button button = new Button();
        button.setOnAction(event -> {
            try {
                FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/A.fxml"));
                Parent root1 = (Parent) fxmlLoader.load();
                Stage stage = new Stage();
                stage.setScene(new Scene(root1));
                stage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        });
        primaryStage.setTitle("pokemon stats");
        Scene value = new Scene(pane, 1000, 600);
        primaryStage.setScene(value);
        button.setOnAction(event -> {
            value.setRoot(pane);

        });
        ImageView imageView2 = new ImageView(image);
        imageView2.setFitHeight(100);
        imageView2.setFitWidth(100);
        pane.getChildren().add(imageView2);
        pane.getChildren().add(button);

        ImageView imageView3 = new ImageView(image);
        imageView3.setRotate(90);
        pane.getChildren().add(imageView3);


        primaryStage.show();


    }


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

【问题讨论】:

  • 尝试提及并解释执行代码时得到的输出/错误。 “似乎不起作用”是一个非常模糊的陈述。

标签: java javafx


【解决方案1】:

您的代码存在多个问题。

  1. Pane pane = new HBox(10); -> 我猜这会导致问题。我在我的代码中进行了尝试,它使用root.setAlignment(Pos.CENTER); 创建了一个错误。另外,我相信这会让必须回来阅读代码的人感到困惑。
  2. 您有一个Button,但您为Button 创建了两个不同的事件处理程序。
  3. 如果您要尝试更改Scene,那么第二个Scene 需要一个Button,这样您就可以返回到第一个Scene。 (本示例不采用这种方法。)

在下面的示例中,我不尝试更改 Scene。我只是在VBox 索引零处切换Nodes。这可能是一个更好的方法。我不知道。我还使用setUserData() 来跟踪当前加载到VBox 索引零中的Node

主要

    import java.io.IOException;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.layout.StackPane;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;

    /**
     *
     * @author blj0011
     */
    public class JavaFXApplication269 extends Application
    {

        @Override
        public void start(Stage primaryStage)
        {
            VBox root = new VBox();
            Scene scene = new Scene(root, 1000, 600);
            Button btnPaneChanger = new Button("Click Me!");

            Label label = new Label("I am Pane 1!");
            StackPane pane1 = new StackPane(label);
            pane1.setPrefSize(1000, 500);
            root.setAlignment(Pos.CENTER);
            root.getChildren().addAll(pane1, btnPaneChanger);//Set the first pane in index zero of the VBox
            btnPaneChanger.setUserData("pane1");//Use setUserData to keep up with which Pane is currently loaded

            btnPaneChanger.setOnAction((event) -> {
                switch (btnPaneChanger.getUserData().toString()) {
                    case "pane1": {
                        try {
                            FXMLLoader listViewLoader = new FXMLLoader(getClass().getResource("pane2.fxml"));
                            StackPane pane2 = ((StackPane) listViewLoader.load());//StackPane is the root node in the FXML
                            root.getChildren().set(0, pane2);
                            btnPaneChanger.setUserData("pane2");
                        }
                        catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                    break;
                    case "pane2":
                        root.getChildren().set(0, pane1);
                        btnPaneChanger.setUserData("pane1");
                        break;
                }

            });

            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        }

        /**
         * @param args the command line arguments
         */
        public static void main(String[] args)
        {
            launch(args);
        }

    }

>Pane 2 Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;

/**
 * FXML Controller class
 *
 * @author blj0011
 */
public class Pane2Controller implements Initializable
{

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        // TODO
    }

}

窗格 2 FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication269.Pane2Controller">
   <children>
      <Label text="This is Pane 2">
         <font>
            <Font size="37.0" />
         </font>
      </Label>
   </children>
</StackPane>

【讨论】:

  • 感谢您的帮助,这帮助很大。
【解决方案2】:

您的代码中的一个问题是您使用 (1) 代码来创建元素,然后 (2) 使用 fxml 来创建另一个窗格。如果您正在使用代码,只需使用代码。如果您使用的是 fxml,只需使用 fxml。

您的初始窗格是在代码中完成的。一种选择是:不做 FXML。创建一个扩展任何 Pane 的新类并在代码中执行所有操作。

重新加载已加载的 FXML 文件总是会出错。

如果您想避免当前代码中的错误,您必须确保 FXML 已经加载。不要在您的 setOnAction 方法(按钮)上实例化它。

public class Main extends Application {

    static Parent root1;

    {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/A.fxml"));
            root1 = (Parent) fxmlLoader.load();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void start(Stage primaryStage) throws Exception {

        Pane pane = new HBox(10);
        pane.setPadding(new Insets(5, 5, 5, 5));
        Image image = new Image("FXML/Capture.PNG");
        Stage stage = new Stage();
        stage.setScene(new Scene(root1,500,500));

        Button button = new Button("Winner");
        button.setMinWidth(200);

        button.setOnAction(e-> {
           stage.show();
        });

        primaryStage.setTitle("pokemon stats");
        Scene value = new Scene(pane, 1000, 600);
        primaryStage.setWidth(1000);
        primaryStage.setScene(value);

        ImageView imageView2 = new ImageView(image);
        imageView2.setPreserveRatio(true);
        pane.getChildren().add(imageView2);
        pane.getChildren().add(button);

        primaryStage.show();

    }

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

我没有测试上面的代码。但我希望你能明白。

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 2017-03-28
    • 1970-01-01
    • 2018-04-15
    • 2013-11-25
    相关资源
    最近更新 更多