2
votes

I am brand-new to programming and only started learning this past 2 weeks, so I'm sorry for any redundant or sloppy code...

I have 2 scenes, which are in my Main class. But I'm using FXML to develop each scene, and all code has been placed in the first scene's FXML Controller. I'm ready to start building my second scene, but don't know how to properly launch it.

My question is, how can I set the stage to show the second scene (mainCallWindow), specifically from within the first FXML file's controller class. If there is a bettery way, please let me know.

Main Class:

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

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

1 Answers

0
votes

You can change scene in various ways. Within your current situation you can try something like below. First, you need reference to your FXMLLoader, scene and stage to change your scene from your controller. Instead of loading in main class, do loading in your controller class.

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

This is not the only way to achieve this. You can use same scene to load different FXML files. I would suggest changing the root node of a scene instead of changing scene completely.