你能把两个不同的 Java FX 场景写成两个单独的 类 吗?

Can you write two different Java FX scenes as two separate classes?

我是初级 Java 程序员,正在我当地的大学完成 "Java 101" class。我也在推动自己学习一些额外的主题,包括 Java FX。我已经完成了 Oracle 网站上的 Java FX 教程,还浏览了一些 YouTube 视频,还阅读了 "Java FX for Dummies"(这是我能为初学者找到的最好的书。)所有这些 material 教会了我很多基础知识,但是一些(应该)相对简单的东西让我不知所措。

例如:假设我有一个 Java FX 程序,它在一个舞台上使用多个场景。当用户单击 "Switch!" 按钮时,第二个场景将换成第一个。简单。我可以在一个 .java 文件中完成所有这些,没问题。 (见下面的代码)

但是我的 .java class 文件变得非常长,而且很难进行故障排除。如果我可以 define/declare/initialize 一个场景作为一个 class 在一个 .java 文件中,第二个场景作为另一个 class 在另一个 .java 文件中,那就太好了.这将使跟踪每个场景的组件变得非常非常容易。问题是,我不知道该怎么做。

我想你会写一个 Scene1.java class 然后一个 Scene2.java class,然后在你想要的时候简单地在两者之间传递阶段对象切换场景。但是我找不到一个例子来说明这是如何完成的,我所有的尝试都会导致编译器错误或非常可怕的运行时错误。

有谁知道如何做到这一点?如果是这样,我需要做些什么来修改下面的 SwitchScenes2() 方法以创建新的 Scene2 对象并将其传递给舞台?

谢谢!饶

/*
    JavaFXExample.java
*/

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
import javafx.event.*;
import javafx.geometry.*;

public class JavaFXExample extends Application{

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

Button btnSw1;
Button btnSw2;
Button btnClose;
HBox hbox1;
VBox vbox1;
Scene scene1;
Scene scene2;
Stage stage;

@Override public void start(Stage primaryStage){
    btnSw1 = new Button("Switch Scenes!");
    btnSw1.setOnAction(
        e -> SwitchScenes2() );
    btnSw2 = new Button("Switch back!");
    btnSw2.setOnAction(
        e -> SwitchScenes1() );
    btnClose = new Button();
    btnClose.setText("Close me!");
    btnClose.setOnAction(e -> CloseWindowClick());

    hbox1 = new HBox(10);
    hbox1.getChildren().addAll(btnSw1);
    vbox1 = new VBox(10);
    vbox1.getChildren().addAll(btnSw2, btnClose);

    scene1 = new Scene(hbox1, 300, 300);
    scene2 = new Scene(vbox1, 200, 400);

    stage = primaryStage;
    stage.setScene(scene1);
    stage.setTitle("Example App");
    stage.show();
   }

    public void SwitchScenes1(){
        stage.setScene(scene1);
    }
    public void SwitchScenes2(){
        stage.setScene(scene2);
    }
    public void CloseWindowClick(){
        stage.close();
    }
}

您要做的是创建单独的 类,两者都具有 return 场景的功能。从那里您将需要初始化这些 类 并使用按钮调用一个函数,该函数将向这些场景添加数据或创建一个新的空白场景(作为 "delete" 场景的快速方法)。但是,如果您想要一种更专业的方式来切换这样的场景,您将需要查看 TabPane()。

Scene1 scene1 = new Scene1();
Scene2 scene2 = new Scene2();

TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
tab1.setContent(scene1);
tabPane.getTabs().add(tab1);
Tab tab2 = new Tab();
tab2.setContent(scene2);
tabPane.getTabs().add(tab2);
  1. 创建一个包含主要方法的管理器 class 并初始化第一个屏幕。例如

public class VMCSManager 扩展应用程序 {

private Parent content;
private static VMCSManager instance;

public VMCSManager() {
    instance=this;
}

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

public static VMCSManager getInstance() {
    return instance;
}

@Override
public void start(Stage primaryStage) throws Exception {    
    initializePanel();  
    Scene scene = new Scene(content);
    stageStyle(primaryStage);
    primaryStage.setScene(scene);
    primaryStage.show();
}

private void initializePanel() throws IOException{
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("fxml/SimulatorDisplay.fxml"));
    content = loader.load(); 
}

