0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaFX含みのjavaのEclipseプロジェクトをKotlinのIntelliJプロジェクトに移行してみる

Posted at

この記事に関して

最近、Kotlinを座学で勉強しています。今までの自分の経験から、自分の性質では、自分で何か作らないと身につかないです。そこで、最近投稿してるシリーズのJavaFXによるDynamoDBツールをKotlinに移植してみようと思いました。
まだまだ機能追加予定なので、今後はKotlinでの機能追加したいという考えです。

目的は違えど同じような事をする人はいるかと思いますので、その人達の参考の一つになれば幸いです。

※そんな感じで勉強している最中で、今の自分はKotlinマスターではないです。こちらの記事で間違っている部分や考慮不足がある可能性があります。その点ご注意ください。

JavaをKotlinに変換する方法の考察

IntelliJやAndroidStudioでは標準で変換機能がついている様です。自分も別記事でやりましたが、AndroidStudioもIntellijの派生らしいです。そんな機能がついているぐらいだから独立してツール化したものがあってよさそうですが、自分はそんなツールを見つける事が出来ませんでした。検索しても大体IntelliJの機能を使っていたり、AndroidStudioでの話でした。
この状況から判断すると、IntelliJを使わなければならない事になります。現在、対象プロジェクトがEclipseなので、これをIntelliJのプロジェクトに変換する必要があります。

EclipseプロジェクトをIntelliJプロジェクトに変換する

公式ページ、「Eclipse から IntelliJ IDEA に移行する」にその必要が無い事が書いてありました。mvnプロジェクト作る時、mvn eclipse:eclipseとかやってたので、IntelliJ専用のコマンドがあるとか思ってましたが、そうでもなさそうです。pom.xmlさえあれば普通にImport出来そうです。

Importしてみる

image.png

Openを選択すると、プロジェクトのフォルダを選択する画面になる。そこで対象フォルダを選択すると以下画面が出てきました。

image.png

もしかしたら自分が今まで勘違いしていたのかもしれません。Eclipse projectMaven projectが別物だったっぽいですね。EclipseでMavenプロジェクトを開発していると思っていましたが、mvn eclipse:eclipseでpom.xmlを元にEclipseプロジェクトを作っていたという事だったのですね。だからpom.xmlを修正する度にこのコマンドが必要だった、という事ですね。(認識間違っていたらすいません)

で、今回はEclipseからの脱却を目指すという意味でもMaven projectを選んでみます。

ビルドしてみる

まだjavaですが、一旦ビルドします。BuildBuild projectを実行したら設定が無いと言われたので、新設に表示されたリンクから設定ページを開き、存在していたjava1.8を選択。出力フォルダも適当に設定します。ビルドは成功し、targetフォルダ配下に出力されていました(さっき設定した出力フォルダじゃなかった)。

jar出力してみる

Intellij IDEAで実行可能なjarを作る方法を参考に、jarを出力してみます。こちらの記事のトレースなので特に書く事は無いのですが、ちゃんとjarが出力され、実行も出来ました。

gitにアップ

ここまででEclipseプロジェクトをIntelliJプロジェクトに変換できたと思うので、gitにアップしようと思います。しかし、なんか中間生成ファイルが大量に発生し、.gitignoreの対応が必須と思われます。GithubGistにあったサンプルを参考に、.gitignoreを編集します

javaからKotlinへ一括変換する

ここまでくれば後はIntelliJの機能を使って一括変換できるはずです。

JavaからKotlinに変換する7つのテクニック Kotlinらしさを生かした簡潔なコードに置き換えよう を参考に、「メニューバーの「Code」→「Convert Java File to Kotlin File」メニュー」を実行します。
ここで、ファイルを選択していると対象ファイルだけKotlinになってしまうので、srcフォルダを選択して実行した方がよさそうです。

エラー部分を修正する

結構エラーが出てる状態です。データクラスとか依存が少ないクラスから修正していこうと思います。

まずはimport宣言の修正

