【问题标题】:Action doesn't repeat on button press JavaFX按下按钮时动作不会重复 JavaFX
【发布时间】:2016-04-24 02:35:41
【问题描述】:

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

现在问题来了。

我在 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 初学者,我的搜索结果是什么,我找不到与我相关的单个问题。

感谢您宝贵的时间和意见

【问题讨论】:

标签: java user-interface exception button javafx


【解决方案1】:

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

但是有一个简单的解决方案:从LoginFunc 中删除静态修饰符并在调用方法loginHandler 之前在事件处理程序中创建一个实例,但是保留对它的引用,以便您可以传递它删除方法。 或者甚至更好地将用于添加和删除的逻辑从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));

【讨论】:

  • 当我尝试实现public EventHandler&lt;MouseEvent&gt; createButtonClickEventHandler(booloean add)时,它表明我必须返回一个EventHandler类型的变量。但我不希望它返回任何东西。我只希望它执行一些计算,但它一直发出这个警告。当我尝试返回EventHandler evt 时,它显示evt 必须被初始化。
猜你喜欢
  • 1970-01-01
  • 2013-01-30
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
  • 2020-10-17
相关资源
最近更新 更多