Подтвердить что ты не робот

Начало работы в Scala + разработке приложений для JavaFX

Есть ли какое-нибудь руководство или пошаговое руководство для создания рабочего стола Scala + JavaFX?

Мне сложно найти хороший источник, и я использую IntelliJ IDEA в качестве среды IDE.

Даже самые упрощенные образцы рабочего стола hello world помогут много, потому что у меня мало подсказки, с чего начать.

Обновление: Это то, что у меня есть сейчас:

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

Запустив его, я получаю:

Исключение в потоке "main" java.lang.IllegalStateException: не на FX прикладная нить; currentThread = main

Как я могу заставить его отображать окно hello world с меткой?

4b9b3361

Ответ 1

Есть несколько вещей, которые нужно знать при написании приложений JavaFX на основе Scala.

Во-первых, здесь пример приложения hello world:

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

Запустив его, вы должны получить:

enter image description here

Вот официальный пример приветствия в Java: http://docs.oracle.com/javafx/2/get_started/hello_world.htm

Основные отличия:

  • Вы должны написать так называемый объект-компаньон с def main(), который запускает фактическое приложение.
  • Вы должны указать, что он будет запущен в контексте класса Test, а не сопутствующего объекта: Application.launch(classOf[Test], args: _*).

Если вы просто попытаетесь запустить приложение напрямую с помощью Application.launch(args : _*), вы получите эту ошибку:

Исключение в потоке "main" java.lang.RuntimeException: Ошибка: class Тест $не является подклассом javafx.application.Application

Чтобы узнать больше о JavaFX, просто прочитайте официальную документацию: http://docs.oracle.com/javafx/index.html

Ответ 2

Я смог решить эту проблему в scala_swing гораздо более удовлетворительно, потому что вы могли бы создать экземпляр с параметрами, а затем вызвать main на нем, чтобы начать Swing позже.

Это решение позволяет получить параметры в приложении FX за счет использования статических переменных и возможных других проблем. Одно из них заключается в том, что это, безусловно, не многопоточное безопасно.

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

Ответ 3

Вы можете использовать этот способ.

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

  }
}