-1

Can I know why there is an error when I say.

Stage s = new Stage();

new CaeserCipherFX().start(s);

This is my code below. I need to launch another JavaFX Application from this one. Please help. Thank you.

public class Main extends Application
{

    String args[];
    @Override
    public void start(Stage stage) throws Exception
    {

        // creating types of encryptions (Button)

        Button caeserCipher = new Button("1. Caeser Cipher");
        Button runningKeyCipher = new Button("2. Running Key Cipher");
        Button trithemiusCipher = new Button("3. Trithemius Cipher");
        Button vignereCipher = new Button("4. Vignere Cipher");

        //setting styles
        caeserCipher.setTextFill(Color.BLUE);
        runningKeyCipher.setTextFill(Color.BLUE);
        trithemiusCipher.setTextFill(Color.BLUE);
        vignereCipher.setTextFill(Color.BLUE);

        /*need to add more!*/
        //setting action listeners
        String arr [] = {"CaeserCipher","RunningKeyCipher","TrithemiusCipher","VignereCipher"};
        caeserCipher.setOnAction((ActionEvent event)->{
                //open caeser cipher
                Stage s = new Stage();
                new CaeserCipherFX().start(s);

            });
        runningKeyCipher.setOnAction((ActionEvent event)->{
                //open running key cipher
                stage.hide();
            });
        trithemiusCipher.setOnAction((ActionEvent event)->{
                //open trithemius cipher 
                stage.hide();
            });
        vignereCipher.setOnAction((ActionEvent event)->{
                //open vignere cipher
                stage.hide();
            });
        // creating flowpane(FlowPane)
        FlowPane menu = new FlowPane();
        menu.setHgap(25);
        menu.setVgap(25);
        menu.setMargin(caeserCipher, new Insets(20, 0, 20, 20));

        //list for Flowpane(ObservableList)
        ObservableList list = menu.getChildren();

        //adding list to flowpane
        list.addAll(caeserCipher,runningKeyCipher,trithemiusCipher,vignereCipher);

        //scene for stage
        Scene scene = new Scene(menu);

        stage.setTitle("Main Menu");
        stage.setScene(scene);
        // stage.initStyle(StageStyle.UTILITY);
        stage.setHeight(100);
        stage.setWidth(600);
        stage.setResizable(false);

        // Show the Stage (window)
        stage.show();
    }

}

And I want to launch the code below:

public class CaeserCipherFX extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {//some other code
        //some other code
    }
 }
Kukic Vladimir
  • 1,010
  • 4
  • 15
  • 22
K00LDUD3
  • 1
  • 1
  • Duplicate of this question: https://stackoverflow.com/questions/38626174/java-setonaction-subscribe-to-event-that-throws-exception – fabian Oct 21 '19 at 16:36
  • What is the error you get....? – Slaw Oct 22 '19 at 04:29
  • it says **unreported exception java.lang.Exception; must be caught or declared to be thrown** – K00LDUD3 Oct 22 '19 at 09:00
  • That (compilation) error is related to the basics of Java, not JavaFX. This Q&A may help you: https://stackoverflow.com/questions/37424284/unreported-exception-java-lang-exception-must-be-caught-or-declared-to-be-throw – Slaw Oct 22 '19 at 13:34

2 Answers2

1

There is a ubiquitous JavaFX main application thread which takes a while to get used to.

Think of it like the front-end thread. Theoretically, you should use that thread to handle UI updates and complex cpu tasks such as looking up something in a BD or figuring out the 100000th decimal of PI should be done in a background thread. If you don't do this, the UI will become unresponsive until the DB data is returned, or that decimal is found.

public class TestClass extends Application {

    public static void main(String[] args) {
        System.out.println("here");
        Application.launch(TestClass.class, args);
        System.out.println("this is called once application launch is terminated.");
    }

    @Override
    public void init() throws Exception {
        super.init(); //To change body of generated methods, choose Tools | Templates.
        System.out.println("message from init");
    }

    @Override
    public void start(Stage primaryStage) throws Exception { // this is abstract.
        System.out.println("message from start");
        Platform.exit(); // if you remove this line, the application won't exit. 
    }
}

Since JavaFX comes with some prerequisites, you need to start you rapplication using a front-end. You can work around this, but technically,

public void start(Stage primaryStage)

is what , for all intensive purposes, starts your program.

From here, you can use the primaryStage to control most of your application. It's a good idea to put a .onCloseRequest() on it in which you call Platform.exit();

If you want to have multiple windows in your application, you could use something like

public class TestClass extends Application {

    public static void main(String[] args) {
        System.out.println("here");
        Application.launch(TestClass.class, args);
        System.out.println("this is called once application launch is terminated.");
    }

    @Override
    public void init() throws Exception {
        super.init(); //To change body of generated methods, choose Tools | Templates.
        System.out.println("message from init");
    }

    @Override
    public void start(Stage primaryStage) throws Exception { // this is abstract.
        primaryStage.setScene(new Scene(new TextArea("this is the first stage (window)")));
        primaryStage.setTitle("stage 1");
        primaryStage.show();

        primaryStage.setOnCloseRequest((event) -> {
            Platform.exit();
        });

        Stage secondaryStage = new Stage();
        secondaryStage.setTitle("stage 2");
        TextArea ta2 = new TextArea("this is a different stage.");
        Scene scene = new Scene(ta2);
        secondaryStage.setScene(scene);
        secondaryStage.show();

        primaryStage.setX(200);

        secondaryStage.setX(200 + primaryStage.getWidth() + 50);

    }
}

This is what I assume you want to do. Basically create a new window whenever you press a button. You can create stages like this.

The reason for which you can't do it your way is because you are attempting to start another javafx thread by invoking new CaeserCipherFX which is an application object, not a Stage.

new CaeserCipherFX().start(s); // this can only be called once.

IF you absolutely want to have 2 distinct applications (note: not application windows), then you need to have 2 distinct processes.

Lastly, the primaryStage parameter used in either examples is in the beginning basically a placeholder (as in it's constructed, but there's nothing really in it... like a new String()). You can use different stage objects as your "primary" UI.

Lastly, if depending on the stuff you want to decrypt, you may need to use background threads if you want to keep the UI responsiveness. For this you will need to check out the concurrency part of the javafx tutorial.

EverNight
  • 964
  • 7
  • 16
0

Is it possible to launch a JavaFX application through another JavaFX application? Not really.

Alternatively, you can use java.lang.ProcessBuilder

This class essentially sends command lines to your operating system shell.

You can use it to run something like "java -jar XXX\YYY\CaeserCipherFX.jar" whenever you click a button. (you'll have to build a CaeserCypherFX project into a jar file)

This will create a new JVM. This means no memory state sharing. You can handle this through IPC.

EverNight
  • 964
  • 7
  • 16
  • ... but there's no point to be honest. ... why don't you just create new stages and show those instead of creating new applications entirely? – EverNight Oct 21 '19 at 11:57
  • I am kind of new to JavaFX so I do not understand how to pass stages as parameters – K00LDUD3 Oct 22 '19 at 09:01