javafx event.getSource() 未按预期工作

javafx event.getSource() not working as expected

提问人:rado_rud 提问时间:11/15/2023 最后编辑:rado_rud 更新时间:11/15/2023 访问量:72

问:

我想寻求有关event.getSource()的帮助。我已经开始学习 JavaFx,互联网上的所有教学视频都说这样做,请参阅基本代码。 但是,event.getSource() 生成的输出只是对 button(Button@4454de36[styleClass=button]'Write') 的引用,因此显然没有与 if 语句中的字符串进行比较。因此,btn 点击什么也做不了。什么是工作解决方案?

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.layout.StackPane;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;

 
public class HelloWorld extends Application implements EventHandler<ActionEvent> {
    
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        // TODO Auto-generated method stub
        Button btn = new Button("Write");
        
        btn.setOnAction(this);
        
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        Scene sc = new Scene(root, 200, 100);
        primaryStage.setScene(sc);
        primaryStage.show();
    }
    
    @Override
    public void handle(ActionEvent event){
        System.out.println(event.getSource());
        if(event.getSource() == "btn"){
        System.out.println("Hello World");
        }
    }
}

我尝试使用event.getSource()。以某种方式分离按钮的名称,但没有任何效果。输出仍然相同。

JavaFX 事件处理

评论

1赞 James_D 11/15/2023
这不是在 JavaFX 中处理事件的方法。对每个控件使用不同的事件处理程序(因此无需测试事件的源)。使用 lambda 表达式(或至少一个匿名类)来实现每个处理程序。
1赞 James_D 11/15/2023
在视频中,他将事件源与实际的按钮引用进行比较,而不是与按钮(或任何其他)中的文本进行比较。如果你以同样的方式做,它就会起作用。不过,这是一种完全不可扩展且荒谬的方法。你不应该盲目地复制你在网上找到的废话,而没有批判性地评估它。String
1赞 Slaw 11/16/2023
"你能更具体地解释一下为什么吗?-- 它违反了SOLID原则(特别是单一责任原则)。子类表示整个应用程序及其生命周期。它不是事件处理程序,事件处理程序也不是应用程序。此外,事件处理程序通常是轻量级的;他们只是在适当的时候调用一些其他代码来实现“操作”。在大多数情况下,使用一个成熟的类来实现事件处理程序是没有意义的。只需使用 lambda 表达式或方法引用即可。Application
1赞 Slaw 11/16/2023
"为什么人们在instr.vids中显示这一点?-- 可能是多种原因。也许讲师并不是一个伟大的软件工程师。也许教师认为打破某些“规则”会更容易教授特定概念,但未能澄清“规则”被打破。也许教师觉得某些概念是在教授其他更基础的概念之后才教授的。也许教练只是懒惰。也许它是 Java 8 之前编写的教程的遗留物(添加了 lambda 表达式/方法引用)。
1赞 Slaw 11/16/2023
或者也许是我没有想到的其他原因。

答:

3赞 jewelsea 11/15/2023 #1

视频中的代码之所以有效,是因为它不是将事件源与 String 进行比较,而是将其与按钮进行比较。

无论如何,这种方法是次优的,不要编写这样的代码,在其中实现开关或测试以在事件处理程序中查找源。

您正在按钮上设置事件处理程序,因此您已经知道事件处理程序应用于哪个按钮 - >您不需要测试来查找应用了哪个按钮,也不需要对所有按钮使用一个事件处理程序。

相反,为每个按钮创建一个新的事件处理程序。这可以使用 lambda 表达式轻松完成:

button.setOnAction(e -> doSomething());

其中 是执行操作时要执行的某个方法的名称。doSomething()

Eden 教程解释了如何处理按钮事件:

Eden 文章中的示例代码(略有修改):

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ButtonEventExampleApp extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        //Create Scene Graph
        Button button = new Button("Press me!");
        StackPane root = new StackPane(button);
        Scene scene = new Scene(root, 300, 250);
        
        //Define Button Action
        Label label = new Label("Pressed!");
        button.setOnAction(event -> 
            root.getChildren().setAll(label)
        );

        //Create Window
        primaryStage.setTitle("Button Example App");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

评论

0赞 rado_rud 11/15/2023
谢谢你的链接,我将专注于这些教程。我是这个领域的初学者,所以欢迎所有有价值的信息。