Scala使用Java库,利用Java 8中的lambda表达式支持

Spa*_*key 19 lambda scala javafx java-8 javafx-8

根据:http: //docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#lambda-expressions-in-gui-applications

先前:

btn.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        System.out.println("Hello World!");
    }
});
Run Code Online (Sandbox Code Playgroud)

现在,我们可以:

btn.setOnAction(
  event -> System.out.println("Hello World!")
);
Run Code Online (Sandbox Code Playgroud)

现在,我在使用Java库时尝试在Scala中执行此操作.

我正在使用JavaFX(Java 1.8 SE中默认包含它).尝试:

chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Run Code Online (Sandbox Code Playgroud)

但是,我得到:

Error:(204, 46) type mismatch;
 found   : javafx.scene.input.MouseEvent => Unit
 required: javafx.event.EventHandler[_ >: javafx.scene.input.MouseEvent]
    chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
                                             ^
Run Code Online (Sandbox Code Playgroud)

旧样式很好用:

chart.setOnMouseClicked( new EventHandler[MouseEvent] {
  override def handle(event: MouseEvent): Unit = println("NOT NOICE")
} )
Run Code Online (Sandbox Code Playgroud)

我在IntelliJ中将项目语言级别设置为Java 8,我使用的是Scala 2.11.1,以及来自Oracle 1.8.0_05的Java

我在这里错过了什么?或者是否根本无法将Scala中的lambda表达式传递给Java,就像在上述示例中所做的那样?

om-*_*nom 20

对于scala版本2.12以后的支持是开箱即用的.

状态为2.12之前:

Lambdas是用java 语言引入的,与scala函数有一点共同之处.它们被编译成不同的字节码,具有不同的层次结构(scala函数很久以前就已存在,显然java设计者选择了无法与scala兼容的洁净室实现).

目前支持非常有限,你想要做的事情是不可能的(开箱即用):

Scala的2.11系列瞄准Java 6中,与(演进)为Java 8.实验支持在2.11,爪哇8支持大多局限于读取的Java字节码8和解析的Java源8.我们将在2.11系列中扩展Scala(实验性)Java 8支持和互操作.- 详情请见:https: //typesafe.com/blog/scala-211-has-arrived#sthash.ukr4FSpU.dpuf

目前正在努力解决这个问题

另请参阅有关scala路线图的讨论以支持java 8函数.

  • 顺便说一下,你已经回答了我的问题,可能连续3天......我刚才注意到它又是你了! (3认同)
  • @Spacemonkey"跟踪大约2011年的scala用户";-) (3认同)

Oct*_*una 8

实现此目的的一种方法是使用隐式转换,您需要做的是创建一个处理所有这些转换的新Object,如下所示:

import javafx.scene.input.MouseEvent
import javafx.event.EventHandler

object FXEvent2HandlerImplicits{
  implicit def mouseEvent2EventHandler(event:(MouseEvent)=>Unit) = new EventHandler[MouseEvent]{
    override def handle(dEvent:MouseEvent):Unit = event(dEvent)
  }
}
Run Code Online (Sandbox Code Playgroud)

然后只需将其导入到您可能需要转换的任何文件中:

import FXEvent2HandlerImplicits._   
//From now on within scope you can now call events like Java8 Lambdas
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Run Code Online (Sandbox Code Playgroud)

这只是一种语法糖,以更优雅的方式存档相同的东西