Reputation: 31
I am new to creating GUI using scalafx. I am trying to create two scenes with the following code but getting some error
import com.sun.glass.ui.Application
import scalafx.event.ActionEvent
import scalafx.event.EventHandler
import scalafx.scene.Scene
import scalafx.scene.control.Button
import scalafx.scene.control.Label
import scalafx.scene.layout.StackPane
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
class example extends Application {
var scene1: Scene = null
var scene2: Scene = null
override def start(primaryStage: Stage): Unit = { primaryStage.setTitle("My First JavaFX GUI")
//Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2"){
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.getChildren.addAll(label1, button1)
scene1 = new Scene(layout1, 300, 250)
//Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
primaryStage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.getChildren.addAll(label2, button2)
scene2 = new Scene(layout2, 300, 250)
primaryStage.setScene(scene1)
primaryStage.show()
}
}
The error is:
found : scalafx.event.ActionEvent => Unit
[error] required: javafx.event.EventHandler[javafx.event.ActionEvent]
[error] onAction = (e: ActionEvent) => {}
How can I declare the action events to switch between the scenes?
It would be really helpful if anyone can help
Upvotes: 1
Views: 194
Reputation: 1533
In ScaleFX, your first troubleshooting is to check if you included the ScaleFX implicit conversion magic:
import scalafx.Includes._
In your case, that will fix the issue with the action handler.
Additionally, you should not use com.sun
packages neither in ScalaFX nor in JavaFX code. In ScalaFX you should use JFXApp3
instead. Here is your code corrected to use JFXApp3
with some minor corrections:
import scalafx.Includes._
import scalafx.application.JFXApp3
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.event.{ActionEvent, EventHandler}
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
import scalafx.stage.Stage
object CreteTwoScenes1App extends JFXApp3 {
var scene1: Scene = _
var scene2: Scene = _
override def start(): Unit = {
stage = new PrimaryStage {
title = "My First JavaFX GUI"
}
// Scene 1
val label1 = new Label("This is the first scene")
val button1 = new Button("Go to scene 2") {
onAction = (e: ActionEvent) => {
stage.setScene(scene2)
}
}
val layout1 = new VBox(20)
layout1.children ++= Seq(label1, button1)
scene1 = new Scene(layout1, 300, 250)
// Scene 2
val label2 = new Label("This is the second scene")
val button2 = new Button("Go to scene 1") {
onAction = (e: ActionEvent) => {
stage.setScene(scene1)
}
}
val layout2 = new VBox(20)
layout2.children ++= Seq(label2, button2)
scene2 = new Scene(layout2, 300, 250)
stage.setScene(scene1)
}
}
You can also rewrite that in more idiomatic ScalaFX builder style. Using Scala 3 can make it much more compact too (no curly braces needed):
import scalafx.Includes.*
import scalafx.application.JFXApp3
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.scene.layout.VBox
object CreteTwoScenes2App extends JFXApp3:
override def start(): Unit =
lazy val scene1: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the first scene"),
new Button("Go to scene 2"):
onAction = () => stage.setScene(scene2)
)
lazy val scene2: Scene = new Scene(300, 200):
root = new VBox(20):
children = Seq(
new Label("This is the second scene"),
new Button("Go to scene 1"):
onAction = () => stage.setScene(scene2)
)
stage = new JFXApp3.PrimaryStage:
title = "My First JavaFX GUI"
scene = scene1
Upvotes: 1