OSDN Git Service

Merge branch 'Branch_release-'
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / view / TabBrowser.java
-/*\r
- * period viewer with tab access\r
- *\r
- * Copyright(c) 2008 olyutorskii\r
- * $Id: TabBrowser.java 964 2009-12-20 16:02:13Z olyutorskii $\r
- */\r
-\r
-package jp.sourceforge.jindolf;\r
-\r
-import java.awt.Component;\r
-import java.awt.event.ActionListener;\r
-import java.util.EventListener;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-import javax.swing.BorderFactory;\r
-import javax.swing.JPanel;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JTabbedPane;\r
-import javax.swing.SwingConstants;\r
-import javax.swing.border.Border;\r
-import javax.swing.event.EventListenerList;\r
-\r
-/**\r
- * タブを用いて村情報と各Periodを閲覧するためのコンポーネント。\r
- */\r
-@SuppressWarnings("serial")\r
-public class TabBrowser extends JTabbedPane{\r
-\r
-    private Village village;\r
-\r
-    private final VillageInfoPanel villageInfo = new VillageInfoPanel();\r
-\r
-    private FontInfo fontInfo;\r
-    private DialogPref dialogPref;\r
-\r
-    private final EventListenerList thisListenerList =\r
-            new EventListenerList();\r
-\r
-    /**\r
-     * 村が指定されていない状態のタブパネルを生成する。\r
-     */\r
-    public TabBrowser(){\r
-        super();\r
-\r
-        setTabPlacement(SwingConstants.TOP);\r
-        // Mac Aqua L&F ignore WRAP_TAB_LAYOUT\r
-        setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);\r
-\r
-        Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);\r
-        this.villageInfo.setBorder(border);\r
-\r
-        addTab("村情報", new JScrollPane(this.villageInfo));\r
-\r
-        setVillage(null);\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 村情報閲覧用のコンポーネントを更新する。\r
-     */\r
-    private void updateVillageInfo(){\r
-        Village target = getVillage();\r
-        this.villageInfo.updateVillage(target);\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 村情報表示タブを選択表示する。\r
-     */\r
-    private void selectVillageInfoTab(){\r
-        setSelectedIndex(0);\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 設定された村を返す。\r
-     * @return 設定された村\r
-     */\r
-    public Village getVillage(){\r
-        return this.village;\r
-    }\r
-\r
-    /**\r
-     * 新規に村を設定する。\r
-     * @param village 新しい村\r
-     */\r
-    public final void setVillage(Village village){\r
-        if(village == null){\r
-            if(this.village != null){\r
-                this.village.unloadPeriods();\r
-            }\r
-            this.village = null;\r
-            selectVillageInfoTab();\r
-            modifyTabCount(0);\r
-            updateVillageInfo();\r
-            return;\r
-        }else if(village != this.village){\r
-            selectVillageInfoTab();\r
-        }\r
-\r
-        if(this.village != null){\r
-            this.village.unloadPeriods();\r
-        }\r
-        this.village = village;\r
-\r
-        updateVillageInfo();\r
-\r
-        int periodNum = this.village.getPeriodSize();\r
-        modifyTabCount(periodNum);\r
-\r
-        for(int periodDays = 0; periodDays < periodNum; periodDays++){\r
-            Period period = this.village.getPeriod(periodDays);\r
-            int tabIndex = periodDaysToTabIndex(periodDays);\r
-            PeriodView periodView = getPeriodView(tabIndex);\r
-            if(periodView == null){\r
-                periodView = new PeriodView(period);\r
-                periodView.setFontInfo(this.fontInfo);\r
-                periodView.setDialogPref(this.dialogPref);\r
-                setComponentAt(tabIndex, periodView);\r
-                Discussion discussion = periodView.getDiscussion();\r
-                for(ActionListener listener : getActionListeners()){\r
-                    discussion.addActionListener(listener);\r
-                }\r
-                for(AnchorHitListener listener : getAnchorHitListeners()){\r
-                    discussion.addAnchorHitListener(listener);\r
-                }\r
-            }\r
-            String caption = period.getCaption();\r
-            setTitleAt(tabIndex, caption);\r
-            if(period == periodView.getPeriod()) continue;\r
-            periodView.setPeriod(period);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 指定した数のPeriodが収まるよう必要十分なタブ数を用意する。\r
-     * @param periods Periodの数\r
-     */\r
-    private void modifyTabCount(int periods){ // TODO 0でも大丈夫?\r
-        int maxPeriodDays = periods - 1;\r
-\r
-        for(;;){   // 短ければタブ追加\r
-            int maxTabIndex = getTabCount() - 1;\r
-            if(tabIndexToPeriodDays(maxTabIndex) >= maxPeriodDays) break;\r
-            String title = "";\r
-            Component component = new JPanel();\r
-            addTab(title, component);\r
-        }\r
-\r
-        for(;;){   // 長ければ余分なタブ削除\r
-            int maxTabIndex = getTabCount() - 1;\r
-            if(tabIndexToPeriodDays(maxTabIndex) <= maxPeriodDays) break;\r
-            remove(maxTabIndex);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * Period日付指定からタブインデックス値への変換。\r
-     * @param days Period日付指定\r
-     * @return タブインデックス\r
-     */\r
-    public int periodDaysToTabIndex(int days){\r
-        int tabIndex = days+1;\r
-        if(tabIndex >= getTabCount()) return -1;\r
-        return tabIndex;\r
-    }\r
-\r
-    /**\r
-     * タブインデックス値からPeriod日付指定への変換。\r
-     * @param tabIndex タブインデックス\r
-     * @return Period日付指定\r
-     */\r
-    private int tabIndexToPeriodDays(int tabIndex){\r
-        if(tabIndex >= getTabCount()) return - 1;\r
-        int days = tabIndex - 1;\r
-        return days;\r
-    }\r
-\r
-    /**\r
-     * PeriodView一覧を得る。\r
-     * @return PeriodView の List\r
-     */\r
-    public List<PeriodView> getPeriodViewList(){\r
-        List<PeriodView> result = new LinkedList<PeriodView>();\r
-\r
-        int tabCount = getTabCount();\r
-        for(int tabIndex = 0; tabIndex <= tabCount - 1; tabIndex++){\r
-            Component component = getComponent(tabIndex);\r
-            if(component == null) continue;\r
-            if( ! (component instanceof PeriodView) ) continue;\r
-            PeriodView periodView = (PeriodView) component;\r
-            result.add(periodView);\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * 現在タブ選択中のDiscussionを返す。\r
-     * Periodに関係ないタブが選択されていたらnullを返す。\r
-     * @return 現在選択中のDiscussion\r
-     */\r
-    public Discussion currentDiscussion(){\r
-        int tabIndex = getSelectedIndex();\r
-        Discussion result = getDiscussion(tabIndex);\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * 現在タブ選択中のPeriodViewを返す。\r
-     * Periodに関係ないタブが選択されていたらnullを返す。\r
-     * @return 現在選択中のPeriodView\r
-     */\r
-    public PeriodView currentPeriodView(){\r
-        int tabIndex = getSelectedIndex();\r
-        PeriodView result = getPeriodView(tabIndex);\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * 指定したタブインデックスに関連付けられたPeriodViewを返す。\r
-     * Periodに関係ないタブが指定されたらnullを返す。\r
-     * @param tabIndex タブインデックス\r
-     * @return 指定されたPeriodView\r
-     */\r
-    public PeriodView getPeriodView(int tabIndex){\r
-        if(tabIndexToPeriodDays(tabIndex) < 0) return null;\r
-        if(tabIndex >= getTabCount()) return null;\r
-        Component component = getComponentAt(tabIndex);\r
-        if(component == null) return null;\r
-\r
-        if( ! (component instanceof PeriodView) ) return null;\r
-        PeriodView periodView = (PeriodView) component;\r
-\r
-        return periodView;\r
-    }\r
-\r
-    /**\r
-     * 指定したタブインデックスに関連付けられたDiscussionを返す。\r
-     * Periodに関係ないタブが指定されたらnullを返す。\r
-     * @param tabIndex タブインデックス\r
-     * @return 指定されたDiscussion\r
-     */\r
-    private Discussion getDiscussion(int tabIndex){\r
-        PeriodView periodView = getPeriodView(tabIndex);\r
-        if(periodView == null) return null;\r
-\r
-        Discussion result = periodView.getDiscussion();\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * フォント描画設定を変更する。\r
-     * @param fontInfo フォント\r
-     */\r
-    public void setFontInfo(FontInfo fontInfo){\r
-        this.fontInfo = fontInfo;\r
-\r
-        for(int tabIndex = 0; tabIndex <= getTabCount() - 1; tabIndex++){\r
-            PeriodView periodView = getPeriodView(tabIndex);\r
-            if(periodView == null) continue;\r
-            periodView.setFontInfo(this.fontInfo);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * 発言表示設定を変更する。\r
-     * @param dialogPref 発言表示設定\r
-     */\r
-    public void setDialogPref(DialogPref dialogPref){\r
-        this.dialogPref = dialogPref;\r
-\r
-        for(int tabIndex = 0; tabIndex <= getTabCount() - 1; tabIndex++){\r
-            PeriodView periodView = getPeriodView(tabIndex);\r
-            if(periodView == null) continue;\r
-            periodView.setDialogPref(this.dialogPref);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * ActionListenerを追加する。\r
-     * @param listener リスナー\r
-     */\r
-    public void addActionListener(ActionListener listener){\r
-        this.thisListenerList.add(ActionListener.class, listener);\r
-\r
-        if(this.village == null) return;\r
-        int periodNum = this.village.getPeriodSize();\r
-        for(int periodDays = 0; periodDays < periodNum; periodDays++){\r
-            int tabIndex = periodDaysToTabIndex(periodDays);\r
-            Discussion discussion = getDiscussion(tabIndex);\r
-            if(discussion == null) continue;\r
-            discussion.addActionListener(listener);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * ActionListenerを削除する。\r
-     * @param listener リスナー\r
-     */\r
-    public void removeActionListener(ActionListener listener){\r
-        this.thisListenerList.remove(ActionListener.class, listener);\r
-\r
-        if(this.village == null) return;\r
-        int periodNum = this.village.getPeriodSize();\r
-        for(int periodDays = 0; periodDays < periodNum; periodDays++){\r
-            int tabIndex = periodDaysToTabIndex(periodDays);\r
-            Discussion discussion = getDiscussion(tabIndex);\r
-            if(discussion == null) continue;\r
-            discussion.removeActionListener(listener);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * ActionListenerを列挙する。\r
-     * @return すべてのActionListener\r
-     */\r
-    public ActionListener[] getActionListeners(){\r
-        return this.thisListenerList.getListeners(ActionListener.class);\r
-    }\r
-\r
-    /**\r
-     * AnchorHitListenerを追加する。\r
-     * @param listener リスナー\r
-     */\r
-    public void addAnchorHitListener(AnchorHitListener listener){\r
-        this.thisListenerList.add(AnchorHitListener.class, listener);\r
-\r
-        if(this.village == null) return;\r
-        int periodNum = this.village.getPeriodSize();\r
-        for(int periodDays = 0; periodDays < periodNum; periodDays++){\r
-            int tabIndex = periodDaysToTabIndex(periodDays);\r
-            Discussion discussion = getDiscussion(tabIndex);\r
-            if(discussion == null) continue;\r
-            discussion.addAnchorHitListener(listener);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * AnchorHitListenerを削除する。\r
-     * @param listener リスナー\r
-     */\r
-    public void removeAnchorHitListener(AnchorHitListener listener){\r
-        this.thisListenerList.remove(AnchorHitListener.class, listener);\r
-\r
-        if(this.village == null) return;\r
-        int periodNum = this.village.getPeriodSize();\r
-        for(int periodDays = 0; periodDays < periodNum; periodDays++){\r
-            int tabIndex = periodDaysToTabIndex(periodDays);\r
-            Discussion discussion = getDiscussion(tabIndex);\r
-            if(discussion == null) continue;\r
-            discussion.removeAnchorHitListener(listener);\r
-        }\r
-\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * AnchorHitListenerを列挙する。\r
-     * @return すべてのAnchorHitListener\r
-     */\r
-    public AnchorHitListener[] getAnchorHitListeners(){\r
-        return this.thisListenerList.getListeners(AnchorHitListener.class);\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     * @param <T> {@inheritDoc}\r
-     * @param listenerType {@inheritDoc}\r
-     * @return {@inheritDoc}\r
-     */\r
-    @Override\r
-    public <T extends EventListener> T[] getListeners(Class<T> listenerType){\r
-        T[] result;\r
-        result = this.thisListenerList.getListeners(listenerType);\r
-\r
-        if(result.length <= 0){\r
-            result = super.getListeners(listenerType);\r
-        }\r
-\r
-        return result;\r
-    }\r
-\r
-}\r
+/*
+ * period viewer with tab access
+ *
+ * License : The MIT License
+ * Copyright(c) 2008 olyutorskii
+ */
+
+package jp.sfjp.jindolf.view;
+
+import java.awt.Component;
+import java.awt.event.ActionListener;
+import java.util.EventListener;
+import java.util.LinkedList;
+import java.util.List;
+import javax.swing.BorderFactory;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.event.EventListenerList;
+import jp.sfjp.jindolf.data.DialogPref;
+import jp.sfjp.jindolf.data.Period;
+import jp.sfjp.jindolf.data.Village;
+import jp.sfjp.jindolf.glyph.AnchorHitListener;
+import jp.sfjp.jindolf.glyph.Discussion;
+import jp.sfjp.jindolf.glyph.FontInfo;
+
+/**
+ * タブを用いて村情報と各Periodを閲覧するためのコンポーネント。
+ */
+@SuppressWarnings("serial")
+public class TabBrowser extends JTabbedPane{
+
+    private Village village;
+
+    private final VillageInfoPanel villageInfo = new VillageInfoPanel();
+
+    private FontInfo fontInfo;
+    private DialogPref dialogPref;
+
+    private final EventListenerList thisListenerList =
+            new EventListenerList();
+
+    /**
+     * 村が指定されていない状態のタブパネルを生成する。
+     */
+    public TabBrowser(){
+        super();
+
+        setTabPlacement(SwingConstants.TOP);
+        // Mac Aqua L&F ignore WRAP_TAB_LAYOUT
+        setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
+
+        Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
+        this.villageInfo.setBorder(border);
+
+        addTab("村情報", new JScrollPane(this.villageInfo));
+
+        setVillage(null);
+
+        return;
+    }
+
+    /**
+     * 村情報閲覧用のコンポーネントを更新する。
+     */
+    private void updateVillageInfo(){
+        Village target = getVillage();
+        this.villageInfo.updateVillage(target);
+        return;
+    }
+
+    /**
+     * 村情報表示タブを選択表示する。
+     */
+    private void selectVillageInfoTab(){
+        setSelectedIndex(0);
+        return;
+    }
+
+    /**
+     * 設定された村を返す。
+     * @return 設定された村
+     */
+    public Village getVillage(){
+        return this.village;
+    }
+
+    /**
+     * 新規に村を設定する。
+     * @param village 新しい村
+     */
+    public final void setVillage(Village village){
+        if(village == null){
+            if(this.village != null){
+                this.village.unloadPeriods();
+            }
+            this.village = null;
+            selectVillageInfoTab();
+            modifyTabCount(0);
+            updateVillageInfo();
+            return;
+        }else if(village != this.village){
+            selectVillageInfoTab();
+        }
+
+        if(this.village != null){
+            this.village.unloadPeriods();
+        }
+        this.village = village;
+
+        updateVillageInfo();
+
+        int periodNum = this.village.getPeriodSize();
+        modifyTabCount(periodNum);
+
+        for(int periodDays = 0; periodDays < periodNum; periodDays++){
+            Period period = this.village.getPeriod(periodDays);
+            int tabIndex = periodDaysToTabIndex(periodDays);
+            PeriodView periodView = getPeriodView(tabIndex);
+            if(periodView == null){
+                periodView = new PeriodView(period);
+                periodView.setFontInfo(this.fontInfo);
+                periodView.setDialogPref(this.dialogPref);
+                setComponentAt(tabIndex, periodView);
+                Discussion discussion = periodView.getDiscussion();
+                for(ActionListener listener : getActionListeners()){
+                    discussion.addActionListener(listener);
+                }
+                for(AnchorHitListener listener : getAnchorHitListeners()){
+                    discussion.addAnchorHitListener(listener);
+                }
+            }
+            String caption = period.getCaption();
+            setTitleAt(tabIndex, caption);
+            if(period == periodView.getPeriod()) continue;
+            periodView.setPeriod(period);
+        }
+
+        return;
+    }
+
+    /**
+     * 指定した数のPeriodが収まるよう必要十分なタブ数を用意する。
+     * @param periods Periodの数
+     */
+    private void modifyTabCount(int periods){ // TODO 0でも大丈夫?
+        int maxPeriodDays = periods - 1;
+
+        for(;;){   // 短ければタブ追加
+            int maxTabIndex = getTabCount() - 1;
+            if(tabIndexToPeriodDays(maxTabIndex) >= maxPeriodDays) break;
+            String title = "";
+            Component component = new JPanel();
+            addTab(title, component);
+        }
+
+        for(;;){   // 長ければ余分なタブ削除
+            int maxTabIndex = getTabCount() - 1;
+            if(tabIndexToPeriodDays(maxTabIndex) <= maxPeriodDays) break;
+            remove(maxTabIndex);
+        }
+
+        return;
+    }
+
+    /**
+     * Period日付指定からタブインデックス値への変換。
+     * @param days Period日付指定
+     * @return タブインデックス
+     */
+    public int periodDaysToTabIndex(int days){
+        int tabIndex = days+1;
+        if(tabIndex >= getTabCount()) return -1;
+        return tabIndex;
+    }
+
+    /**
+     * タブインデックス値からPeriod日付指定への変換。
+     * @param tabIndex タブインデックス
+     * @return Period日付指定
+     */
+    private int tabIndexToPeriodDays(int tabIndex){
+        if(tabIndex >= getTabCount()) return - 1;
+        int days = tabIndex - 1;
+        return days;
+    }
+
+    /**
+     * PeriodView一覧を得る。
+     * @return PeriodView の List
+     */
+    public List<PeriodView> getPeriodViewList(){
+        List<PeriodView> result = new LinkedList<>();
+
+        int tabCount = getTabCount();
+        for(int tabIndex = 0; tabIndex <= tabCount - 1; tabIndex++){
+            Component component = getComponent(tabIndex);
+            if(component == null) continue;
+            if( ! (component instanceof PeriodView) ) continue;
+            PeriodView periodView = (PeriodView) component;
+            result.add(periodView);
+        }
+
+        return result;
+    }
+
+    /**
+     * 現在タブ選択中のDiscussionを返す。
+     * Periodに関係ないタブが選択されていたらnullを返す。
+     * @return 現在選択中のDiscussion
+     */
+    public Discussion currentDiscussion(){
+        int tabIndex = getSelectedIndex();
+        Discussion result = getDiscussion(tabIndex);
+        return result;
+    }
+
+    /**
+     * 現在タブ選択中のPeriodViewを返す。
+     * Periodに関係ないタブが選択されていたらnullを返す。
+     * @return 現在選択中のPeriodView
+     */
+    public PeriodView currentPeriodView(){
+        int tabIndex = getSelectedIndex();
+        PeriodView result = getPeriodView(tabIndex);
+        return result;
+    }
+
+    /**
+     * 指定したタブインデックスに関連付けられたPeriodViewを返す。
+     * Periodに関係ないタブが指定されたらnullを返す。
+     * @param tabIndex タブインデックス
+     * @return 指定されたPeriodView
+     */
+    public PeriodView getPeriodView(int tabIndex){
+        if(tabIndexToPeriodDays(tabIndex) < 0) return null;
+        if(tabIndex >= getTabCount()) return null;
+        Component component = getComponentAt(tabIndex);
+        if(component == null) return null;
+
+        if( ! (component instanceof PeriodView) ) return null;
+        PeriodView periodView = (PeriodView) component;
+
+        return periodView;
+    }
+
+    /**
+     * 指定したタブインデックスに関連付けられたDiscussionを返す。
+     * Periodに関係ないタブが指定されたらnullを返す。
+     * @param tabIndex タブインデックス
+     * @return 指定されたDiscussion
+     */
+    private Discussion getDiscussion(int tabIndex){
+        PeriodView periodView = getPeriodView(tabIndex);
+        if(periodView == null) return null;
+
+        Discussion result = periodView.getDiscussion();
+        return result;
+    }
+
+    /**
+     * フォント描画設定を変更する。
+     * @param fontInfo フォント
+     */
+    public void setFontInfo(FontInfo fontInfo){
+        this.fontInfo = fontInfo;
+
+        for(int tabIndex = 0; tabIndex <= getTabCount() - 1; tabIndex++){
+            PeriodView periodView = getPeriodView(tabIndex);
+            if(periodView == null) continue;
+            periodView.setFontInfo(this.fontInfo);
+        }
+
+        return;
+    }
+
+    /**
+     * 発言表示設定を変更する。
+     * @param dialogPref 発言表示設定
+     */
+    public void setDialogPref(DialogPref dialogPref){
+        this.dialogPref = dialogPref;
+
+        for(int tabIndex = 0; tabIndex <= getTabCount() - 1; tabIndex++){
+            PeriodView periodView = getPeriodView(tabIndex);
+            if(periodView == null) continue;
+            periodView.setDialogPref(this.dialogPref);
+        }
+
+        return;
+    }
+
+    /**
+     * ActionListenerを追加する。
+     * @param listener リスナー
+     */
+    public void addActionListener(ActionListener listener){
+        this.thisListenerList.add(ActionListener.class, listener);
+
+        if(this.village == null) return;
+        int periodNum = this.village.getPeriodSize();
+        for(int periodDays = 0; periodDays < periodNum; periodDays++){
+            int tabIndex = periodDaysToTabIndex(periodDays);
+            Discussion discussion = getDiscussion(tabIndex);
+            if(discussion == null) continue;
+            discussion.addActionListener(listener);
+        }
+
+        return;
+    }
+
+    /**
+     * ActionListenerを削除する。
+     * @param listener リスナー
+     */
+    public void removeActionListener(ActionListener listener){
+        this.thisListenerList.remove(ActionListener.class, listener);
+
+        if(this.village == null) return;
+        int periodNum = this.village.getPeriodSize();
+        for(int periodDays = 0; periodDays < periodNum; periodDays++){
+            int tabIndex = periodDaysToTabIndex(periodDays);
+            Discussion discussion = getDiscussion(tabIndex);
+            if(discussion == null) continue;
+            discussion.removeActionListener(listener);
+        }
+
+        return;
+    }
+
+    /**
+     * ActionListenerを列挙する。
+     * @return すべてのActionListener
+     */
+    public ActionListener[] getActionListeners(){
+        return this.thisListenerList.getListeners(ActionListener.class);
+    }
+
+    /**
+     * AnchorHitListenerを追加する。
+     * @param listener リスナー
+     */
+    public void addAnchorHitListener(AnchorHitListener listener){
+        this.thisListenerList.add(AnchorHitListener.class, listener);
+
+        if(this.village == null) return;
+        int periodNum = this.village.getPeriodSize();
+        for(int periodDays = 0; periodDays < periodNum; periodDays++){
+            int tabIndex = periodDaysToTabIndex(periodDays);
+            Discussion discussion = getDiscussion(tabIndex);
+            if(discussion == null) continue;
+            discussion.addAnchorHitListener(listener);
+        }
+
+        return;
+    }
+
+    /**
+     * AnchorHitListenerを削除する。
+     * @param listener リスナー
+     */
+    public void removeAnchorHitListener(AnchorHitListener listener){
+        this.thisListenerList.remove(AnchorHitListener.class, listener);
+
+        if(this.village == null) return;
+        int periodNum = this.village.getPeriodSize();
+        for(int periodDays = 0; periodDays < periodNum; periodDays++){
+            int tabIndex = periodDaysToTabIndex(periodDays);
+            Discussion discussion = getDiscussion(tabIndex);
+            if(discussion == null) continue;
+            discussion.removeAnchorHitListener(listener);
+        }
+
+        return;
+    }
+
+    /**
+     * AnchorHitListenerを列挙する。
+     * @return すべてのAnchorHitListener
+     */
+    public AnchorHitListener[] getAnchorHitListeners(){
+        return this.thisListenerList.getListeners(AnchorHitListener.class);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @param <T> {@inheritDoc}
+     * @param listenerType {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public <T extends EventListener> T[] getListeners(Class<T> listenerType){
+        T[] result;
+        result = this.thisListenerList.getListeners(listenerType);
+
+        if(result.length <= 0){
+            result = super.getListeners(listenerType);
+        }
+
+        return result;
+    }
+
+}