どうやら、他クラスの内部クラスも宣言してしまいエラーになってる様なので、削除します。また、全ソースにプロジェクトで使ってるimportが全て記載されてしまっているみたいなので、使ってるもの以外削除します。

Lombockのgetter/setter対応

どうやらLombockアノテーションで提供されるgetter/setterメソッドが使えずに出てるエラーが沢山。
javaからkotlin変換の色々メモによるとlombockは使えない模様です。

修正前(Kotlinへ自動変換直後)
package com.silverboxsoft.dynamodbtool.classes

import lombok.Data

@Data
class DynamoDbColumn {
    private val columnName: String? = null
    private val columnType: DynamoDbColumnType? = null
}

単純置き換えだと下のような感じになると思います。

単純修正後
package com.silverboxsoft.dynamodbtool.classes

import lombok.Data

@Data
class DynamoDbColumn {
    private var columnName: String? = null
    private var columnType: DynamoDbColumnType? = null
    fun getColumnName(): String? {
        return columnName
    }
    fun getColumnType(): DynamoDbColumnType? {
        return columnType
    }
    fun setColumnName(name: String) {
        this.columnName = name
    }
    fun setColumnType(type: DynamoDbColumnType) {
        this.columnType = type
    }
}

せっかくKotlin化をしようとしているので、nullを許可しない形に修正します。

?を外した形
package com.silverboxsoft.dynamodbtool.classes

import lombok.Data

@Data
class DynamoDbColumn(columnNamePrm: String, columnType: DynamoDbColumnType) {
    private val columnName: String = columnNamePrm
    private val columnType: DynamoDbColumnType = columnType
    fun getColumnName(): String {
        return columnName
    }
    fun getColumnType(): DynamoDbColumnType {
        return columnType
    }
}

当然連鎖反応的にこれを使用している部分を修正していきます。関連する?を取る事が出来ました。
ここまで修正した後に色々Kotlinのページを見ていると、Kotlinは特getter/setterを設けずに、変数に直接アクセスするのがベストプラクティスっぽいと感じ、その方向で修正する事にしました。読み込みだけしたい場合などはvalで宣言すればよいと思います。

コンストラクタ引数をそのままフィールド値にする形式にしました。
class DynamoDbColumn(val columnName: String, val columnType: DynamoDbColumnType)

変数持ちenum

変更前(Kotlin変換直後)
package com.silverboxsoft.dynamodbtool.classes

enum class DynamoDbConditionType(condStr: String) {
    EQUAL(" = "), GREATER_THAN(" > "), LESSER_THAN(" < "), GREATER_THAN_EQ(" >= "), LESSER_THAN_EQ(" <= ");
}

内部変数を記載し、getterを追加します。

変更後
package com.silverboxsoft.dynamodbtool.classes

enum class DynamoDbConditionType(condStr: String) {
    EQUAL(" = "), GREATER_THAN(" > "), LESSER_THAN(" < "), GREATER_THAN_EQ(" >= "), LESSER_THAN_EQ(" <= ");
    private val condStr = condStr
    fun getCondStr(): String{
        return this.condStr
    }
}

ここから、さらにgetterを無くす形に修正し、かつコンストラクタ変数でフィールド変数も宣言してしまう形に修正します。一括変換時、なんでこの形になってなかったか不明です。もしかしたら間違って修正しちゃっていたかもしれません。

変更後
enum class DynamoDbConditionType(val condStr: String) {
    EQUAL(" = "), GREATER_THAN(" > "), LESSER_THAN(" < "), GREATER_THAN_EQ(" >= "), LESSER_THAN_EQ(" <= ");
}

ListでaddメソッドつかっているものをMutableListに変更

プロパティの中がListだったりした時には自動変換が検知できない様です。
※plusメソッドは、新しい要素を追加した、新しいリストを返すメソッドなので既存のロジックの置き換えでは使わないほうが良さそうです。

ListのsortをsortedWithに変更

