Scala How to change window size - scala

I would like to change the size of my window application. I am using scene builder for this project. In the preview, the size of my fxml is the size that I want. However, when I try to run it with my windows it will show the application in a slightly small size. My question is how can I make the window application size the same as the size of the preview. In another word, I want to make my window application to the exact size that I want. Below attach my code.
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.Includes._
import scalafxml.core.{NoDependencyResolver, FXMLView, FXMLLoader}
import javafx.{scene => jfxs}
import scalafx.scene.image.Image
object MainApp extends JFXApp {
// transform path of RootLayout.fxml to URI for resource location.
val rootResource = getClass.getResource("view/RootLayout.fxml")
// initialize the loader object.
val loader = new FXMLLoader(rootResource, NoDependencyResolver)
// Load root layout from fxml file.
loader.load();
// retrieve the root component BorderPane from the FXML
val roots = loader.getRoot[jfxs.layout.BorderPane]
// initialize stage
stage = new PrimaryStage {
title = "TalkShow"
scene = new Scene {
root = roots
}
}
// actions for display person overview window
def showTalkOverview() = {
val resource = getClass.getResource("view/TalkShow.fxml")
val loader = new FXMLLoader(resource, NoDependencyResolver)
loader.load();
val roots = loader.getRoot[jfxs.layout.AnchorPane]
this.roots.setCenter(roots)
}
def showWelcome() = {
val resource = getClass.getResource("view/Welcome.fxml")
val loader = new FXMLLoader(resource, NoDependencyResolver)
loader.load();
val roots = loader.getRoot[jfxs.layout.AnchorPane]
this.roots.setCenter(roots)
}
// call to display PersonOverview when app start
showWelcome()
}

Related

'OnCreateView' Overrides = nothing

im new to alot of this, trying to combine two projects together in Android Studio,
im getting an error of the bellow code. Line 52, "override fun onCreateView(" giving me a error overrides nothing. can anyone fix this code? searching elsewhere on this site talks about "Kotlin '?' indicates that this value can be null in Kotlin." but im struggling to fix it. Thank you xx
package com.example.version4.ui.map
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.example.version4.R
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
class MapsFragment : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.text_map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val OrchidsSpa = LatLng(52.316296, -2.261900)
mMap.addMarker(MarkerOptions().position(OrchidsSpa).title("Marker in Bryony's # Orchids Spa"))
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(OrchidsSpa,12F))
}
private lateinit var mapsViewModel: MapsViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mapsViewModel =
ViewModelProviders.of(this).get(MapsViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_maps, container, false)
val textView: TextView = root.findViewById(R.id.text_map)
mapsViewModel.text.observe(this, Observer {
textView.text = it
})
return root
}
}
onCreateView is in Fragment, not AppCompatActivity.

Scalafx. Start the Alert by Timer

I have a main window with some information. I can't start the Alert by timer. I need to show alert every 10 seconds(with working main window) and by the alert's button change the Label's text in the main window.
I have this code, but it's not work:
object main extends JFXApp {
stage = new JFXApp.PrimaryStage() {
scene = new Scene {
val MyLabel = new Label("SomeText")
root = new VBox {
children = MyLabel
}
}
val ButtonTypeOne = new ButtonType("Change the text")
val ButtonTypeTwo = new ButtonType("No")
val alert1 = new Alert(AlertType.Warning) {
initOwner(stage)
title = "Warning!!!"
headerText = "Header"
contentText = "Do you need to change the text?"
buttonTypes = Seq(ButtonTypeOne, ButtonTypeTwo, ButtonType.Cancel)
}
val result = alert1.showAndWait()
val timerA = new PauseTransition(Duration(5000))
timerA.onFinished = { _ =>
result match {
case Some(ButtonTypeOne) => /*Here I need to change text in MyLabel */
case Some(ButtonTypeTwo) => None
case _ => None
}
timerA.playFromStart()
}
timerA.play
}
}
There are a few different problems in your code:
You display the alert only once, regardless of what's happening with the timer.
The code that reacts to the result of the alert in the timer always looks at the same initial result.
Unfortunately, even if you move the val result = alert1.showAndWait inside of the timer's animation update event, JavaFX makes it illegal to call showAndWait within such a routine.
The solution is to create an onHidden event handler for alert1, which reacts to it being closed. The button type used to close the dialog is then stored in alert1.result, so you can use that to determine what action to take.
I've added a StringProperty to assist with the changing of the label value. The following example should be a good starting point for what you want to achieve...
import scalafx.Includes._
import scalafx.animation.PauseTransition
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.StringProperty
import scalafx.scene.Scene
import scalafx.scene.layout.VBox
import scalafx.scene.control.{Alert, ButtonType, Label}
import scalafx.scene.control.Alert.AlertType
import scalafx.util.Duration
object main extends JFXApp {
// String property for the text in myLabel.
val strProp = StringProperty("Some Text")
// Declare this so that it's accessible from timerA.onFinished.
val myLabel = new Label {
// Bind the text property to the value of strProp.
// When strProp's value changes, so does the label's text.
text <== strProp
}
stage = new PrimaryStage() {
scene = new Scene {
root = new VBox {
children = myLabel
}
}
}
// Custom buttons.
val ButtonTypeOne = new ButtonType("Change the text")
val ButtonTypeTwo = new ButtonType("No")
// Create the timer. This goes off after 5,000ms (5 seconds) - after play is called.
val timerA = new PauseTransition(Duration(5000))
// Alert dialog.
// Note: JavaFX forbids use of showAndWait within animation processing, so we must use
// an onHidden event instead.
val alert1 = new Alert(AlertType.Warning) {
initOwner(stage)
title = "Warning!!!"
headerText = "Header"
contentText = "Do you need to change the text?"
buttonTypes = Seq(ButtonTypeOne, ButtonTypeTwo, ButtonType.Cancel)
}
// React to the dialog being closed.
alert1.onHidden = {_ =>
alert1.result.value match {
// If button type one, change the property value.
// Note alert1.result.value is a JavaFX ButtonType, so use .delegate for the match.
case ButtonTypeOne.delegate => strProp.value = "Changed!"
// Otherwise, do nothing.
case _ =>
}
// Start the timer once more.
// This is going to be a very annoying app! ;-)
timerA.playFromStart()
}
// When the timer goes off, show the alert.
timerA.onFinished = {_ =>
alert1.show()
}
// Start the timer for the first time.
timerA.play
}

