java - button.onActionProperty().addListener 在 javafx 中不起作用

标签 java events javafx

我是 Java 的新手,正在尝试 Java 事件,但我完全迷路了。我知道 C# 中的事件没有问题,它们工作得很好,但 Java 是不同的宇宙。我试图在 Internet 上找到一些东西,但很长时间都弄不明白,所以我来了。

我有一个对象,我需要触发一些 Action 。触发此操作时,我不仅需要调用一个事件处理程序,还需要从不同的对象调用更多事件处理程序。

例如,我只使用 Button 类。

有两种方法可以做到这一点:

一种方法是使用button.setOnAction 方法。但这不起作用,因为当我第二次(从另一个对象)调用此方法时,我只是将一个事件处理程序替换为另一个。您可以在 initEventsUselessWay() 方法的代码中看到我的意思。

第二种方式是使用button.onActionProperty().addListener。但这根本不起作用。您可以在方法 initEventsNeededWay() 中看到。

那么,为什么 button.onActionProperty().addListener 不起作用?

有什么办法可以在 Javafx 中做到这一点吗?

最后我不会使用 Button 类,而是像 MyClass 这样的东西,我需要在这里实现它。但是,如果这不适用于 Button 类,它也不会适用于 MyClas。

非常感谢您的建议。

package sample;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class JavaEventsTest1589 extends Application {
private Button btnDemo1;
private Button btnDemo2;

@Override
public void start(Stage primaryStage) {
    // panel
    Pane rootPane = new Pane();

    // scene
    Scene scene = new Scene(rootPane, 300, 250);
    primaryStage.setTitle("events demo");
    primaryStage.setScene(scene);

    // button 1
    btnDemo1 = new Button();
    rootPane.getChildren().add(btnDemo1);
    btnDemo1.setText("Execute Demo 1");
    btnDemo1.setLayoutX(50);
    btnDemo1.setLayoutY(10);

    // button 2
    btnDemo2 = new Button();
    rootPane.getChildren().add(btnDemo2);
    btnDemo2.setText("Execute Demo 2");
    btnDemo2.setLayoutX(50);
    btnDemo2.setLayoutY(50);

    initEventsUselessWay();

    initEventsNeededWay();

    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}

private void initEventsUselessWay() {

    btnDemo1.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            runDemoPrimaryReaction();
        }
    });

    btnDemo1.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            runDemoSecondaryReaction();
        }
    });
}

private void initEventsNeededWay() {

    btnDemo2.onActionProperty().addListener(new ChangeListener<EventHandler<ActionEvent>>() {
        @Override
        public void changed(ObservableValue<? extends EventHandler<ActionEvent>> observableValue, EventHandler<ActionEvent> actionEventEventHandler, EventHandler<ActionEvent> actionEventEventHandler2) {
            runDemoThisINeed_No1();
        }
    });

    btnDemo2.onActionProperty().addListener(new ChangeListener<EventHandler<ActionEvent>>() {
        @Override
        public void changed(ObservableValue<? extends EventHandler<ActionEvent>> observableValue, EventHandler<ActionEvent> actionEventEventHandler, EventHandler<ActionEvent> actionEventEventHandler2) {
            runDemoThisINeed_No2();
        }
    });

}

private void runDemoPrimaryReaction() {
    System.out.println("useless way - primary reaction");
}

private void runDemoSecondaryReaction() {
    System.out.println("useless way - secondary reaction");
}

private void runDemoThisINeed_No1() {
    System.out.println("not working way - No1");
}

private void runDemoThisINeed_No2() {
    System.out.println("not working way - No2");
}

}

最佳答案

使用 addEventHandler:

btnDemo1.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
        runDemoPrimaryReaction();
    }
});

btnDemo1.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
        runDemoSecondaryReaction();
    }
});

我建议使用 Java 8,这样你就可以写

btnDemo1.addEventHandler(ActionEvent.ACTION, event -> runDemoPrimaryReaction());
btnDemo1.addEventHandler(ActionEvent.ACTION, event -> runDemoSecondaryReaction());

setOnAction(...)方法是一种“方便”的方法。它的工作方式是 Button维护一个 ObjectProperty<EventHandler<ActionEvent>>.如果您设置此属性的值(设置为 EventHandler<ActionEvent> ),该事件处理程序将自动添加到按钮的事件处理程序中。如果您第二次设置它,因为它只是一个属性,它将替换现有的事件处理程序。因此,在只有一个处理程序的情况下,您可以将其用于一种稍微更快的方法。 (它也可以很好地与 FXML 配合使用。)

onActionProperty().addListener(...)完全是另一回事:它监听属性本身的变化。所以如果你用这种方式注册一个监听器,那么调用setOnAction(...) ,当您调用 setOnAction 时,将调用您在属性中注册的监听器(不是在按下按钮时)。

看看 tutorial ,特别是第一部分“处理事件”和第二部分“使用便捷方法”。第二部分明确了 setOnAction 实际执行的时间。

关于java - button.onActionProperty().addListener 在 javafx 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22744334/

相关文章:

java - 如何将本地项目连接到github仓库

java - 为什么.class 不调用类中的静态 block ?

java - 使用 BigInteger 进行素数检查(参数不匹配)

java - lib 升级后 iText pdf 功能损坏 - 无法合并表格

用于服务器端图像生成的 JavaFX

netbeans - 如何使用场景构建器在 java fxml 上制作图像按钮?

c# - 在 C# 中为所有事件和委托(delegate)创建一个包罗万象的处理程序

java - 在 JTabbedPane 上触发 stateChanged 事件

c# - 为什么我的事件抛出空错误?

找不到 JavaFX 类 : Is this an error in Java FX or in my code?