我是 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/