【问题标题】:Can you write two different Java FX scenes as two separate classes?你能把两个不同的 Java FX 场景写成两个独立的类吗?
【发布时间】:2016-08-01 18:38:26
【问题描述】:

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

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

但是我的 .java 类文件变得非常长并且难以解决。如果我可以将一个场景定义/声明/初始化为一个 .java 文件中的一个类,而将第二个场景定义/声明/初始化为另一个 .java 文件中的另一个类,那就太好了。这将使跟踪每个场景的组件变得更加容易。问题是,我不知道该怎么做。

我想你会编写一个 Scene1.java 类,然后是一个 Scene2.java 类,当你想要切换场景时,只需在两者之间传递舞台对象。但是我找不到如何做到这一点的示例,而且我所有的尝试都会导致编译器错误或非常可怕的运行时错误。

有谁知道如何做到这一点?如果是这样,我需要做些什么来修改下面的 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();
    }
}

【问题讨论】:

标签: java javafx scene stage


【解决方案1】:

您要做的是创建单独的类,它们都具有返回场景的功能。从那里您将要初始化这些类并使用按钮调用一个函数,该函数将向这些场景添加数据或创建一个新的空白场景(作为“删除”场景的快速方法)。但是,如果您想要一种更专业的方式在这样的场景之间切换,您将需要查看 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);

【讨论】:

    【解决方案2】:
    1. 创建一个包含主要方法的管理器类并初始化第一个屏幕。例如。

    公共类 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. 为第一个屏幕创建主控制器类。例如;

    公共类 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. 最后为指定的屏幕创建控制器类。例如`

    公共类 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();
    }
    .
    .
    .
    

    }

    `

    【讨论】:

      【解决方案3】:

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

      在我的示例中,我用一个函数创建了一个主类和一个分离类,只是为了向您展示它的工作原理。在我的主要有2个标签,2个按钮一种布局和一个分离类的对象,通过单击按钮场景将改变 我的主要:

      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();
      }
      

      }

      我的第二课:

      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;
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2013-11-25
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 2017-05-15
        • 2013-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多