tutorial - Scala utilizando bibliotecas de Java, aprovechando el soporte de expresiones lambda en Java 8
instrucciones lambda java (2)
De acuerdo con: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#lambda-expressions-in-gui-applications
Previamente:
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
Ahora podemos:
btn.setOnAction(
event -> System.out.println("Hello World!")
);
Ahora, trato de hacer eso en Scala cuando uso una biblioteca de Java.
Estoy usando JavaFX (que se incluye de forma predeterminada en Java 1.8 SE). Tratar:
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Sin embargo, me sale:
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") )
^
El viejo estilo funciona bien:
chart.setOnMouseClicked( new EventHandler[MouseEvent] {
override def handle(event: MouseEvent): Unit = println("NOT NOICE")
} )
Establecí el nivel de idioma del proyecto en Java 8 en IntelliJ, estoy usando Scala 2.11.1 y Java desde Oracle versión 1.8.0_05
¿Que me estoy perdiendo aqui? ¿O simplemente no es posible pasar una expresión lambda de Scala a Java de la misma manera que se hace en el ejemplo mencionado?
Para las versiones 2.12 de Scala, el soporte saldrá de la caja.
Estado para pre-2.12:
Lambdas se introdujo en lenguaje java y tiene un poco en común con las funciones de scala. Se compilan a un código de bytes diferente , tienen una jerarquía diferente (las funciones de scala estuvieron aquí mucho antes y, aparentemente, los diseñadores de Java han elegido la implementación de sala limpia sin compatibilidad con scala).
Actualmente el soporte es bastante limitado y lo que estás tratando de hacer no es posible (listo para usar):
La serie Scala 2.11 se enfoca en Java 6, con soporte experimental (en evolución) para Java 8. En 2.11, el soporte de Java 8 se limita principalmente a leer el código de bytes de Java 8 y analizar la fuente de Java 8. Estaremos ampliando el soporte de Java 8 (experimental) de Scala e interoperando a lo largo de la serie 2.11. - Vea más en: https://typesafe.com/blog/scala-211-has-arrived#sthash.ukr4FSpU.dpuf
Hay esfuerzos en curso para resolver este problema
Consulte también la discusión sobre la hoja de ruta de Scala para admitir las funciones de Java 8 .
Una forma de lograr esto es mediante transformaciones implícitas. Lo que debe hacer es crear un nuevo Objeto que maneje todas estas transformaciones, algo como esto:
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)
}
}
Luego simplemente impórtelo en cualquier archivo que necesite la transformación:
import FXEvent2HandlerImplicits._
//From now on within scope you can now call events like Java8 Lambdas
chart.setOnMouseClicked( (e: MouseEvent) => println("Noice") )
Esto es solo azúcar sintáctica para archivar lo mismo de una manera más elegante.