Passing information between two stages with ScalaFX fails due to not setting the field in controller

I am trying to understand the message passing possibilities of ScalaFX in combination with ScalaFXML. I created a small example, which has two views with controllers defined in the FXML. The first (or Main) view, is supposed to send a String to the second (or Dialog) view, by a button press.
I followed the example of the ScalaFXML Github page and used a trait in order to get the controller and it's possible for me to call a method on the Dialog controller, which sets a field to different value. This method gets called correctly, but the field isn't overwritten, when I check by clicking a button. Does this have something to do with ScalaFXML injecting the Controller?
Bellow I have the code for the two controllers
#sfxml
class MainController(val clicky: Button,
val inputText: TextField,
val resultText: TextArea) {
/** Creates a new window (in addition to the main window) and passes the contents of the text view to this window */
def onButtonPressed(): Unit = {
// Create the new window
val dialogFXML: String = "/Dialog.fxml"
val resource = getClass.getResource(dialogFXML)
val rootView = FXMLView(resource, NoDependencyResolver)
val loader = new FXMLLoader(resource, NoDependencyResolver)
loader.load()
val controller = loader.getController[AmountReceiver]
controller.setAmount(inputText.text.value)
val dialog = new Stage() {
title = "Add Person"
scene = new Scene(rootView)
resizable = false
initModality(Modality.ApplicationModal)
}
if (!dialog.showing()) {
dialog.show()
} else {
dialog.requestFocus()
}
}
}
and
#sfxml
class DialogController(val minAmountOfWords: Label,
val sendToMainButton: Button,
val input: TextArea) extends AmountReceiver {
var amount: String = "empty"
def submitText(): Unit = {
println(s"The actual amount is ${this.amount}")
// Close Dialog
quitDialog()
}
override def setAmount(amount: String): Unit = {
this.amount = amount
println(s"Setting the amount to ${this.amount}")
}
def quitDialog(): Unit = {
val stage: Stage = input.getScene.getWindow.asInstanceOf[Stage]
stage.close()
}
}
Running this code and entering "2" in the textfield, will print the following output:
Setting the amount to 2
The actual amount is empty
I actually figured it out myself. The problem lays within the rootView, which is received by creating a new FXMLView. In order access the correct controller, the rootView has to be received by the loader, which is already used to get the controller.
So calling
val rootView = loader.getRoot[jfxs.Parent]
instead of
val rootView = FXMLView(resource, NoDependencyResolver)
Like in the above example, the rootView is passed to the Scene constructor.

How to create a floating search box for macOS

How can I create a floating search box for macOS using Swift like Spotlight and Alfred?
We can use ScalaFX for this purpose
object Main extends JFXApp {
val resource = getClass.getResource("/box.fxml")
val root = FXMLView(resource, new GuiceDependencyResolver())
stage = new PrimaryStage() {
initStyle(StageStyle.Undecorated) // this option removes the default header
title = "Cats"
scene = new Scene(root)
}
}

Scala Swing: how to get child component form Borderpanel

How do I get the child component for a particular position on a Scala Swing BorderPanel? I can place components OK. In this particular case I want to check the component at BorderPanel.Position.Centre. Also am I right that there can only be one child component or a null at each position: North, East etc?
Well, the layout is a Map from component to position, so the following works (not sure if there's an easier way):
import scala.swing.SimpleSwingApplication
import scala.swing.MainFrame
import scala.swing.BorderPanel
import scala.swing.Label
object BorderLayoutTest extends SimpleSwingApplication {
def top = new MainFrame {
contents = new BorderPanel {
val label = new Label("hi")
import BorderPanel.Position._
layout(label) = Center
println("North: " + layout.find(_._2 == North)) //None
println("Center: "+ layout.find(_._2 == Center)) //Some( ... )
}
}
}