0

First of all, please do not mark this question as duplicate & close it without going through the whole problem. I have searched for problems similar to mine, but couldn't find any. So I request that you kindly direct me to the post that has a similar problem & then close it.

Now the problem.

I have created a popup window in a JavaFX application. I have two buttons on the main window/stage, pressing either of which generates a new window/stage. However when I close the newly generated popup window and press those buttons on the original window again, it results in JavaFX application thread exception.

Here is the code for the buttons & the action associated with them & it is in the MAIN WINDOW:

public class FirstScene
{
  //.....usual code.....//
    //Creating the buttons
    Button leftClick = new Button("",lftIcon);
    Button rightClick = new Button("", rghtIcon);

    //Adding ACTION to the buttons
    add.setOnAction(ae->LoginFunc.loginHandler("add"));
    remove.setOnAction(ae ->LoginFunc.loginHandler("remove"));

Here's the code for LoginFunc that handles the event & it is in the popup window

public class LoginFunc 
{
    private static String userID, password, button;
    private static Stage loginStage = new Stage();
    static Button login = new Button("Login");
    Scene addScene, removeScene;

    public static void loginHandler(String bttn)
    {
        button = bttn;
        loginStage.setTitle("Movie Database Login");

        loginStage.setMaxHeight(400);
        loginStage.setMaxWidth(400);

        GridPane loginLayout = new GridPane();
        loginLayout.getChildren().add(login);

        Scene loginScene = new Scene(loginLayout,400,400);

        login.setOnAction(eh -> ButtonClicked(eh));


        loginStage.setScene(loginScene);
        loginStage.initStyle(StageStyle.UTILITY);
        loginStage.initModality(Modality.APPLICATION_MODAL);        

        loginStage.show();

    }

    private static void ButtonClicked (ActionEvent eh)
    {
        if(button == "add")
        {
            FirstScene.mainStage.setTitle("Add Window");
            loginStage.close();

        }
        if(button == "remove")
        {
            FirstScene.mainStage.setTitle("Remove Window");
            loginStage.close();

        }
    }   
}

THE PROBLEM IS, once I close the newly generated popup window & press any of the buttons again, it results in the following exception:

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Cannot set style once stage has been set visible
    at javafx.stage.Stage.initStyle(Unknown Source)
    at MovieDataBase.LoginFunc.loginHandler(LoginFunc.java:34)
    at MovieDataBase.FirstScene.lambda$0(FirstScene.java:101)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Node.fireEvent(Unknown Source)
    at javafx.scene.control.Button.fire(Unknown Source)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source)
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyMouse(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

I want to be able to repeat the same window every time the button is pressed.

I'm sorry if this is a very simple problem & a solution already exists, I'm a beginner in Java & what my search resulted in, I couldn't find a single problem that related to mine.

Thank you for your valuable time & input

Auro
  • 1,578
  • 3
  • 31
  • 62
  • 1
    Not related to your question, but something you need to read: http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java In summary, don't use `==` to compare String values. – VGR Jan 18 '16 at 21:25

1 Answers1

0

Your method call to LoginFunc is static and it uses static members of the class. That means that they are initialized and setup when you run through the method for the first time. The second time you call the method, they are already initialized. There are some methods (initStyle is one of them) that can only be called once in the lifecycle of the object.

However there is an easy solution to that: Remove the static modifiers from LoginFunc and create an instance in the event handler before you call the method loginHandler, however retain a reference to it, so you can pass it on the remove method. Or even better separate the logic for adding and removing out of LoginFunc as it is not good decision to trigger behavior upon an input parameter.

You can have a factory method that will provide the event handlers for add and remove and use a boolean to decide which event handler the factory method should return.

public EventHandler<MouseEvent> createButtonClickEventHandler(boolean add) {
  ...
}

Then you can implement the buttons like this:

EventHandler<MouseEvent> addEventHandler = creatButtonClickEventHandler(true);
add.setOnAction(ae->new LoginFunc().loginHandler(addEventHandler));

EventHandler<MouseEvent> removeEventHandler = creatButtonClickEventHandler(false);
remove.setOnAction(ae->new LoginFunc().loginHandler(removeEventHandler));
hotzst
  • 7,238
  • 9
  • 41
  • 64
  • When I try to implement the `public EventHandler createButtonClickEventHandler(booloean add)`, it shows that I have to return a variable of EventHandler type. But I don't want it to return anything. I just want it perform a few computations, but it keeps giving this warning. And when I try to return `EventHandler evt`, it shows `evt` has to be initialized. – Auro Jan 21 '16 at 13:49