Clojure で GUI アプリを書いてみる (例外キャッチ編)
- Clojure で GUI アプリを書いてみる (システムトレイ・タスクトレイ編) - Kikuchy's Second Memory
- Clojure で GUI アプリを書いてみる (一旦の完成を見る・前編) - Kikuchy's Second Memory
- Clojure で GUI アプリを書いてみる (一旦の完成を見る・後編) - Kikuchy's Second Memory
一旦完成を迎えた天気予報アプリですが、これが抱えている問題点に
「ネットに繋がってないと、キャッチされない例外が出て起動しない」
というのがあります。
私は MacBook (最後の黒 MacBook)を使っていてしょっちゅう移動しますし、必要無い時はテザリングを使わないので、オフライン環境にいる事がままあります。
天気予報アプリをログイン項目に追加してあるせいで、オフラインのまま Mac を立ち上げると、キャッチされない例外のダイアログが出て鬱陶しいのです。
そこで、改良することにしました。
方針は以下のように。
- 起動時に出る例外をキャッチ
- アイコンを天気予報アイコンではなく、ネットに繋がっていない事がわかりやすいようなものにする
さっそくコードをいじります。
変更したのは、前々回の -main のコードのみ。
(defn -main [& args] (try ;; ネットに繋がらないと、 get-tenki が例外を出す (let [today-forecast (tenki-today (get-tenki)) icon (system-tray-icon (read-image-local (nth icon-images-list (telop-to-index (:telop today-forecast)))) (tenki-temperature today-forecast) (system-tray-popupmenu))] (add-icon-system-tray icon)) (catch Exception _ (add-icon-system-tray (system-tray-icon (read-image-local "no_connection.png") "インターネットに接続できませんでした" (system-tray-popupmenu))))))
例外を発生させる get-tenki が let の中に入ってしまっている上、 today-forecast の次に束縛している icon の中で today-forecast を使う物ですから、 let ごと try で囲んでしまいました。
あまり奇麗なコードではないですね。
正常系の中で何かしらの例外が出た場合に、 "no_connection.png" をアイコンにして、ツールチップを設定し、システムトレイにアイコンを追加しています。
そして出来上がりは冒頭のスクリーンショットのようになりました。
これでもう、いちいち例外のダイアログを閉じなくてもOK!
Clojure の try - catch - finally の使い方はこうらしいです。
(try (何か例外が出そうな処理) (catch (例外のクラス名) (例外を束縛する変数名) (例外が起きたときの処理。 例外が起きたら、ここの戻り値が try の戻り値になる) (finally (例外が起きても起きなくても行う処理)))
面白いのは、 try が値を返す事。例えば
(try 1 (catch Exception _ 2) (finally 3))
上のコードの評価値は 1 。そして、
(try 1 (throw (Exception. "Errorrrrrr")) (catch Exception _ 2) (finally 3))
このコードの評価値は 2 になります。 finally の値は try の値にはならないようですね。
ちなみに、 catch はいくつでも書けて、 finally は省略可。この辺は Java と変わりません。