public void openCustomerPanel() throws IOException{
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("fxml/CustomerDisplay.fxml"));
    content = loader.load(); 
    Scene scene = new Scene(content);
    primaryStage.setScene(scene);
    primaryStage.show();
}

}

  1. 为第一个屏幕创建主控制器class。例如;

public class SimulatorController 实现 Initializable{

@FXML
public void clickCustomer (ActionEvent event) throws IOException{
    log.info("Starting Customer Panel");
    VMCSManager.getInstance().openCustomerPanel();
}
@FXML
public void clickMaintainer(ActionEvent event) throws IOException{
    log.info("Starting Maintainer Panel");
    VMCSManager.getInstance().openMaintainerPanel();
}

}

  1. 最后为指定的屏幕创建控制器class。例如`

public class CustomerController 扩展了 SimulatorController{

@FXML
private Label brand1Lbl;
@FXML
private Label brand2Lbl;
@FXML
private Label brand3Lbl;
@FXML
private Label brand4Lbl;
@FXML
private Label brand5Lbl;

@FXML
private Label statusLbl1;
@FXML
private Label statusLbl2;

private static final Logger log=LoggerFactory.getLogger(CustomerController.class);

public CustomerController() {
    context= new BuyingStateContext();
}

public void initialize(URL location, ResourceBundle resources) {
     this.location = location;
     this.rb = resources;
     coinsValidityFlash.setVisible(false);
     insertCoinTxt.setDisable(true);

     brand1Btn.setStyle("-fx-background-color:  #CACACA;");
     brand2Btn.setStyle("-fx-background-color:  #CACACA;");
     brand3Btn.setStyle("-fx-background-color:  #CACACA;");
     brand4Btn.setStyle("-fx-background-color:  #CACACA;");
     brand5Btn.setStyle("-fx-background-color:  #CACACA;");

     populateVending();
}
.
.
.

}

`

Pete 据我了解你希望将一个大 java 文件分成小文件,在每个 class 创建方法(函数)中创建 Java classes将 return 布局(HBox、VBox、Flowpane 或 ....)然后在您的主程序中创建一个 Java class 的对象并使用这些方法构建大型应用程序。

在我的示例中,我制作了一个主要的和一个分离的 class 具有一个功能,只是为了向您展示它是如何工作的。在我的主体中有 2 个标签,2 个按钮,一种布局和一个分离的对象 class,通过单击按钮场景将改变 我的主要:

public class SwitchSceneSample extends Application {
public static void main(String[] args) {
    launch(args);
}

Stage window;
Scene scene1, scene2;

@Override
public void start(Stage primaryStage) throws Exception {
    // I am using window as primaryStage
    window = primaryStage;
    // Label 1
    Label label1 = new Label("Welcome to the first scene!");
    // Label 2
    Label label2 = new Label("This is second scene!");
    // Button 1, by pressing this button primaryStage will be set as scene 2
    Button button1 = new Button("Go to scene 2");
    button1.setOnAction(e -> window.setScene(scene2));
    // Button 2, by pressing this button primaryStage will be set as scene 1
    Button button2 = new Button("Click to go scene 1");
    button2.setOnAction(e -> window.setScene(scene1));
    // Creating an object of the class'LayoutOne.java'
    LayoutOne l1 = new LayoutOne();
    // set my scene 1(by calling method called 'sceneView1()' from class 'LayoutOne.java')
    scene1 = new Scene(l1.sceneView1(label1, button1), 200, 200);
    // Set my scene 2 inside my main class
    StackPane layout2 = new StackPane();
    layout2.getChildren().addAll(label2, button2);
    scene2 = new Scene(layout2, 600, 300);
    // Making my 
    window.setScene(scene1);
    window.setTitle("Scene Switch Sample");
    window.show();
}

}

我的第二个Class:

public class LayoutOne {
public VBox sceneView1(Label label, Button button) {

    // Layout 1 - children are laid out in vertical column
    VBox layout1 = new VBox(20);
    layout1.getChildren().addAll(label, button);

    return layout1;
}

}