繁体   English   中英

按下按钮不重复操作

[英]Action doesn't repeat on button press JavaFX

首先,请不要将此问题标记为重复问题并在未解决整个问题的情况下将其关闭。 我已经搜索了与我相似的问题,但找不到任何问题。 因此,我请您将我引到一个有类似问题的职位上,然后关闭它。

现在的问题。

我已经在JavaFX应用程序中创建了一个弹出窗口。 我在主窗口/舞台上有两个按钮,按下其中任一按钮都会生成一个新窗口/舞台。 但是,当我关闭新生成的弹出窗口并再次按原始窗口上的那些按钮时,将导致JavaFX应用程序线程异常。

这是按钮的代码以及与它们关联的操作,它位于主窗口中

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"));

这是处理事件的LoginFunc的代码,它在弹出窗口中

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

        }
    }   
}

问题是 ,一旦我关闭了新生成的弹出窗口并再次按下任何一个按钮,就会导致以下异常:

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)

我希望每次按下按钮都可以重复相同的窗口。

很抱歉,如果这是一个非常简单的问题,并且已经存在解决方案,我是Java的初学者,我的搜索结果是什么,我找不到与我的问题相关的单个问题。

感谢您的宝贵时间和投入

您对LoginFunc方法调用是静态的,它使用该类的静态成员。 这意味着,当您第一次运行该方法时,它们将被初始化和设置。 第二次调用该方法时,它们已经被初始化。 有些方法( initStyle是其中的一种)只能在对象的生命周期中调用一次。

但是,有一个简单的解决方案:在调用方法loginHandler之前,从LoginFunc删除静态修饰符并在事件处理程序中创建实例,但是保留对其的引用,因此可以将其传递给remove方法。 甚至更好地将用于添加和删除LoginFunc的逻辑分开,因为这不是触发输入参数行为的明智决定。

您可以有一个工厂方法,该方法将提供用于添加和删除的事件处理程序,并使用布尔值确定工厂方法应返回哪个事件处理程序。

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

然后,您可以实现以下按钮:

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

EventHandler<MouseEvent> removeEventHandler = creatButtonClickEventHandler(false);
remove.setOnAction(ae->new LoginFunc().loginHandler(removeEventHandler));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM