OSDN Git Service

split BusyStatus from Controller.
authorOlyutorskii <olyutorskii@users.osdn.me>
Thu, 30 Apr 2020 07:01:05 +0000 (16:01 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Thu, 30 Apr 2020 07:01:05 +0000 (16:01 +0900)
src/main/java/jp/sfjp/jindolf/BusyStatus.java [new file with mode: 0644]
src/main/java/jp/sfjp/jindolf/Controller.java

diff --git a/src/main/java/jp/sfjp/jindolf/BusyStatus.java b/src/main/java/jp/sfjp/jindolf/BusyStatus.java
new file mode 100644 (file)
index 0000000..c9bd402
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * busy status manager
+ *
+ * License : The MIT License
+ * Copyright(c) 2020 olyutorskii
+ */
+
+package jp.sfjp.jindolf;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jp.sfjp.jindolf.view.TopFrame;
+import jp.sfjp.jindolf.view.TopView;
+
+/**
+ * ビジー状態の見た目を管理する。
+ *
+ * <p>ビジー状態を伴うタスクの管理も行う。
+ *
+ * <p>EDTで処理しきれない長時間タスクを実行している状況、
+ * およびその間のGUI操作が抑止される期間をビジーと呼ぶ。
+ */
+public class BusyStatus {
+
+    private static final Logger LOGGER = Logger.getAnonymousLogger();
+
+
+    private final TopFrame topFrame;
+    private final Executor executor = Executors.newCachedThreadPool();
+
+    private boolean isBusy = false;
+
+
+    /**
+     * コンストラクタ。
+     *
+     * @param topFrame TopFrameインスタンス
+     */
+    public BusyStatus(TopFrame topFrame){
+        super();
+        this.topFrame = topFrame;
+        return;
+    }
+
+
+    /**
+     * ビジー状態か否か返す。
+     *
+     * @return ビジーならtrue
+     */
+    public boolean isBusy(){
+        return this.isBusy;
+    }
+
+    /**
+     * ビジー状態を設定する。
+     *
+     * <p>ヘビーなタスク実行をアピールするために、
+     * プログレスバーとカーソルの設定を行う。
+     *
+     * <p>ビジー中のトップフレームのマウス操作、キーボード入力は
+     * 全てグラブされるため無視される。
+     *
+     * @param flag trueならプログレスバーのアニメ開始&amp;WAITカーソル。
+     * falseなら停止&amp;通常カーソル。
+     * @param msg フッタメッセージ。nullなら変更なし。
+     */
+    public void setBusy(boolean flag, String msg){
+        if(EventQueue.isDispatchThread()){
+            setBusyEdt(flag, msg);
+            return;
+        }
+
+        try{
+            EventQueue.invokeAndWait(() -> {
+                setBusyEdt(flag, msg);
+            });
+        }catch(InterruptedException | InvocationTargetException e){
+            LOGGER.log(Level.SEVERE, "ビジー処理で失敗", e);
+        }
+
+        return;
+    }
+
+    /**
+     * ビジー状態を設定する。
+     *
+     * <p>原則EDTから呼ばねばならない。
+     *
+     * @param flag trueならビジー
+     * @param msg メッセージ。nullなら変更なし。
+     */
+    public void setBusyEdt(boolean flag, String msg){
+        assert EventQueue.isDispatchThread();
+
+        this.isBusy = flag;
+
+        this.topFrame.setBusy(this.isBusy);
+
+        if(msg != null){
+            TopView topView = this.topFrame.getTopView();
+            topView.updateSysMessage(msg);
+        }
+
+        return;
+    }
+
+    /**
+     * 軽量タスクをEDTで実行する。
+     *
+     * <p>タスク実行中はビジー状態となる。
+     *
+     * <p>軽量タスク実行中はイベントループが停止するので、
+     * 入出力待ちを伴わなずに早急に終わるタスクでなければならない。
+     *
+     * @param task 軽量タスク
+     * @param beforeMsg ビジー中ステータス文字列
+     * @param afterMsg ビジー復帰時のステータス文字列
+     */
+    public void submitLightBusyTask(Runnable task,
+                                    String beforeMsg,
+                                    String afterMsg ){
+        EventQueue.invokeLater(() -> {
+            setBusy(true, beforeMsg);
+        });
+
+        EventQueue.invokeLater(task);
+
+        EventQueue.invokeLater(() -> {
+            setBusy(false, afterMsg);
+        });
+
+        return;
+    }
+
+    /**
+     * 重量級タスクをEDTとは別のスレッドで実行する。
+     *
+     * <p>タスク実行中はビジー状態となる。
+     *
+     * @param heavyTask 重量級タスク
+     * @param beforeMsg ビジー中ステータス文字列
+     * @param afterMsg ビジー復帰時のステータス文字列
+     */
+    public void submitHeavyBusyTask(final Runnable heavyTask,
+                                    final String beforeMsg,
+                                    final String afterMsg ){
+        setBusy(true, beforeMsg);
+
+        EventQueue.invokeLater(() -> {
+            fork(() -> {
+                try{
+                    heavyTask.run();
+                }finally{
+                    setBusy(false, afterMsg);
+                }
+            });
+        });
+
+        return;
+    }
+
+    /**
+     * スレッドプールを用いて非EDTなタスクを投入する。
+     *
+     * @param task タスク
+     */
+    private void fork(Runnable task){
+        this.executor.execute(task);
+        return;
+    }
+
+}
index a26a35b..1dc94d0 100644 (file)
@@ -16,12 +16,9 @@ import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.text.MessageFormat;
 import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
 import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -120,8 +117,7 @@ public class Controller
     private final ChangeListener filterWatcher =
             new FilterWatcher();
 
-    private final Executor executor = Executors.newCachedThreadPool();
-    private volatile boolean isBusyNow;
+    private final BusyStatus busyStatus;
 
 
     /**
@@ -184,6 +180,7 @@ public class Controller
                 shutdown();
             }
         });
+        this.busyStatus = new BusyStatus(topFrame);
 
         filterPanel.addChangeListener(this.filterWatcher);
 
@@ -325,34 +322,6 @@ public class Controller
     }
 
     /**
-     * ビジー状態の設定を行う。
-     *
-     * <p>ヘビーなタスク実行をアピールするために、
-     * プログレスバーとカーソルの設定を行う。
-     *
-     * <p>ビジー中のActionコマンド受信は無視される。
-     *
-     * <p>ビジー中のトップフレームのマウス操作、キーボード入力は
-     * 全てグラブされるため無視される。
-     *
-     * @param isBusy trueならプログレスバーのアニメ開始&amp;WAITカーソル。
-     * falseなら停止&amp;通常カーソル。
-     * @param msg フッタメッセージ。nullなら変更なし。
-     */
-    private void setBusy(boolean isBusy, String msg){
-        this.isBusyNow = isBusy;
-
-        TopFrame topFrame = getTopFrame();
-
-        topFrame.setBusy(isBusy);
-        if(msg != null){
-            this.topView.updateSysMessage(msg);
-        }
-
-        return;
-    }
-
-    /**
      * ステータスバーを更新する。
      * @param message メッセージ
      */
@@ -362,91 +331,6 @@ public class Controller
     }
 
     /**
-     * ビジー状態を設定する。
-     *
-     * <p>EDT以外から呼ばれると実際の処理が次回のEDT移行に遅延される。
-     *
-     * @param isBusy ビジーならtrue
-     * @param message ステータスバー表示。nullなら変更なし
-     */
-    public void submitBusyStatus(boolean isBusy, String message){
-        Runnable task = () -> {
-            setBusy(isBusy, message);
-        };
-
-        if(EventQueue.isDispatchThread()){
-            task.run();
-        }else{
-            try{
-                EventQueue.invokeAndWait(task);
-            }catch(InvocationTargetException | InterruptedException e){
-                LOGGER.log(Level.SEVERE, "ビジー処理で失敗", e);
-            }
-        }
-
-        return;
-    }
-
-    /**
-     * 軽量タスクをEDTで実行する。
-     *
-     * <p>タスク実行中はビジー状態となる。
-     *
-     * <p>軽量タスク実行中はイベントループが停止するので、
-     * 入出力待ちを伴わなずに早急に終わるタスクでなければならない。
-     *
-     * @param task 軽量タスク
-     * @param beforeMsg ビジー中ステータス文字列
-     * @param afterMsg ビジー復帰時のステータス文字列
-     */
-    public void submitLightBusyTask(Runnable task,
-                                    String beforeMsg,
-                                    String afterMsg ){
-        submitBusyStatus(true, beforeMsg);
-        EventQueue.invokeLater(task);
-        submitBusyStatus(false, afterMsg);
-
-        return;
-    }
-
-    /**
-     * 重量級タスクをEDTとは別のスレッドで実行する。
-     *
-     * <p>タスク実行中はビジー状態となる。
-     *
-     * @param heavyTask 重量級タスク
-     * @param beforeMsg ビジー中ステータス文字列
-     * @param afterMsg ビジー復帰時のステータス文字列
-     */
-    public void submitHeavyBusyTask(final Runnable heavyTask,
-                                    final String beforeMsg,
-                                    final String afterMsg ){
-        submitBusyStatus(true, beforeMsg);
-
-        EventQueue.invokeLater(() -> {
-            fork(() -> {
-                try{
-                    heavyTask.run();
-                }finally{
-                    submitBusyStatus(false, afterMsg);
-                }
-            });
-        });
-
-        return;
-    }
-
-    /**
-     * スレッドプールを用いて非EDTなタスクを投入する。
-     *
-     * @param task タスク
-     */
-    private void fork(Runnable task){
-        this.executor.execute(task);
-        return;
-    }
-
-    /**
      * About画面を表示する。
      */
     private void actionAbout(){
@@ -602,7 +486,7 @@ public class Controller
         String className = this.actionManager.getSelectedLookAndFeel();
         if(className == null) return;
 
-        submitLightBusyTask(
+        this.busyStatus.submitLightBusyTask(
             () -> {taskChangeLaF(className);},
             "Look&Feelを更新中…",
             "Look&Feelが更新されました"
@@ -777,7 +661,7 @@ public class Controller
             });
         };
 
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 task,
                 "一括読み込み開始",
                 "一括読み込み完了"
@@ -863,7 +747,7 @@ public class Controller
      * 一括検索処理。
      */
     private void bulkSearch(){
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 () -> {taskBulkSearch();},
                 null, null
         );
@@ -1017,7 +901,7 @@ public class Controller
      * 全日程の一括ロード。
      */
     private void actionLoadAllPeriod(){
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 () -> {taskLoadAllPeriod();},
                 "一括読み込み開始",
                 "一括読み込み完了"
@@ -1183,7 +1067,7 @@ public class Controller
 
         };
 
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 task,
                 "ジャンプ先の読み込み中…",
                 null
@@ -1200,7 +1084,7 @@ public class Controller
         if(result != JFileChooser.APPROVE_OPTION) return;
         File selected = this.xmlFileChooser.getSelectedFile();
 
-        submitHeavyBusyTask(() -> {
+        this.busyStatus.submitHeavyBusyTask(() -> {
             Village village;
 
             try{
@@ -1238,7 +1122,7 @@ public class Controller
      * @param land 国
      */
     private void submitReloadVillageList(final Land land){
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
             () -> {taskReloadVillageList(land);},
             "村一覧を読み込み中…",
             "村一覧の読み込み完了"
@@ -1304,7 +1188,7 @@ public class Controller
             });
         };
 
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 task,
                 "会話の読み込み中",
                 "会話の表示が完了"
@@ -1417,7 +1301,7 @@ public class Controller
             });
         };
 
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 task,
                 "村情報を読み込み中…",
                 "村情報の読み込み完了"
@@ -1437,7 +1321,7 @@ public class Controller
      */
     @Override
     public void actionPerformed(ActionEvent ev){
-        if(this.isBusyNow) return;
+        if(this.busyStatus.isBusy()) return;
 
         String cmd = ev.getActionCommand();
         if(cmd == null) return;
@@ -1572,7 +1456,7 @@ public class Controller
             }
         };
 
-        submitHeavyBusyTask(
+        this.busyStatus.submitHeavyBusyTask(
                 task,
                 "アンカーの展開中…",
                 null