scala javafx fxml

Comenzando en el desarrollo de aplicaciones de escritorio Scala+JavaFX



fxml (3)

Hay algunas cosas que debe saber al escribir aplicaciones JavaFX basadas en Scala.

Primero, aquí hay una muestra de la aplicación hola mundo:

import javafx.application.Application import javafx.scene.Scene import javafx.scene.layout.StackPane import javafx.stage.Stage import javafx.scene.control.Label class Test extends Application { println("Test()") override def start(primaryStage: Stage) { primaryStage.setTitle("Sup!") val root = new StackPane root.getChildren.add(new Label("Hello world!")) primaryStage.setScene(new Scene(root, 300, 300)) primaryStage.show() } } object Test { def main(args: Array[String]) { Application.launch(classOf[Test], args: _*) } }

Al ejecutarlo debes obtener:

Aquí hay un ejemplo oficial de hello world en Java: http://docs.oracle.com/javafx/2/get_started/hello_world.htm

Las principales diferencias son:

  • Debe escribir el denominado objeto complementario con la def main() que inicia la aplicación real.
  • Application.launch(classOf[Test], args: _*) especificar que se ejecutará en el contexto de la clase Test y no del objeto complementario: Application.launch(classOf[Test], args: _*) .

Si solo intenta ejecutar la aplicación directamente con Application.launch(args : _*) obtendrá este error:

Excepción en el hilo "main" java.lang.RuntimeException: Error: la clase Test $ no es una subclase de javafx.application.Application

Para obtener más información sobre JavaFX, simplemente lea la documentación oficial: http://docs.oracle.com/javafx/index.html

¿Existe alguna guía o tutorial para crear una aplicación de escritorio Scala + JavaFX?

Estoy teniendo dificultades para encontrar una buena fuente y estoy utilizando IntelliJ IDEA como IDE.

Incluso las muestras de hello world de escritorio más simplistas me ayudarían mucho, porque tengo poca idea de por dónde empezar.

Actualización: Esto es lo que tengo ahora:

import javafx.application.Application import javafx.scene.Scene import javafx.scene.layout.StackPane import javafx.stage.Stage import javafx.scene.control.Label class Test extends Application { override def start(primaryStage: Stage) { primaryStage.setTitle("Sup!") val root = new StackPane root.getChildren.add(new Label("Hello world!")) primaryStage.setScene(new Scene(root, 300, 300)) primaryStage.show() } } object Test { def main(args: Array[String]) { val t = new Test t.start(new Stage) } }

Al ejecutarlo me sale:

Excepción en el hilo "main" java.lang.IllegalStateException: No en el hilo de la aplicación FX; currentThread = main

¿Cómo puedo hacer que muestre la ventana de hello world con la etiqueta?


Pude resolver este problema en scala_swing mucho más satisfactoriamente, ya que podría crear una instancia con parámetros y luego llamar a main para iniciar Swing más tarde.

Esta solución permite que los parámetros se obtengan en la aplicación FX a costa del uso de variables estáticas y otros posibles problemas. Una de ellas es que esto seguramente no es multihilo seguro.

package hack /** * Created by WorkDay on 8/11/16.<br> * <br> * HelloTest shows a method which allows parameters to be passed * into your javaFX application as it is started * this allows it to be connected to non-FX code that existed before it. * * You could also pass a reference to the Application back * into the non-FX code if needed. */ import javafx.application.Application import javafx.scene.Scene import javafx.scene.layout.StackPane import javafx.stage.Stage import javafx.scene.control.Label case class Data(data: String) object SomeOtherCode extends App { HelloTest.launch(Data("brave"), Data("new")) } object HelloTest { var data1: Data = _ var data2: Data = _ def launch(data1: Data, data2: Data) = { HelloTest.data1 = data1 HelloTest.data2 = data2 Application.launch(classOf[HelloTest]) } } private class HelloTest extends Application { val data1: Data = HelloTest.data1 val data2: Data = HelloTest.data2 override def start(primaryStage: Stage) { primaryStage.setTitle("Sup!") val root = new StackPane root.getChildren.add(new Label(s"Hello ${data1.data} ${data2.data} world!")) primaryStage.setScene(new Scene(root, 300, 300)) primaryStage.setX(0) primaryStage.setY(0) primaryStage.show() } }


Se puede utilizar de esta manera.

class BuildFx extends Application{ override def start(primaryStage: Stage): Unit = { primaryStage.setTitle("Scala") var btn=new Button("Say Hello Scala") val root=new StackPane() root.getChildren().add(btn) primaryStage.setScene(new Scene(root, 300, 300)) primaryStage.show() } def launchIt():Unit={ Application.launch() } } /////////////////////////////////////////////////////////// object Init{ def main(args: Array[String]): Unit = { val buildFx=new BuildFx buildFx.launchIt() } }