修正前
attrNameList.sort(
    Comparator.comparing { attrName: String -> getDynamoDbColumnType(dynamoDbRecord[attrName]).displayOrder })
return attrNameList
修正後
return attrNameList.sortedWith(
    Comparator.comparing { attrName: String -> getDynamoDbColumnType(dynamoDbRecord[attrName]).displayOrder }
)

if文のネストをwhenに変更

javaでswitchが使えない処理で、ifのネストしてた部分があったので、エラーではないけどIntelliJの自動修正機能でwhenに修正

Mapのデータ取得対応

Mapのデータを取得する時、getだと、Null可能性が残るので、getOrDefault関数を使用

修正前
    fun getColumnIndexByName(colName: String): Int? {
        return if (colNameIndex.containsKey(colName)) {
            colNameIndex[colName]
        } else -1
修正後
    fun getColumnIndexByName(colName: String): Int {
        return colNameIndex.getOrDefault(colName, -1)
    }

jafaFXのApplication起動部分修正

Kotlin+JavaFXの基本的なコードを参考にさせて頂きました。

修正前
// ・・前略・・
class App : Application() {
    @Throws(Exception::class)
    override fun start(stage: Stage) {
        prepareControl(stage)
        stage.show()
    }
    // ・・中略・・
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            launch(*args)
        }
    }
}
修正後
// ・・前略・・
class App : Application() {
    @Throws(Exception::class)
    override fun start(stage: Stage) {
        prepareControl(stage)
        stage.show()
    }
    // ・・中略・・
}

fun main(args: Array<String>) {
    Application.launch(App::class.java, *args)
}

ここまででビルドとFX起動まで完了

javaFXコンポーネント

javaFXのコンポーネント(@FXMLアノテーションで関連付けされるオブジェクト)は、initブロックを処理する時にはまだインジェクションされていない。別のinitialize関数を作って、コンストラクタ以後に呼ばなくてはいけなさそうです。

無事にjavaFXをKotlinで動かせました。

記事に書いてる部分だけだとスムーズに行ったように見えましたが、初学者の私は結構時間かかりました。でもちゃんと動くようになりました。微妙に前回からボタンのレイアウト位置変えてます。この際のレイアウト変更は、今まで通りjavaFX Scene Builderで行いました。

image.png

現在のソースでも、githubにKotlinと認識されたようです。

その他気になった事

Eclipseでは、実行可能jarを作る際、関係モジュールをjarに埋め込むか、サブフォルダに出力するかなど選べたのですが、IntelliJでのやり方が解りませんでした。とりあえず今はpom.xmlでmaven-assembly-pluginを使ってmvn packageをする事でjar生成しています。サイズ大きいので、依存jarは分けたいと思っている所です。

過去のシリーズ記事

第1回記事:DynamoDBの情報を読み込んでJavaFXで表示してみる
第2回記事:JavaFXで動的にテーブル列を設定する
第3回記事:AWS java SDKでDynamoDBテーブル情報を取得してみる
第4回記事:JavaFX の TableView の選択範囲をクリップボードにコピーする。
第5回記事:JavaFX でコンポーネント作って動的生成してみる
第6回記事:DynamoDBのデータ型をjava SDKから把握してみる。
第7回記事:JavaFXでジェネリック使って入力ダイアログ作成してみる
第8回記事:JavaFXで各種サイズ制御
第9回記事:JavaFXのDialogで入力値チェック制御
第10回記事:DynamoDBでPartiQLをjavaSDKで実行してみる。
第11回記事:JavaFXでダイアログの入力チェック制御をちゃんと考えてみる
第12回記事:javaFX、TableViewのソート後の情報取得不具合対応

参考にさせて頂いたページ

公式ページ

Eclipse から IntelliJ IDEA に移行する

皆さんの良記事

JavaからKotlinに変換する7つのテクニック Kotlinらしさを生かした簡潔なコードに置き換えよう
Intellij IDEAで実行可能なjarを作る方法
javaからkotlin変換の色々メモ
Kotlin+JavaFXの基本的なコード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?