java - 如何从 FXML Controller 中设置新场景

标签 java optimization javafx fxml scenebuilder

我是编程新手,最近两周才开始学习,所以对于任何多余或马虎的代码我深表歉意......

我有 2 个场景,位于我的主类中。但我使用 FXML 来开发每个场景,并且所有代码都已放置在第一个场景的 FXML Controller 中。我已准备好开始构建第二个场景,但不知道如何正确启动它。

我的问题是,如何设置舞台来显示第二个场景 (mainCallWindow),特别是在第一个 FXML 文件的 Controller 类中。如果有更好的方法,请告诉我。

主类:

package supportTool;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.Stage;

public class Main extends Application {

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

    public String versionNumber = "v2.1";

    @Override
    public void start(Stage primaryStage) throws Exception {
        // SETTING UP THE STAGE
        Stage window;
        window = primaryStage;
        window.setTitle("Support Tool " + versionNumber);
        // SETTING UP THE SCENES
        Parent newCallDetailsFXML = FXMLLoader.load(getClass().getResource("newCallDetails.fxml"));
        Parent mainCallWindowFXML = FXMLLoader.load(getClass().getResource("mainCallWindow.fxml"));
        Scene newCallDetails = new Scene (newCallDetailsFXML, 800, 600);
        Scene mainCallWindow = new Scene (mainCallWindowFXML, 800, 600);
        // CHOOSING THE SCENE AND SHOWING THE STAGE
        window.setScene(newCallDetails);
        window.show();
    }
}

场景 1 FXML Controller :

package supportTool;

import javafx.scene.control.*;
import javafx.scene.image.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class newCallController {

    private int maxChar;
    public ChoiceBox choiceAccount;
    public ImageView btnCall;
    public TextField tfCallbackNumber;
    public TextField tfCallerName;
    public TextField tfStoreNumber;

    // ACTION COMPLETED WHEN CALL BUTTON IS PRESSED
    public void btnCall() {
        Caller newCaller = new Caller();
        newCaller.setCallerName(tfCallerName.getText());
        newCaller.setCallbackNumber(tfCallbackNumber.getText());
        newCaller.setAccount(String.valueOf(choiceAccount.getValue()));
        newCaller.setStoreNumber(tfStoreNumber.getText());
        try {
            FileOutputStream fos = new FileOutputStream("caller.bin");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(newCaller);
            oos.close();
            fos.close();
        } catch(IOException e){
            e.printStackTrace();
        }           
        // RIGHT HERE IS WHERE I WANT TO SET THE SCENE TO "mainCallWindow"
    }

    // CHECKS TO SEE IF THE TEXT CONTAINS ONLY LETTERS
    private boolean isNumberCheckEvent(String message) {
        if (message.matches("[0-9]+")) {
            return true;
        } else {
            return false;
        }
    }

    // SETS THE MAX CHARACTERS FOR ALL TEXTFIELDS
    public void maxCharEvent() {
        // CALLER NAME MAX CHARACTERS
        tfCallerName.setOnKeyTyped(maxCharEvent -> {
            maxChar = 20;
            if(tfCallerName.getText().length() >= maxChar) {
                maxCharEvent.consume();
            }
        });
        // CALLBACK NUMBER MAX CHARACTERS
        tfCallbackNumber.setOnKeyTyped(maxCharEvent -> {
            maxChar = 10;
            if(tfCallbackNumber.getText().length() >= maxChar) {
                maxCharEvent.consume();
            }
        });
        // STORE NUMBER MAX CHARACTERS
        tfStoreNumber.setOnKeyTyped(maxCharEvent -> {
            maxChar = 5;
            if (String.valueOf(choiceAccount.getValue()).equals("6 Digit Account")) {
                maxChar = 6;
            }
            if (tfStoreNumber.getText().length() >= maxChar) {
                maxCharEvent.consume();
            }
        });
    }

    // CHANGES TEXT TO ONLY LETTERS BASED ON isNumberCheckEvent
    public void numberValidationEvent() {
        tfCallbackNumber.setOnKeyReleased(numberValidationEvent -> {
            maxCharEvent();
            if(tfCallbackNumber.getText().length() > 0) {
                if (!isNumberCheckEvent(tfCallbackNumber.getText())) {
                    tfCallbackNumber.setText(tfCallbackNumber.getText().substring(0, tfCallbackNumber.getText().length() - 1));
                    tfCallbackNumber.positionCaret(10);
                    numberValidationEvent.consume();
                }
            }
        });
        tfStoreNumber.setOnKeyReleased(numberValidationEvent -> {
            maxCharEvent();
            if(tfStoreNumber.getText().length() > 0) {
                if (!isNumberCheckEvent(tfStoreNumber.getText())) {
                    tfStoreNumber.setText(tfStoreNumber.getText().substring(0, tfStoreNumber.getText().length() - 1));
                    tfStoreNumber.positionCaret(10);
                    numberValidationEvent.consume();
                }
            }
        });
    }
}

最佳答案

您可以通过多种方式改变场景。根据您目前的情况,您可以尝试以下操作。首先,您需要引用 FXMLLoader、场景和舞台来从 Controller 更改场景。不要在主类中加载,而是在 Controller 类中加载。

   FXMLLoader loader = new FXMLLoader(getClass().getResource("mainCallWindow.fxml"));
   Parent mainCallWindowFXML = loader.load();

   //use one of components on your scene to get a reference to your scene object.

   Stage stage = (Stage)tfCallerName.getScene.getWindow();//or use any other component in your controller
   Scene mainCallWindow = new Scene (mainCallWindowFXML, 800, 600);
   stage.setScene(newCallDetails);
   stage.show(); //this line may be unnecessary since you are using the same stage.
}

这不是实现这一目标的唯一方法。您可以使用同一场景加载不同的 FXML 文件。我建议更改场景的根节点,而不是完全更改场景。

关于java - 如何从 FXML Controller 中设置新场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49875548/

相关文章:

Java:计算数据在类中出现的次数

java - 套接字、BufferedReader.readline() - 为什么流没有准备好?

java - 使用打包的.jar作为插件时Py4J回调接口(interface)抛出 "Invalid interface name"

javascript - 使用 React 突出显示列表中的项目时的性能

mysql - 如何使用 JOINED 表和 ORDER BY 和 OFFSET 改进 MySQL 查询

android - 智能转换与 KOTLIN 中的显式转换有何不同

java - 使用 UpdateFX 更新 JavaFX 应用程序

JavaFX。在哪里放置服务类引用? Controller 或主应用程序入门类(class)?

JavaFX - 如何让 VBox 子级与 VBox 父级一起成长

具有太多属性的java编辑对象