KotlinでJavaFX 2.2のContextMenuを利用する

JavaFX 2.2のContextMenuとはPopupMenuの事です。
今回はシンプルなボタンをクリックすると”Hello Kotlin World!”とラベルにテキストをセットするものにExitというメニューでJavaFXプログラムを終了させるContextMenuをマウスの右クリックで表示させます。
プログラムにはFXMLを使いコントローラークラスもKotlinで書きます。
コントローラークラスにはKotlinらしく関数リテラルも使ってみます。
コードは以下のようになります。

JavaFX_FXML_TEST.kt

package javafx_fxml_test

import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.stage.Stage
import javafx.application.Platform

fun main(args: Array<String>) = Application.launch(JavaFX_FXML_TEST().javaClass, args.makeString(""))

public class JavaFX_FXML_TEST : Application() {

    override public fun init():Unit{

        println("javafx.version = " + System.getProperty("javafx.version"))
        println("init()はPlatform.isFxApplicationThread() が " + Platform.isFxApplicationThread())
    }


    override public fun start(p0: Stage?) : Unit {

        val root : Parent?  = FXMLLoader.load(getClass().getResource("/Sample.fxml"))

        val scene: Scene  = Scene(root)

        p0?.setScene(scene)
        p0?.show()
    }


}

SampleController.kt

package javafx_fxml_test

import java.net.URL
import java.util.ResourceBundle
import javafx.event.ActionEvent
import javafx.fxml.FXML
import javafx.fxml.Initializable
import javafx.scene.control.Label
import javafx.scene.layout.AnchorPane
import javafx.scene.input.MouseEvent
import javafx.scene.input.MouseButton
import javafx.scene.control.ContextMenu
import javafx.scene.control.MenuItem

public class SampleController() : Initializable {

  FXML
  private var label : Label? = null
  FXML
  private var anchorPane : AnchorPane? = null
  
  FXML
  private fun handleButtonAction(event : ActionEvent?) : Unit {
    println("You clicked me!" +"\n" + event)
    label?.setText("Hello Kotlin World!")
  }
  
  override
  public fun initialize(p0: URL?, p1 : ResourceBundle?) : Unit {
      val cm = ContextMenu()
      val cmItem1 = MenuItem("Exit")
      cmItem1.setOnAction{
         System.exit(0)
      }

      cm.getItems()?.add(cmItem1)

      val handler = {(p0:MouseEvent?) -> if (p0?.getButton() == MouseButton.SECONDARY) {

          cm.show(anchorPane, p0?.getScreenX() as Double, p0?.getScreenY() as Double)
          println("MOUSE_CLICKED x = " + p0?.getScreenX() + " y = " + p0?.getScreenY())
      }
      }

      anchorPane?.addEventHandler(MouseEvent.MOUSE_CLICKED, handler)

  }
  
}

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" fx:id="anchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafx_fxml_test.SampleController">
    <children>
        <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
        <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
    </children>
</AnchorPane>