Zastanawialiście się kiedyś, czy da się uruchomić aplikację JavaFX w Kotlinie? Da się i – wbrew pozorom – nie jest to wcale trudne. Załóżmy, że mamy klasę JavaFX, taką jak poniżej:
package assets;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ClassTemplate extends
Application {
@Override
public void init() {
}
@Override
public void start(Stage stage) {
try {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 200);
stage.setScene(scene);
stage.setTitle(this.getClass().getName());
stage.setOnCloseRequest(e -> Platform.exit());
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void stop() {
}
public static void main(String[] args) {
Application.launch(args);
}
}
package assets;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ClassTemplate extends
Application {
@Override
public void init() {
}
@Override
public void start(Stage stage) {
try {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 200);
stage.setScene(scene);
stage.setTitle(this.getClass().getName());
stage.setOnCloseRequest(e -> Platform.exit());
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void stop() {
}
public static void main(String[] args) {
Application.launch(args);
}
}
package assets; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class ClassTemplate extends Application { @Override public void init() { } @Override public void start(Stage stage) { try { StackPane root = new StackPane(); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle(this.getClass().getName()); stage.setOnCloseRequest(e -> Platform.exit()); stage.show(); } catch (Exception e) { e.printStackTrace(); } } @Override public void stop() { } public static void main(String[] args) { Application.launch(args); } }
Teraz wystarczy użyć automatycznego tłumaczam dostępnego w IntelliJ IDEA. Po poprawieniu
Int
Int
na Double
Double
i uporządkowaniu sekcji importów, otrzymamy kod taki jak poniżej:
package assets
import javafx.application.Application
import javafx.application.Platform
import javafx.event.EventHandler
import javafx.scene.Scene
import javafx.scene.layout.StackPane
import javafx.stage.Stage
class ClassTemplate : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
val scene = Scene(root, 300.0,
200.0)
stage.scene = scene
stage.title = this.javaClass.name
stage.onCloseRequest = EventHandler { Platform.exit() }
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
companion object {
@JvmStatic
fun main(args: Array<String>) {
launch(*args)
}
}
}
package assets
import javafx.application.Application
import javafx.application.Platform
import javafx.event.EventHandler
import javafx.scene.Scene
import javafx.scene.layout.StackPane
import javafx.stage.Stage
class ClassTemplate : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
val scene = Scene(root, 300.0,
200.0)
stage.scene = scene
stage.title = this.javaClass.name
stage.onCloseRequest = EventHandler { Platform.exit() }
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
companion object {
@JvmStatic
fun main(args: Array<String>) {
launch(*args)
}
}
}
package assets import javafx.application.Application import javafx.application.Platform import javafx.event.EventHandler import javafx.scene.Scene import javafx.scene.layout.StackPane import javafx.stage.Stage class ClassTemplate : Application() { override fun init() {} override fun start(stage: Stage) { try { val root = StackPane() val scene = Scene(root, 300.0, 200.0) stage.scene = scene stage.title = this.javaClass.name stage.onCloseRequest = EventHandler { Platform.exit() } stage.show() } catch (e: Exception) { e.printStackTrace() } } override fun stop() {} companion object { @JvmStatic fun main(args: Array<String>) { launch(*args) } } }
To jednak nie wystarczy – jeśli spróbujemy ten kod uruchomić, otrzymamy błąd:
Powodem jest błędne tłumaczenie metody
main
main
uruchamiającej aplikację. Po poprawieniu kodu klasa powinna wyglądać tak:
package assets
import javafx.application.Application
import javafx.application.Platform
import javafx.event.EventHandler
import javafx.scene.Scene
import javafx.scene.layout.StackPane
import javafx.stage.Stage
class ClassTemplate : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
val scene = Scene(root, 300.0,
200.0)
stage.scene = scene
stage.title = this.javaClass.name
stage.onCloseRequest = EventHandler { Platform.exit() }
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
companion object {
@JvmStatic
fun main(args: Array<String>) {
launch(ClassTemplate::class.java, *args)
}
}
}
package assets
import javafx.application.Application
import javafx.application.Platform
import javafx.event.EventHandler
import javafx.scene.Scene
import javafx.scene.layout.StackPane
import javafx.stage.Stage
class ClassTemplate : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
val scene = Scene(root, 300.0,
200.0)
stage.scene = scene
stage.title = this.javaClass.name
stage.onCloseRequest = EventHandler { Platform.exit() }
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
companion object {
@JvmStatic
fun main(args: Array<String>) {
launch(ClassTemplate::class.java, *args)
}
}
}
package assets import javafx.application.Application import javafx.application.Platform import javafx.event.EventHandler import javafx.scene.Scene import javafx.scene.layout.StackPane import javafx.stage.Stage class ClassTemplate : Application() { override fun init() {} override fun start(stage: Stage) { try { val root = StackPane() val scene = Scene(root, 300.0, 200.0) stage.scene = scene stage.title = this.javaClass.name stage.onCloseRequest = EventHandler { Platform.exit() } stage.show() } catch (e: Exception) { e.printStackTrace() } } override fun stop() {} companion object { @JvmStatic fun main(args: Array<String>) { launch(ClassTemplate::class.java, *args) } } }
Zauważcie, że zmienił się tylko parametr metody
launch()
launch()
. Teraz kod powinien uruchomić się poprawnie. Oczywiście dla porządku metodę main możemy wyłączyć poza klasę, tak jak widać poniżej:
package assets
import javafx.application.Application
import javafx.stage.Stage
import javafx.scene.layout.StackPane
import javafx.scene.Scene
import java.lang.Exception
import kotlin.jvm.JvmStatic
class ClassTemplate2 : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
stage.scene = Scene(root, 300.0, 200.0)
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
}
fun main(args: Array<String>) {
Application.launch(ClassTemplate2::class.java, *args)
}
package assets
import javafx.application.Application
import javafx.stage.Stage
import javafx.scene.layout.StackPane
import javafx.scene.Scene
import java.lang.Exception
import kotlin.jvm.JvmStatic
class ClassTemplate2 : Application() {
override fun init() {}
override fun start(stage: Stage) {
try {
val root = StackPane()
stage.scene = Scene(root, 300.0, 200.0)
stage.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun stop() {}
}
fun main(args: Array<String>) {
Application.launch(ClassTemplate2::class.java, *args)
}
package assets import javafx.application.Application import javafx.stage.Stage import javafx.scene.layout.StackPane import javafx.scene.Scene import java.lang.Exception import kotlin.jvm.JvmStatic class ClassTemplate2 : Application() { override fun init() {} override fun start(stage: Stage) { try { val root = StackPane() stage.scene = Scene(root, 300.0, 200.0) stage.show() } catch (e: Exception) { e.printStackTrace() } } override fun stop() {} } fun main(args: Array<String>) { Application.launch(ClassTemplate2::class.java, *args) }
W ten sposób można oczywiście „przetłumaczyć” dowolną klasę JavaFX na Kotlina.