OSDN Git Service

ダイヤモンド演算子対応
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / view / ActionManager.java
1 /*
2  * action manager
3  *
4  * License : The MIT License
5  * Copyright(c) 2008 olyutorskii
6  */
7
8 package jp.sfjp.jindolf.view;
9
10 import java.awt.Insets;
11 import java.awt.event.ActionListener;
12 import java.awt.event.KeyEvent;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import javax.swing.AbstractButton;
18 import javax.swing.ButtonGroup;
19 import javax.swing.ButtonModel;
20 import javax.swing.Icon;
21 import javax.swing.JButton;
22 import javax.swing.JMenu;
23 import javax.swing.JMenuBar;
24 import javax.swing.JMenuItem;
25 import javax.swing.JRadioButtonMenuItem;
26 import javax.swing.JToolBar;
27 import javax.swing.KeyStroke;
28 import javax.swing.LookAndFeel;
29 import javax.swing.UIManager;
30 import jp.sfjp.jindolf.ResourceManager;
31 import jp.sfjp.jindolf.VerInfo;
32 import jp.sfjp.jindolf.util.GUIUtils;
33
34 /**
35  * メニュー、ボタン、その他各種Actionを伴うイベントを生成する
36  * コンポーネントの一括管理。
37  */
38 public class ActionManager{
39
40     /** アクション{@value}。 */
41     public static final String CMD_ACCOUNT    = "ACCOUNT";
42     /** アクション{@value}。 */
43     public static final String CMD_EXIT       = "EXIT";
44     /** アクション{@value}。 */
45     public static final String CMD_COPY       = "COPY";
46     /** アクション{@value}。 */
47     public static final String CMD_SHOWFIND   = "SHOWFIND";
48     /** アクション{@value}。 */
49     public static final String CMD_SEARCHNEXT = "SEARCHNEXT";
50     /** アクション{@value}。 */
51     public static final String CMD_SEARCHPREV = "SEARCHPREV";
52     /** アクション{@value}。 */
53     public static final String CMD_ALLPERIOD  = "ALLPERIOD";
54     /** アクション{@value}。 */
55     public static final String CMD_SHOWDIGEST = "DIGEST";
56     /** アクション{@value}。 */
57     public static final String CMD_WEBVILL    = "WEBVILL";
58     /** アクション{@value}。 */
59     public static final String CMD_WEBCAST    = "WEBCAST";
60     /** アクション{@value}。 */
61     public static final String CMD_WEBWIKI    = "WEBWIKI";
62     /** アクション{@value}。 */
63     public static final String CMD_RELOAD     = "RELOAD";
64     /** アクション{@value}。 */
65     public static final String CMD_DAYSUMMARY = "DAYSUMMARY";
66     /** アクション{@value}。 */
67     public static final String CMD_DAYEXPCSV  = "DAYEXPCSV";
68     /** アクション{@value}。 */
69     public static final String CMD_WEBDAY     = "WEBDAY";
70     /** アクション{@value}。 */
71     public static final String CMD_OPTION     = "OPTION";
72     /** アクション{@value}。 */
73     public static final String CMD_LANDF      = "LANDF";
74     /** アクション{@value}。 */
75     public static final String CMD_SHOWFILT   = "SHOWFILT";
76     /** アクション{@value}。 */
77     public static final String CMD_SHOWEDIT   = "SHOWEDIT";
78     /** アクション{@value}。 */
79     public static final String CMD_SHOWLOG    = "SHOWLOG";
80     /** アクション{@value}。 */
81     public static final String CMD_HELPDOC    = "HELPDOC";
82     /** アクション{@value}。 */
83     public static final String CMD_SHOWPORTAL = "SHOWPORTAL";
84     /** アクション{@value}。 */
85     public static final String CMD_ABOUT      = "ABOUT";
86
87     /** アクション{@value}。 */
88     public static final String CMD_COPYTALK    = "COPYTALK";
89     /** アクション{@value}。 */
90     public static final String CMD_JUMPANCHOR  = "JUMPANCHOR";
91     /** アクション{@value}。 */
92     public static final String CMD_WEBTALK     = "WEBTALK";
93     /** アクション{@value}。 */
94     public static final String CMD_SWITCHORDER = "SWITCHORDER";
95     /** アクション{@value}。 */
96     public static final String CMD_VILLAGELIST = "VILLAGELIST";
97     /** アクション{@value}。 */
98     public static final String CMD_FONTSIZESEL = "FONTSIZESEL";
99
100     /** WWWアイコン。 */
101     public static final Icon ICON_WWW = GUIUtils.getWWWIcon();
102     /** 検索アイコン。 */
103     public static final Icon ICON_FIND;
104     /** 前検索アイコン。 */
105     public static final Icon ICON_SEARCH_PREV;
106     /** 次検索アイコン。 */
107     public static final Icon ICON_SEARCH_NEXT;
108     /** リロードアイコン。 */
109     public static final Icon ICON_RELOAD;
110     /** フィルタアイコン。 */
111     public static final Icon ICON_FILTER;
112     /** 発言エディタアイコン。 */
113     public static final Icon ICON_EDITOR;
114
115     private static final KeyStroke KEY_F1 = KeyStroke.getKeyStroke("F1");
116     private static final KeyStroke KEY_F3 = KeyStroke.getKeyStroke("F3");
117     private static final KeyStroke KEY_SHIFT_F3 =
118             KeyStroke.getKeyStroke("shift F3");
119     private static final KeyStroke KEY_F5 = KeyStroke.getKeyStroke("F5");
120     private static final KeyStroke KEY_CTRL_F =
121             KeyStroke.getKeyStroke("ctrl F");
122
123     static{
124         ICON_FIND =
125             ResourceManager.getImageIcon("resources/image/tb_find.png");
126
127         ICON_SEARCH_PREV =
128             ResourceManager.getImageIcon("resources/image/tb_findprev.png");
129
130         ICON_SEARCH_NEXT =
131             ResourceManager.getImageIcon("resources/image/tb_findnext.png");
132
133         ICON_RELOAD =
134             ResourceManager.getImageIcon("resources/image/tb_reload.png");
135
136         ICON_FILTER =
137             ResourceManager.getImageIcon("resources/image/tb_filter.png");
138
139         ICON_EDITOR =
140             ResourceManager.getImageIcon("resources/image/tb_editor.png");
141     }
142
143     private final Set<AbstractButton> actionItems =
144             new HashSet<>();
145     private final Map<String, JMenuItem> namedMenuItems =
146             new HashMap<>();
147     private final Map<String, JButton> namedToolButtons =
148             new HashMap<>();
149
150     private final JMenuBar menuBar;
151
152     private final JMenu menuFile;
153     private final JMenu menuEdit;
154     private final JMenu menuVillage;
155     private final JMenu menuDay;
156     private final JMenu menuPreference;
157     private final JMenu menuTool;
158     private final JMenu menuHelp;
159
160     private final JMenu menuLook;
161     private final ButtonGroup landfGroup = new ButtonGroup();
162     private final Map<ButtonModel, String> landfMap =
163         new HashMap<>();
164
165     private final JToolBar browseToolBar;
166
167     /**
168      * コンストラクタ。
169      */
170     public ActionManager(){
171         this.menuFile       = buildMenu("Jindolf",  KeyEvent.VK_F);
172         this.menuEdit       = buildMenu("編集",     KeyEvent.VK_E);
173         this.menuVillage    = buildMenu("村",       KeyEvent.VK_V);
174         this.menuDay        = buildMenu("日",       KeyEvent.VK_D);
175         this.menuPreference = buildMenu("設定",     KeyEvent.VK_P);
176         this.menuTool       = buildMenu("ツール",   KeyEvent.VK_T);
177         this.menuHelp       = buildMenu("ヘルプ",   KeyEvent.VK_H);
178
179         this.menuLook = buildLookAndFeelMenu("ルック&フィール", KeyEvent.VK_L);
180
181         buildMenuItem(CMD_ACCOUNT, "アカウント管理", KeyEvent.VK_M);
182         buildMenuItem(CMD_EXIT, "終了", KeyEvent.VK_X);
183         buildMenuItem(CMD_COPY, "選択範囲をコピー", KeyEvent.VK_C);
184         buildMenuItem(CMD_SHOWFIND, "検索...", KeyEvent.VK_F);
185         buildMenuItem(CMD_SEARCHNEXT, "次候補", KeyEvent.VK_N);
186         buildMenuItem(CMD_SEARCHPREV, "前候補", KeyEvent.VK_P);
187         buildMenuItem(CMD_ALLPERIOD, "全日程の一括読み込み", KeyEvent.VK_R);
188         buildMenuItem(CMD_SHOWDIGEST, "村のダイジェストを表示...",
189                 KeyEvent.VK_D);
190         buildMenuItem(CMD_WEBVILL, "この村をブラウザで表示...", KeyEvent.VK_N);
191         buildMenuItem(CMD_WEBWIKI,
192                       "まとめサイトの村ページを表示...", KeyEvent.VK_M);
193         buildMenuItem(CMD_WEBCAST, "キャスト紹介表ジェネレータ...",
194                       KeyEvent.VK_H);
195         buildMenuItem(CMD_RELOAD, "この日を強制リロード", KeyEvent.VK_R);
196         buildMenuItem(CMD_DAYSUMMARY, "この日の発言を集計...", KeyEvent.VK_D);
197         buildMenuItem(CMD_DAYEXPCSV, "CSVへエクスポート...", KeyEvent.VK_C);
198         buildMenuItem(CMD_WEBDAY, "この日をブラウザで表示...", KeyEvent.VK_B);
199         buildMenuItem(CMD_OPTION, "オプション...", KeyEvent.VK_O);
200         buildMenuItem(CMD_SHOWFILT, "発言フィルタ", KeyEvent.VK_F);
201         buildMenuItem(CMD_SHOWEDIT, "発言エディタ", KeyEvent.VK_E);
202         buildMenuItem(CMD_SHOWLOG, "ログ表示", KeyEvent.VK_S);
203         buildMenuItem(CMD_HELPDOC, "ヘルプ表示", KeyEvent.VK_H);
204         buildMenuItem(CMD_SHOWPORTAL, "ポータルサイト...", KeyEvent.VK_P);
205         buildMenuItem(CMD_ABOUT, VerInfo.TITLE + "について...", KeyEvent.VK_A);
206
207         buildToolButton(CMD_RELOAD, "選択中の日を強制リロード", ICON_RELOAD);
208         buildToolButton(CMD_SHOWFIND,   "検索",     ICON_FIND);
209         buildToolButton(CMD_SEARCHPREV, "↑前候補", ICON_SEARCH_PREV);
210         buildToolButton(CMD_SEARCHNEXT, "↓次候補", ICON_SEARCH_NEXT);
211         buildToolButton(CMD_SHOWFILT, "発言フィルタ", ICON_FILTER);
212         buildToolButton(CMD_SHOWEDIT, "発言エディタ", ICON_EDITOR);
213
214         getMenuItem(CMD_SHOWPORTAL).setIcon(ICON_WWW);
215         getMenuItem(CMD_WEBVILL)   .setIcon(ICON_WWW);
216         getMenuItem(CMD_WEBWIKI)   .setIcon(ICON_WWW);
217         getMenuItem(CMD_WEBCAST)   .setIcon(ICON_WWW);
218         getMenuItem(CMD_WEBDAY)    .setIcon(ICON_WWW);
219         getMenuItem(CMD_SHOWFIND)  .setIcon(ICON_FIND);
220         getMenuItem(CMD_SEARCHPREV).setIcon(ICON_SEARCH_PREV);
221         getMenuItem(CMD_SEARCHNEXT).setIcon(ICON_SEARCH_NEXT);
222         getMenuItem(CMD_SHOWFILT)  .setIcon(ICON_FILTER);
223         getMenuItem(CMD_SHOWEDIT)  .setIcon(ICON_EDITOR);
224
225         registKeyAccelerator();
226
227         this.menuBar       = buildMenuBar();
228         this.browseToolBar = buildBrowseToolBar();
229
230         appearVillageImpl(false);
231         appearPeriodImpl(false);
232
233         return;
234     }
235
236     /**
237      * メニューを生成する。
238      * @param label メニューラベル
239      * @param nemonic ニモニックキー
240      * @return メニュー
241      */
242     private JMenu buildMenu(String label, int nemonic){
243         JMenu result = new JMenu();
244
245         String keyText = label + "(" + KeyEvent.getKeyText(nemonic) + ")";
246
247         result.setText(keyText);
248         result.setMnemonic(nemonic);
249
250         return result;
251     }
252
253     /**
254      * メニューアイテムを生成する。
255      * @param command アクションコマンド名
256      * @param label メニューラベル
257      * @param nemonic ニモニックキー
258      * @return メニューアイテム
259      */
260     private JMenuItem buildMenuItem(String command,
261                                       String label,
262                                       int nemonic ){
263         JMenuItem result = new JMenuItem();
264
265         String keyText = label + "(" + KeyEvent.getKeyText(nemonic) + ")";
266
267         result.setActionCommand(command);
268         result.setText(keyText);
269         result.setMnemonic(nemonic);
270
271         this.actionItems.add(result);
272         this.namedMenuItems.put(command, result);
273
274         return result;
275     }
276
277     /**
278      * ツールボタンを生成する。
279      * @param command アクションコマンド名
280      * @param tooltip ツールチップ文字列
281      * @param icon アイコン画像
282      * @return ツールボタン
283      */
284     private JButton buildToolButton(String command,
285                                       String tooltip,
286                                       Icon icon){
287         JButton result = new JButton();
288
289         result.setIcon(icon);
290         result.setToolTipText(tooltip);
291         result.setMargin(new Insets(1, 1, 1, 1));
292         result.setActionCommand(command);
293
294         this.actionItems.add(result);
295         this.namedToolButtons.put(command, result);
296
297         return result;
298     }
299
300     /**
301      * L&F 一覧メニューを作成する。
302      * @param label メニューラベル
303      * @param nemonic ニモニックキー
304      * @return L&F 一覧メニュー
305      */
306     private JMenu buildLookAndFeelMenu(String label, int nemonic){
307         JMenu result = buildMenu(label, nemonic);
308
309         LookAndFeel currentLookAndFeel = UIManager.getLookAndFeel();
310         String currentName = currentLookAndFeel.getClass().getName();
311         JMenuItem matchedButton = null;
312
313         UIManager.LookAndFeelInfo[] landfs =
314                 UIManager.getInstalledLookAndFeels();
315         for(UIManager.LookAndFeelInfo lafInfo : landfs){
316             String name      = lafInfo.getName();
317             String className = lafInfo.getClassName();
318
319             JRadioButtonMenuItem button = new JRadioButtonMenuItem(name);
320             button.setActionCommand(CMD_LANDF);
321
322             if(className.equals(currentName)) matchedButton = button;
323
324             this.actionItems.add(button);
325             this.landfGroup.add(button);
326             this.landfMap.put(button.getModel(), className);
327
328             result.add(button);
329         }
330
331         if(matchedButton != null) matchedButton.setSelected(true);
332
333         return result;
334     }
335
336     /**
337      * アクセラレータの設定。
338      */
339     private void registKeyAccelerator(){
340         getMenuItem(CMD_HELPDOC)    .setAccelerator(KEY_F1);
341         getMenuItem(CMD_SHOWFIND)   .setAccelerator(KEY_CTRL_F);
342         getMenuItem(CMD_SEARCHNEXT) .setAccelerator(KEY_F3);
343         getMenuItem(CMD_SEARCHPREV) .setAccelerator(KEY_SHIFT_F3);
344         getMenuItem(CMD_RELOAD)     .setAccelerator(KEY_F5);
345         return;
346     }
347
348     /**
349      * アクションコマンド名からメニューアイテムを探す。
350      * @param command アクションコマンド名
351      * @return メニューアイテム
352      */
353     private JMenuItem getMenuItem(String command){
354         JMenuItem result = this.namedMenuItems.get(command);
355         return result;
356     }
357
358     /**
359      * アクションコマンド名からツールボタンを探す。
360      * @param command アクションコマンド名
361      * @return ツールボタン
362      */
363     private JButton getToolButton(String command){
364         JButton result = this.namedToolButtons.get(command);
365         return result;
366     }
367
368     /**
369      * 現在メニューで選択中のL&amp;Fのクラス名を返す。
370      * @return L&amp;F クラス名
371      */
372     public String getSelectedLookAndFeel(){
373         ButtonModel selected = this.landfGroup.getSelection();
374         if(selected == null) return null;
375         String className = this.landfMap.get(selected);
376         return className;
377     }
378
379     /**
380      * 全てのボタンにアクションリスナーを登録する。
381      * @param listener アクションリスナー
382      */
383     public void addActionListener(ActionListener listener){
384         for(AbstractButton button : this.actionItems){
385             button.addActionListener(listener);
386         }
387         return;
388     }
389
390     /**
391      * メニューバーを生成する。
392      * @return メニューバー
393      */
394     private JMenuBar buildMenuBar(){
395         this.menuFile.add(getMenuItem(CMD_ACCOUNT));
396         this.menuFile.addSeparator();
397         this.menuFile.add(getMenuItem(CMD_EXIT));
398
399         this.menuEdit.add(getMenuItem(CMD_COPY));
400         this.menuEdit.addSeparator();
401         this.menuEdit.add(getMenuItem(CMD_SHOWFIND));
402         this.menuEdit.add(getMenuItem(CMD_SEARCHPREV));
403         this.menuEdit.add(getMenuItem(CMD_SEARCHNEXT));
404
405         this.menuVillage.add(getMenuItem(CMD_ALLPERIOD));
406         this.menuVillage.add(getMenuItem(CMD_SHOWDIGEST));
407         this.menuVillage.addSeparator();
408         this.menuVillage.add(getMenuItem(CMD_WEBVILL));
409         this.menuVillage.add(getMenuItem(CMD_WEBWIKI));
410         this.menuVillage.add(getMenuItem(CMD_WEBCAST));
411
412         this.menuDay.add(getMenuItem(CMD_RELOAD));
413         this.menuDay.add(getMenuItem(CMD_DAYSUMMARY));
414         this.menuDay.add(getMenuItem(CMD_DAYEXPCSV));
415         this.menuDay.addSeparator();
416         this.menuDay.add(getMenuItem(CMD_WEBDAY));
417
418         this.menuPreference.add(getMenuItem(CMD_OPTION));
419         this.menuPreference.addSeparator();
420         this.menuPreference.add(this.menuLook);
421
422         this.menuTool.add(getMenuItem(CMD_SHOWFILT));
423         this.menuTool.add(getMenuItem(CMD_SHOWEDIT));
424         this.menuTool.add(getMenuItem(CMD_SHOWLOG));
425
426         this.menuHelp.add(getMenuItem(CMD_HELPDOC));
427         this.menuHelp.addSeparator();
428         this.menuHelp.add(getMenuItem(CMD_SHOWPORTAL));
429         this.menuHelp.add(getMenuItem(CMD_ABOUT));
430
431         JMenuBar bar = new JMenuBar();
432
433         bar.add(this.menuFile);
434         bar.add(this.menuEdit);
435         bar.add(this.menuVillage);
436         bar.add(this.menuDay);
437         bar.add(this.menuPreference);
438         bar.add(this.menuTool);
439         bar.add(this.menuHelp);
440
441         return bar;
442     }
443
444     /**
445      * メニューバーを取得する。
446      * @return メニューバー
447      */
448     public JMenuBar getMenuBar(){
449         return this.menuBar;
450     }
451
452     /**
453      * ブラウザ用ツールバーの生成を行う。
454      * @return ツールバー
455      */
456     private JToolBar buildBrowseToolBar(){
457         JToolBar toolBar = new JToolBar();
458
459         toolBar.add(getToolButton(CMD_RELOAD));
460         toolBar.addSeparator();
461         toolBar.add(getToolButton(CMD_SHOWFIND));
462         toolBar.add(getToolButton(CMD_SEARCHNEXT));
463         toolBar.add(getToolButton(CMD_SEARCHPREV));
464         toolBar.addSeparator();
465         toolBar.add(getToolButton(CMD_SHOWFILT));
466         toolBar.add(getToolButton(CMD_SHOWEDIT));
467
468         return toolBar;
469     }
470
471     /**
472      * ブラウザ用ツールバーを取得する。
473      * @return ツールバー
474      */
475     public JToolBar getBrowseToolBar(){
476         return this.browseToolBar;
477     }
478
479     /**
480      * Periodが表示されているか通知を受ける。
481      * @param appear 表示されているときはtrue
482      */
483     private void appearPeriodImpl(boolean appear){
484         if(appear) appearVillageImpl(appear);
485
486         this.menuEdit.setEnabled(appear);
487         this.menuDay .setEnabled(appear);
488
489         getToolButton(CMD_RELOAD)     .setEnabled(appear);
490         getToolButton(CMD_SHOWFIND)   .setEnabled(appear);
491         getToolButton(CMD_SEARCHNEXT) .setEnabled(appear);
492         getToolButton(CMD_SEARCHPREV) .setEnabled(appear);
493
494         return;
495     }
496
497     /**
498      * Periodが表示されているか通知を受ける。
499      * @param appear 表示されているときはtrue
500      */
501     public void appearPeriod(boolean appear){
502         appearPeriodImpl(appear);
503         return;
504     }
505
506     /**
507      * 村が表示されているか通知を受ける。
508      * @param appear 表示されているときはtrue
509      */
510     private void appearVillageImpl(boolean appear){
511         if( ! appear) appearPeriodImpl(appear);
512
513         this.menuVillage.setEnabled(appear);
514
515         return;
516     }
517
518     /**
519      * 村が表示されているか通知を受ける。
520      * @param appear 表示されているときはtrue
521      */
522     public void appearVillage(boolean appear){
523         appearVillageImpl(appear);
524         return;
525     }
526
527 }