Introducción al desarrollo de aplicaciones de escritorio Scala + JavaFX

Is there some guide or walkthrough to building a Scala + JavaFX desktop application?

I'm having hard time finding a good source and I am using IntelliJ IDEA as the IDE.

Even the most simplistic desktop hello world samples would help a lot, because I have little clue where to start.

Actualizar: 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)
  }
}

Ejecutándolo me sale:

Exception in thread "main" java.lang.IllegalStateException: Not on FX application thread; currentThread = main

How can I get it to display the hello world window with the label?

preguntado el 25 de agosto de 12 a las 19:08

Have you successfully written anything in JavaFX before using just Java? Which IDE did you use? -

@LuigiPlinge No I just found about JavaFX, and I started learning Scala a month ago or so. I'm using IntelliJ IDE. -

I would get started by following the examples on the Oracle website. oracle.com/technetwork/java/javafx/documentation/index.html Make sure you can get it running with Java, then maybe try translating the examples into Scala. You might also be interested in ScalaFX, which is an ongoing project to produce idiomatic Scala bindings for the library. code.google.com/p/scalafx -

@LuigiPlinge I've updated my question with code. Do you have any idea how to continue from where I've left off? -

3 Respuestas

There are a few things to know when writing Scala based JavaFX applications.

First, here's a sample hello world app:

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: _*)
  }
}

Running it you should get:

enter image description here

Here's an official hello world example in Java: http://docs.oracle.com/javafx/2/get_started/hello_world.htm

Las principales diferencias son:

  • You have to write the so-called companion object with the def main() that launches the actual application.
  • You have to specify that it will be run in context of the class Test, and not the companion object: Application.launch(classOf[Test], args: _*).

If you just try to run the application directly with Application.launch(args : _*) obtendrá este error:

Exception in thread "main" java.lang.RuntimeException: Error: class Test$ is not a subclass of javafx.application.Application

To learn more about JavaFX, just read the official documentation: http://docs.oracle.com/javafx/index.html

Respondido 26 ago 12, 14:08

Puedes usarlo 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()

  }
}

Respondido el 15 de Septiembre de 17 a las 21:09

I was able to solve this problem in scala_swing much more satisfactorily because you could instantiate an instance with parameters then call main on it to start Swing later.

This solution allows parameters to be obtained in the FX application at the cost of using static var and possible other issues. One being that this is surely not multi-thread safe.

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()
  }
}

Respondido 13 ago 16, 10:08

desbordamiento de pila is not a forum, so answers cannot contain questions. If you have a question please open a new question, and leave the answer as a stand alone answer. - Brian Tompsett - 汤 莱恩

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.