起動中ダイアログを表示する(2)

時間のかかるアプレットの起動中にダイアログを表示する方法を前回紹介しました。前回は固定の(静的な)メッセージを表示するサンプルでしたが、今回は動くプログレスバーを表示する方法の紹介です。

アプレット起動中にプログレスバー動かすためにはサブアプレットという仕組みを使います。まずは次のようなクラスを定義します。

{import * from CURL.ENGINE.BROWSER}

{define-class public final SplashScreenManager
  
  field private applet-data:#AppletData
  field private applet-url:Url
  
  {constructor public {default}
    set self.applet-url =
        {string-url
            {stringify
                {curl 6.0 applet}
                {{Dialog
                     cursor = cursor-wait,
                     {ProgressBar indeterminate? = true},
                     {on e:WindowClose do {e.consume}}
                 }.show
                    title = "起動中",
                    modal? = false
                }
            }
        }
    {on-applet-suspend do
        {self.close}
    }
  }
  
  {method public {close}:void
    {if-non-null self.applet-data then
        {self.applet-data.destroy}
    }
  }
  
  {method public {show}:void
    def ag = {AppletGraphic}
    set self.applet-data = {AppletData ag, self.applet-url}
    {while self.applet-data.loading? do
        {dispatch-events true}
    }
    {if self.applet-data.what != "finished" then
        {self.close}
    }
  }
  
}

この SplashScreenManager クラスのポイントは

プログレスバーをモーダルダイアログで表示するだけのサブアプレットを作成します。
このサンプルでは別ファイルを作るのを少し横着してコンストラクタ内でサブアプレットをハードコードしています(stringifyマクロ内がそれ)。これは当然別の .curl ファイルにしても構いません。その場合は {string-url {stringify ...}} の部分を単純に {url "subapplet.curl"} などとします。

show メソッド内では AppletData というクラスを使ってサブアプレットインスタンス化しています(その次の while 文はサブアプレットのロード完了を待つためのコードです)。よって、この show メソッドが呼び出されるとサブアプレットが実行され、動くプログレスバー入りのダイアログが表示されます。

close メソッドでは、show メソッド内で生成された AppletData を destroy します。サブアプレットは終了してダイアログが閉じます。


以下はこの SplashScreenManager クラスを利用して起動中にプログレスバーを表示するサンプルです。(上記の SplashScreenManager クラスは splash-screen.scurl というファイルに定義されているものとします)

{curl 6.0 applet}
{curl-file-attributes character-encoding = "shift-jis"}
{applet manifest = "manifest.mcurl",
    {compiler-directives careful? = true}
}

{include "splash-screen.scurl"}

{def splash-screen = {SplashScreenManager}}
{splash-screen.show}

{import * from A-HEAVY-PACKAGE-TO-LOAD}

{View
    {Frame width = 8cm, height = 8cm, "サンプルアプレット"},
    visibility = "normal",
    owner = null,
    {on WindowClose do
        {exit}
    }
}

{splash-screen.close}