Here is an example:
/*
* 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(""))
}
What I send the line BasicLineChart.main(Array(""))
to the console, a JavaFx window shows up with a line chart in it, and the console is blocked. When I close the chart window, I recover access to scala console. When I try to fire up the same window again, I get an error:
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
So I have two questions:
How to launch a JavaFx app in the console without blocking?
How to avoid the above error?
Update 1
Following some advice from freenode, I changed the BasicLineChart into a class and did this:
object Main {
val x = new BasicLineChart()
x.main(Array(""))
val y = new BasicLineChart()
y.main(Array(""))
}
Still got the same error.
On question 2, from a quick look at JFXApp it calls through to javafx.application.Application.launch, docs here. That page describes the life cycle, indicating that launch must only be called once. Basically JFXApp expects to be the entry point for a whole application, so shouldn't be called multiple times.
If you want to be able to quickly relaunch your app, I would consider just running it from SBT using run or runMain rather than using the console.
On question 1, if you do decide to run from SBT you should be able to fork in run, there are details in the SBT docs, specifically try adding fork in run := true
to build.sbt
.
来源:https://stackoverflow.com/questions/32630052/open-and-close-javafx-apps-in-scala-console