在scala控制台中打开和关闭JavaFx应用程序

时间:2015-09-17 12:13:06

标签: scala javafx scalafx

以下是一个例子:

/*
 * Copyright 2013 ScalaFX Project
 * All right reserved.
 */
package scalafx.ensemble.example.charts

import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.LineChart
import scalafx.scene.chart.NumberAxis
import scalafx.scene.chart.XYChart

/** A chart in which lines connect a series of data points. Useful for viewing
  * data trends over time.
  *
  * @see scalafx.scene.chart.LineChart
  * @see scalafx.scene.chart.Chart
  * @see scalafx.scene.chart.Axis
  * @see scalafx.scene.chart.NumberAxis
  * @related charts/AreaChart
  * @related charts/ScatterChart
  */
object BasicLineChart extends JFXApp {

  stage = new JFXApp.PrimaryStage {
    title = "Line Chart Example"
    scene = new Scene {
      root = {

        val xAxis = NumberAxis("Values for X-Axis", 0, 3, 1)
        val yAxis = NumberAxis("Values for Y-Axis", 0, 3, 1)

        // Helper function to convert a tuple to `XYChart.Data`
        val toChartData = (xy: (Double, Double)) => XYChart.Data[Number, Number](xy._1, xy._2)

        val series1 = new XYChart.Series[Number, Number] {
          name = "Series 1"
          data = Seq(
            (0.0, 1.0),
            (1.2, 1.4),
            (2.2, 1.9),
            (2.7, 2.3),
            (2.9, 0.5)).map(toChartData)
        }

        val series2 = new XYChart.Series[Number, Number] {
          name = "Series 2"
          data = Seq(
            (0.0, 1.6),
            (0.8, 0.4),
            (1.4, 2.9),
            (2.1, 1.3),
            (2.6, 0.9)).map(toChartData)
        }

        new LineChart[Number, Number](xAxis, yAxis, ObservableBuffer(series1, series2))
      }
    }
  }
}

object Main {
  BasicLineChart.main(Array(""))
}

我将行BasicLineChart.main(Array(""))发送到控制台,JavaFx窗口显示其中包含折线图,并且控制台被阻止。当我关闭图表窗口时,我恢复了对scala控制台的访问。当我再次尝试启动同一个窗口时,出现错误:

scala>   BasicLineChart.main(Array(""))
java.lang.IllegalStateException: Application launch must not be called more than once
  at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:162)
  at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:143)
  at javafx.application.Application.launch(Application.java:191)
  at scalafx.application.JFXApp$class.main(JFXApp.scala:242)
  at BasicLineChart$.main(<console>:23)
  ... 35 elided

所以我有两个问题:

  1. 如何在控制台中启动JavaFx应用程序而不阻止?

  2. 如何避免上述错误?

  3. 更新1

    根据freenode的一些建议,我将BasicLineChart更改为一个类并执行了此操作:

    object Main {
      val x = new BasicLineChart()
      x.main(Array(""))
      val y = new BasicLineChart()
      y.main(Array(""))
    }
    

    仍有同样的错误。

1 个答案:

答案 0 :(得分:4)

在问题2上,快速查看JFXApp,它会调用javafx.application.Application.launch,docs here。该页面描述了生命周期,表明只能调用一次启动。基本上JFXApp希望成为整个应用程序的入口点,因此不应多次调用。

如果您希望能够快速重新启动应用程序,我会考虑使用run或runMain而不是使用控制台从SBT运行它。

问题1,如果您决定从SBT运行,您应该能够分叉运行,SBT docs中有详细信息,特别是尝试将fork in run := true添加到build.sbt