Android StudioでJavaFXをKotlinに変換したけどエラー多数!なんとか修正したぞ!
2017/06/11
前回、Android StudioにKotlinプラグインを導入を導入しました。
今回はそれを使って、以前作ったJavaFXのファイルをKotlinに変換してみました。
結論を先に言うと、完全に変換できず、いくつかエラーが発生しました。それを対処しましたので記録として残しておきます。
目次
まずはコンバート
まず、JavaFXファイルを読み込み、メニューから「Code」-「Convert Java File to Kotlin File」を選びます。
すると、コンバートが開始されます。
こんなメッセージが出ましたが、とりあえず「OK」。
無事(?)、Kotlin形式にコンバートできました。拡張子が.ktになっています。
[ad#top-1]
ファイルが上書きされる!
ここで1つ問題発生。なんと変換前の.javaファイルが消えて、.ktファイルしかなくなっています。Android Studio上でコンバートすると上書きと言うか、元ファイルが消えてしまうんですね。
たぶんAndeoidアプリのプロジェクト内で旧ファイルを残しておくのがまずいからだと思います。
もし、旧ファイルを残しておきたい場合は別に保存しておく必要があります。
コンパイルするもエラー続出!
返還後のKotlinファイルをコマンドプロンプト上でコンパイルしてみたところ、エラーが続出しました。JavaFXに限っては100%完全な変換には至らないようですね。
以下、コンパイルエラーの詳細と対処法です。
IntegerからDoubleに変換されず
Javaのクラスへの引数でInteger型だったものでも、KotlinではすべてDouble型になるみたいです。その変換がうまくできていませんでした。
例えば、以下のようにJavaではAnchorPaneのサイズを指定する場合、引数はInteger型です。
AnchorPane root = new AnchorPane(); root.setPrefWidth(400); root.setPrefHeight(100);
こちらがKotlinへの返還後で、Integer型のままでした。これをこのままコンパイルするとエラーになります。(the integer literal does not conform to the expected type Double)
val root = AnchorPane() root.setPrefWidth(400) root.setPrefHeight(100)
なので、以下のように1つ1つDouble型に手修正する必要があります。
val root = AnchorPane() root.setPrefWidth(400.0) root.setPrefHeight(100.0)
簡単なプログラムならいいのですが、大きなプログラムの場合は膨大な量の手修正が必要になります。
@Overrideが残った
なぜか@Override文がKotlin形式に変換されず。あと、Throws部分が変な変換のされ方をしました。
元のJavaコードはこちらです。
@Override public void start(Stage stage) throws Exception{ stage.setTitle("Java Test"); ...
以下のようにKotlin形式に修正しました。変なThrow文はとりあえずコメントアウト。
ランチャー部分が変なオブジェクトにまとめられた
JavaFXのランチャーが変なまとめ方をされてしまいました。
こちらが元のJavaコード
public static void main(String[] args) { launch(args); }
以下のように変なまとめ方をされました。companion objectって何だ?? こいつを消して、Kotlinのランチャーを書き加えました。
イベント処理がエラー!
残念ながら以下のようなイベント処理でエラーが発生してしまいました。こちらはとりあえずコメントアウト。ここについては後で調べてみます。ラムダ式に問題あるのかな?
コンパイル成功!
上記の修正をして、再度コンパイルしたところ無事通りました。
そして無事実行しました。とりあえず何とかなった!
イベント処理だけは問題を残していますので、こちらは早急に調べてみたいと思います。
2017/6/11追記:解決しました。
Kotlinのソースコード全文
変換&修正したKotlinのソースコードです。
import javafx.application.Application import javafx.event.ActionEvent import javafx.scene.Scene import javafx.scene.text.Font import javafx.scene.control.* import javafx.scene.layout.AnchorPane import javafx.stage.Stage class FxTest2 : Application() { // implements Initializable{ //@Throws(Exception::class) override fun start(stage: Stage) { stage.setTitle("Java Test") val label = Label("Hello World") label.setFont(Font("Meiryo UI", 36.0)) AnchorPane.setTopAnchor(label, 26.0) AnchorPane.setLeftAnchor(label, 46.0) val btn = Button("OK") btn.setFont(Font("Meiryo UI", 18.0)) btn.setPrefWidth(95.0) btn.setPrefHeight(19.0) AnchorPane.setTopAnchor(btn, 31.0) AnchorPane.setLeftAnchor(btn, 267.0) //btn.setOnAction({ event -> handleOK(ActionEvent()) }) val root = AnchorPane() root.setPrefWidth(400.0) root.setPrefHeight(100.0) root.getChildren().addAll(label, btn) stage.setScene(Scene(root)) stage.show() } //fun handleOK(event: ActionEvent) { // System.out.println("OK") //} } fun main(args: Array<String>) { Application.launch(FxTest2()::class.java, *args) }
[ad#ad-1]
スポンサーリンク