Java 如何在单击按钮时调用函数?

Java 如何在单击按钮时调用函数?,java,processing,Java,Processing,我有一个名为Button的处理类,它具有以下函数onClick: class Button() { // Extra code void onClick() { // Run function here } } 它应该在单击按钮时触发函数调用,并从参数中获取函数,如下所示: Button test = new Button(..., callFunction()) 其中callFunction()保证为void函数。单击test后,如何调用函数call

我有一个名为Button的处理类,它具有以下函数
onClick

class Button() {
    // Extra code
    void onClick() {
        // Run function here
    }
}
它应该在单击按钮时触发函数调用,并从参数中获取函数,如下所示:

Button test = new Button(..., callFunction())

其中
callFunction()
保证为
void
函数。单击
test
后,如何调用函数
callFunction()
?我可以检查按钮是否被单击,但我不知道如何将其连接到参数提供的函数调用。

我不确定这是否符合您的目的。但外部处理程序可能很方便

class Button {
    // Extra code
    private ClickHandler handler;

    //Constructor
    Button(..., ClickHandler handler) {
        this.handler = handler;
    }
    void onClick() {
    // Run function here
        handler.handle();
    }
}

interface ClickHandler {
    void handle();
}
现在,您可以创建对象,如:

Button test = new Button(..., new ClickHandler() {
    public void handle() {
        //do your stuff.
    }
});


注意:Java 8可能支持通过lambdas进行回调函数引用。

使用Runnable

Button test = new Button(..., new Runnable(){

     public void run() {
         // your stuff.
         callFunction();
     }
});
然后:

看一看这张照片

它没有封装到类中,这取决于您的实现, 但它确实说明了如何使用Processing的内置
draw()
mousePressed()
方法处理事件

如果有帮助的话,这里有一个button类,我在其中一些应用程序中使用:

int numButtons=3;
按钮[]按钮=新按钮[numButtons];
无效设置(){
规模(180200);
int按钮宽度=150;
int按钮高度=50;
int buttonSpacing=15;
for(int i=0;iisOver=((mx>=x&&mx=y&&my我假设您使用的是Java 8。如果您没有,您应该这样做!因为它与旧版本相比的主要改进之一就是将函数用作参数

要将函数对象(即lambda)作为参数传递,首先需要定义一个函数接口,以某种方式“保存”函数的实现。函数接口可以是仅使用一种方法的任何接口,如下所示:

interface MyFunction {
    public void call();
}
Button test = new Button(..., () -> callFunction());
无论您想在哪里声明它,即使在
按钮
类中也是如此。只要
按钮
可以访问它,这并不重要

然后您只需告诉您的
按钮
构造函数最后一个参数是一个函数,将其存储为私有字段,稍后单击按钮时调用它:

class Button() {
    MyFunction buttonFunction;
    public Button(..., MyFunction myFunction) {
        // ... other initialization ...
        buttonFunction = myFunction;
    }
    // Extra code
    void onClick() {
        // Run function here
        buttonFunction.call();
    }
}
要将函数作为参数传递,请执行以下操作:

interface MyFunction {
    public void call();
}
Button test = new Button(..., () -> callFunction());
您不需要创建一个匿名的
MyFunction
类,也不需要重写任何内容。Java 8为您解决了所有这些问题。它知道
按钮
构造函数需要一个
MyFunction
参数,并且它知道
MyFunction
只有一个方法,
call()
没有参数;因此,当您提供一个没有参数的函数体时,Java知道它是
MyFunction\call()
的实现

事实上,您甚至不需要定义接口:您只需将
MyFunction
替换为
Runnable
,将
call()
替换为
run()
,一切都将按预期工作,因为
Runnable
也是一个功能接口:

class Button() {
    Runnable buttonFunction;
    public Button(..., Runnable myFunction) {
        // ... other initialization ...
        buttonFunction = myFunction;
    }
    // Extra code
    void onClick() {
        // Run function here
        buttonFunction.run();
    }
}

Button test = new Button(..., () -> callFunction());

但是最好先了解基本知识!

我不需要使用导入来使用它吗?我应该使用什么导入?它是标准的java:onClick中的“runnable”是什么?从我看来,它是一个未定义的变量。这不起作用-在
runnable.start()
行上处理错误,说
start()由于某种原因,它不是一个函数。我认为应该是
runnable.run()
。Java完全是关于类和接口的。甚至lambda表达式也有点映射到接口。因此,没有方法或函数引用。您必须使用Runnable或Consumer来定义您的函数。这就是我计划做的,在我解决完这个问题之后——而且,您还没有回答我的问题,因为您已经绕了一圈位。如果回调是您要找的主要内容,请查看上面更新的答案,该答案必须是
public void
-否则,它会工作的!谢谢!@Qwerp Derp我编辑了代码,感谢您指出它!如果有帮助,您可能还希望接受答案:-)处理不支持Java 8,不幸的是…:(听到这个消息我很难过。在这种情况下,马里亚诺的答案是最好的——只需将
start()
替换为
run()
class Button() {
    Runnable buttonFunction;
    public Button(..., Runnable myFunction) {
        // ... other initialization ...
        buttonFunction = myFunction;
    }
    // Extra code
    void onClick() {
        // Run function here
        buttonFunction.run();
    }
}

Button test = new Button(..., () -> callFunction());