2
2

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 5 years have passed since last update.

Kotlin / ControlsFXのMaskerPaneをつかってみる

Posted at

環境

  • Kotlin 1.0.5
  • JDK 1.8.0_121
  • ControlsFX 8.40.12

MaskerPaneとは

ローディング中であることを表示するクルクルアイコンと、背後のコントロールにアクセスできなくさせるための半透明の覆いがセットになったペインです。JavaFXのProgressIndicatorに覆いを足しただけの機能ですがより手軽に使えます。
1.gif
Class MaskerPane

今回はJavaFXに用意された同時実行用クラスであるTaskと一緒に使ってみます。

使用例(Taskの場合)

上記キャプチャ画像のコントローラクラスの実装です。

Controller.kt
class Controller {

    @FXML lateinit private var maskerPane: MaskerPane
    @FXML lateinit private var button: Button

    @FXML fun onButtonAction(@Suppress("UNUSED_PARAMETER") event: ActionEvent) {

        val task = object : Task<String>() {
            override fun call(): String {
                (0..400).forEach { count ->
                    updateProgress(count.toDouble(), 400.0)   // [1]
                    Thread.sleep(10)
                }
                return "done"
            }
        }

        maskerPane.progressProperty().bind(task.progressProperty())   // [2]
        maskerPane.visibleProperty().bind(task.runningProperty())     // [3]
        Thread(task).start()
    }

}

1.JavaFXのTaskには void updateProgress(double workDone, double max) というメソッドが用意されています。作業中はworkDoneを増やしながらmaxになるまでこのメソッドを呼んであげる必要があります。

2.MaskerPaneのprogressをTaskのprogressに追従させます。
task.progressが変更される -> maskerPane.progressが追従する -> maskerPaneの見た目が変わる
といった流れをこれで実現できます。progress自体は0.0から1.0に変化していくDouble値です。

3.MaskerPaneの表示可否をTaskの実行中かどうかを示す値に追従させます。
つまりTaskが動作を停止するとMaskerPaneは消えます。

バリエーション

Webページの読み込みなど、完了のタイミングを予測できない場合があるかと思います。そのような場合は[1]と[2]の行を削除して以下のような表示にできます。
2.gif

同期周り

javafx.concurrentパッケージはこれらの処理をスレッドセーフに行ってくれます。今回の例ではTaskがprogressやrunningの値を書き換えるときに、自動的にJavaFXアプリケーション・スレッドを使用するようになっているので、画面がごりごり書き換わっていても描画スレッドを意識しなくて済みます。
ORACLE: JavaFXでの同時実行

参考

ControlsFX: Getting Started (sample)
ORACLE: Java Sample - Ensemble

FXML

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.StackPane?>
<?import org.controlsfx.control.MaskerPane?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
           prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="maskerpane.Controller">
   <Button fx:id="button" mnemonicParsing="false" onAction="#onButtonAction" text="Button"/>
   <MaskerPane fx:id="maskerPane" visible="false"/>
</StackPane>
2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?