JavaFX is a GUI library that makes it easy to create a cool GUI that runs on the desktop on a so-called PC. Since it is a Java library, it can be used in an environment where Java SE (Java Platform, Standard Edition) runs. This will be a PC running an OS such as Linux, MacOS, or Windows. In addition, since the compiled result binary (Java bytecode), which is a feature of Java programs, is common regardless of the OS, programs created on one OS can be executed as they are on another OS.
Java as a programming language focuses on the functionality of object-oriented programming. Recently, we are incorporating the functions of other advanced programming languages, such as the functions of functional programming, but there are some inadequate points compared to the functions of advanced programming languages. However, Java as an environment has a wealth of standard libraries, a huge number of third-party libraries and tools, and the Java ecosystem is very strong and surpasses that of other languages.
Here, although the source code is a programming language different from Java, the compilation result is Java byte code, and there is a programming language group called JVM language that can be run on the Java execution environment. Typical JVM languages include new languages such as Scala, Groovy, Clojure, and Kotlin, as well as existing programming languages such as JRuby and Jython running on Java.
A wealth of Java standard and third-party libraries are available from these JVM languages. Therefore, you can take advantage of Java's abundant assets while doing advanced programming using the JVM language.
Kotlin, one of the JVM languages, is a programming language that inherits the characteristics of Java as a general-purpose programming language, but has the ability to program more concisely, more productively, and more safely. In addition, we emphasize interoperability with Java, and it is devised so that not only Java can be called from Kotlin but also Kotlin can be called from Java.
When using JavaFX from Kotlin, the functions (more concise / productive / safe) unique to Kotlin cannot be fully utilized by directly hitting the JavaFX API. Therefore, TornadoFX, a library that thoroughly remodeled JavaFX into the Kotlin style, was developed.
This article is the next article to make a so-called Hello world-like program with a little movement like JavaFX.
The next article about making this program in Kotlin
As the third part following, it will be created by calling JavaFX from Kotlin via TornadoFX.
The Kotlin programming environment uses IntelliJ IDEA Community Edition [^ 1].
[^ 1]: IntelliJ IDEA is a programming tool (integrated development environment IDE) developed and sold by JetBrains. The Community Edition is limited in functionality but is provided free of charge, and the Kotlin development environment is also included as standard with the Community Edition. There is also a TornadeFX plugin.
item | Contents |
---|---|
CPU | AMD Phenom II 1055T (6 cores) |
OS | Japanese Windows 10 64bit version |
memory | 16GB |
Graphics | NVIDIA GeForce GTX 760 |
disk | SATA SSD 500GB |
JDK | Oracle JDK 9.0.4 |
IntelliJ IDEA | 2017.3.5 Community Edition |
TornadoFX | 1.7.14 |
IntelliJ IDEA download URL https://www.jetbrains.com/idea/download/
IntelliJ IDEA applies a Japanese localization tool called Pleiades to Japaneseize it. When describing the operating procedure of IntelliJ IDEA in this article, we will use the names of menus, buttons, tabs, etc. that have been translated into Japanese. Japanese manual for IntelliJ-based products
Download URL for Oracle JDK 9.0.4 http://www.oracle.com/technetwork/java/javase/downloads/index.html
Install the Tornado FX plugin in IntelliJ IDEA.
TornadoFX exists in the left pane, and when you select it, the maven or gradle project types are listed in the right pane.
Gradle included in IntelliJ IDEA's Gradle plugin is version 4.0 as of March 15, 2018. Using this with JDK 9 will result in an error.
Could not determine java version from '9.0.4'.
Since JDK 9 support is Gradle 4.2.1 or later, in this case it is better to install and use Gradle 4.2.1 or later locally instead of Gradle wrapper.
There are directories, configuration files, and sample source files that are generated by default. Also, in the status area (at the bottom of the IntelliJ IDEA screen), you will be notified to import Gradle.
Click the notification icon in the lower right corner of the IntelliJ IDEA screen to open the Event Log with the message. Immediately after creating a new project, since the library defined by the dependency has not been downloaded yet, Gradle will be imported first. Click Import Gradle Project in the message in the Event Log area. Click to open the "Import Module from Gradle" screen [^ 2].
[^ 2]: When I closed this screen with [Cancel], I had a hard time not knowing where to call this screen next time. The link in the Event Log message was grayed out and the link was invalid. Also, the menu items that open in View menu> Tools Window do not include Gradle. Once I closed IntelliJ IDEA and started it again, the link in the Event Log message was enabled and I was finally able to reopen the screen.
Click the [OK] button to start the setting.
In an environment where there is a firewall on the Internet connection, it may be necessary to set a proxy server, but I will omit the explanation in this article [^ 3].
[^ 3]: This article is written at home without a proxy server.
The project generated by the TornadoFX plugin contains three source files as demo code: MyApp, Styles and MainView. By building and executing this, it is confirmed whether the programming environment was built correctly.
When you open the Run menu, Run, Debug, and Run with Coverage are disabled. First, you need to configure the startup settings. The easiest way is to right-click the App Inheritance Class file (MyApp in the demo code), which is the entry point for running the program, and select Run.
If successful, you will see the following screen.
From now on, when you open the Run menu, Run, Debug, and Run with Coverage are enabled. Also, if you select [Run] menu> [Run Launch Configuration], [MyApp] is added to the options.
When I generate a TornadoFX project, it generates demo code, but I throw it away and create two classes:
name of the class | Contents |
---|---|
MessageBoardApp | A class that inherits the TornadoFX App that wraps the JavaFX Application class |
MessageBoardView | A class that inherits the TornadoFX View that shows the scene graph |
In the demo code, the package was divided into app and view, but this time we will place it in the same package.
MessageBoardApp.kt
package com.torutk.messageboard
import tornadofx.App
class MessageBoardApp: App(MessageBoardView::class)
MessageBoardApp inherits the JavaFX Application class and inherits the TornadoFX App class, and receives the MessageBoardView class that defines the view (scene graph) as an argument of the primary constructor. It features no code implementation at all. In JavaFX's Application inheritance class, I wrote the routine code that overrides the start method and messes with Stage and Scene. TornadoFX eliminates the need to write this routine code.
MessageBoardView.kt
package com.torutk.messageboard
import javafx.scene.Group
import javafx.scene.text.Text
import tornadofx.*
class MessageBoardView : View() {
override val root = Group()
init {
val message = Text("Hello, Kotlin. This is TornadoFX.")
message.layoutY = 50.0
root += message
}
}
MessageBoardView inherits the View class of TornadoFX, generates a JavaFX Group as the root node, and generates text as a child node of Group to configure the scene graph. Since the root node is defined in the View class as a property, override it with override to define the child node. Overriding the root property creates and assigns an instance of the Group class.
The init block is an initialization block. Since the primary constructor can only define properties, the code written in the init block is executed when instantiating with the primary constructor. You can refer to properties in the init block.
In this init block, we are instantiating Text, setting the layout (layoutY), and adding it to the root node as a child node. Adding child nodes to the root node uses operator overloading.
Let's run it.
Functions are provided to generate JavaFX controls. These take a lambda expression at the end of the argument.
The following code defines a builder group function that creates a Group at the root node, and uses a builder text function that creates a Text in it.
MessageBoardView.kt
class MessageBoardView : View() {
override val root = group {
text("Hello, Kotlin. This is TornadoFX.") {
layoutY = 50.0
}
}
}
In this way, the hierarchical structure of the scene graph can be represented by a nested structure.
The flowing message uses JavaFX's TranslateTransition. In TornadoFX, the extension function move describes an animation using TranslateTransition.
MessageBoardView.kt
class MessageBoardView : View() {
override val root = group {
text("Hello, Kotlin. This is TornadoFX.") {
layoutY = 50.0
move(Duration.seconds(8.0), Point2D(-layoutBounds.width, 0.0), Interpolator.LINEAR, play = true) {
fromX = layoutBounds.width
cycleCount = Animation.INDEFINITE
}
}
}
}
The move arguments specify the duration, destination, interpolation method, and whether to run the animation immediately. Since the move source and the number of repetitions were not specified in the move argument, they are specified by the lambda expression.
I will do it.
In TornadoFX, the appearance of fonts and colors is defined by CSS realized by Kotlin's DSL, but this time it is defined by JavaFX API instead of CSS for the convenience of flowing animation.
MessageBoardView.kt
class MessageBoardView : View() {
override val root = group {
text("Hello, Kotlin. This is TornadoFX.") {
font = Font.font("Serif", FontWeight.SEMI_BOLD, 32.0)
fill = Color.DARKMAGENTA
layoutY = 50.0
move(Duration.seconds(8.0), Point2D(-layoutBounds.width, 0.0), Interpolator.LINEAR, play = true) {
fromX = layoutBounds.width
cycleCount = Animation.INDEFINITE
}
}
}
}
I will do it.
Recommended Posts