OSDN Git Service

Merge commit '2458eff3aea04f67893bc824b5cf896fbb767332'
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / PeriodView.java
diff --git a/src/main/java/jp/sourceforge/jindolf/PeriodView.java b/src/main/java/jp/sourceforge/jindolf/PeriodView.java
new file mode 100644 (file)
index 0000000..6ea1e80
--- /dev/null
@@ -0,0 +1,381 @@
+/*\r
+ * period viewer\r
+ *\r
+ * Copyright(c) 2008 olyutorskii\r
+ * $Id: PeriodView.java 972 2009-12-26 05:05:15Z olyutorskii $\r
+ */\r
+\r
+package jp.sourceforge.jindolf;\r
+\r
+import java.awt.BorderLayout;\r
+import java.awt.Color;\r
+import java.awt.Component;\r
+import java.awt.GridBagConstraints;\r
+import java.awt.GridBagLayout;\r
+import java.awt.Insets;\r
+import java.awt.LayoutManager;\r
+import java.awt.Rectangle;\r
+import java.awt.event.ItemEvent;\r
+import java.awt.event.ItemListener;\r
+import java.util.List;\r
+import javax.swing.BorderFactory;\r
+import javax.swing.DefaultComboBoxModel;\r
+import javax.swing.DefaultListCellRenderer;\r
+import javax.swing.JComboBox;\r
+import javax.swing.JLabel;\r
+import javax.swing.JList;\r
+import javax.swing.JPanel;\r
+import javax.swing.JScrollBar;\r
+import javax.swing.JScrollPane;\r
+import javax.swing.JViewport;\r
+import javax.swing.ScrollPaneConstants;\r
+import javax.swing.border.Border;\r
+import jp.sourceforge.jindolf.corelib.TalkType;\r
+\r
+/**\r
+ * 発言ブラウザを内包するPeriodビューワ。\r
+ */\r
+@SuppressWarnings("serial")\r
+public class PeriodView extends JPanel implements ItemListener{\r
+\r
+    private static final Color COLOR_SELECT = new Color(0xffff80);\r
+    private static final Color COLOR_NORMALBG = Color.BLACK;\r
+    private static final Color COLOR_SIMPLEBG = Color.WHITE;\r
+\r
+    private Period period;\r
+\r
+    private final Discussion discussion;\r
+    private final JScrollPane scroller = new JScrollPane();\r
+    private final JLabel caption = new JLabel();\r
+    private final JLabel limit = new JLabel();\r
+    private final JComboBox talkSelector = new JComboBox();\r
+    private final DefaultComboBoxModel model = new DefaultComboBoxModel();\r
+\r
+    private DialogPref dialogPref = new DialogPref();\r
+\r
+    /**\r
+     * 発言ブラウザを内包するPeriodビューワを生成する。\r
+     * @param period 日\r
+     */\r
+    public PeriodView(Period period){\r
+        super();\r
+\r
+        this.period = period;\r
+\r
+        this.talkSelector.setEditable(false);\r
+        this.talkSelector.setMaximumRowCount(20);\r
+        this.talkSelector.setModel(this.model);\r
+        this.talkSelector.setRenderer(new AnchorRenderer());\r
+        this.talkSelector.addItemListener(this);\r
+\r
+        this.discussion = new Discussion();\r
+        Border border =\r
+                BorderFactory.createMatteBorder(15, 15, 15, 15, Color.BLACK);\r
+        this.discussion.setBorder(border);\r
+        this.discussion.setPeriod(this.period);\r
+\r
+        JViewport viewPort = this.scroller.getViewport();\r
+        viewPort.setBackground(Color.BLACK);\r
+        viewPort.setView(this.discussion);\r
+\r
+        this.scroller.setHorizontalScrollBarPolicy(\r
+                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);\r
+        this.scroller.setVerticalScrollBarPolicy(\r
+                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);\r
+\r
+        design();\r
+\r
+        setColorDesign();\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * デザインを行う。\r
+     */\r
+    private void design(){\r
+        LayoutManager layout;\r
+\r
+        JPanel topPanel = new JPanel();\r
+        layout = new GridBagLayout();\r
+        GridBagConstraints constraints = new GridBagConstraints();\r
+        topPanel.setLayout(layout);\r
+        constraints.insets = new Insets(1, 3, 1, 3);\r
+        constraints.weightx = 1.0;\r
+        constraints.anchor = GridBagConstraints.WEST;\r
+        constraints.fill = GridBagConstraints.NONE;\r
+        topPanel.add(this.caption, constraints);\r
+        constraints.weightx = 0.0;\r
+        constraints.anchor = GridBagConstraints.EAST;\r
+        topPanel.add(this.limit, constraints);\r
+        constraints.weightx = 0.0;\r
+        topPanel.add(this.talkSelector, constraints);\r
+\r
+        layout = new BorderLayout();\r
+        setLayout(layout);\r
+        add(topPanel,      BorderLayout.NORTH);\r
+        add(this.scroller, BorderLayout.CENTER);\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * 配色を設定する。\r
+     */\r
+    private void setColorDesign(){\r
+        Color bgColor;\r
+\r
+        if(this.dialogPref.isSimpleMode()){\r
+            bgColor = COLOR_SIMPLEBG;\r
+        }else{\r
+            bgColor = COLOR_NORMALBG;\r
+        }\r
+\r
+        JViewport viewPort = this.scroller.getViewport();\r
+        viewPort.setBackground(bgColor);\r
+\r
+        Border border =\r
+                BorderFactory.createMatteBorder(15, 15, 15, 15, bgColor);\r
+        this.discussion.setBorder(border);\r
+\r
+        repaint();\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * Periodを更新する。\r
+     * 古いPeriodの表示内容は消える。\r
+     * 新しいPeriodの表示内容はまだ反映されない。\r
+     * @param period 新しいPeriod\r
+     */\r
+    public void setPeriod(Period period){\r
+        this.discussion.setPeriod(period);\r
+\r
+        this.period = period;\r
+\r
+        updateTopPanel();\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * 現在のPeriodを返す。\r
+     * @return 現在のPeriod\r
+     */\r
+    public Period getPeriod(){\r
+        return this.discussion.getPeriod();\r
+    }\r
+\r
+    /**\r
+     * 上部のGUI(村名、発言一覧)を、Periodの状態に合わせて更新する。\r
+     */\r
+    private void updateTopPanel(){\r
+        if(this.period == null){\r
+            this.caption.setText("");\r
+            this.limit.setText("");\r
+            this.model.removeAllElements();\r
+            return;\r
+        }\r
+\r
+        Village village = this.period.getVillage();\r
+        String villageName = village.getVillageName();\r
+\r
+        String dayCaption   = this.period.getCaption();\r
+        String limitCaption = this.period.getLimit();\r
+        String account      = this.period.getLoginName();\r
+\r
+        String loginout;\r
+        if(this.period.isFullOpen()){\r
+            loginout = "";\r
+        }else if(account != null){\r
+            loginout = " (ログイン中)";\r
+        }else{\r
+            loginout = " (ログアウト中)";\r
+        }\r
+\r
+        String info = villageName + "村 " + dayCaption + loginout;\r
+        this.caption.setText(info);\r
+        this.limit.setText("更新時刻 " + limitCaption);\r
+\r
+        this.model.removeAllElements();\r
+        this.model.addElement(" ");\r
+        List<Topic> topicList = this.period.getTopicList();\r
+        for(Topic topic : topicList){\r
+            if( ! (topic instanceof Talk) ) continue;\r
+            Talk talk = (Talk) topic;\r
+            if(talk.getTalkCount() <= 0) continue;\r
+            this.model.addElement(talk);\r
+        }\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * フィルタを適用してPeriodの内容を出力する。\r
+     */\r
+    public void showTopics(){\r
+        Period newPeriod = this.discussion.getPeriod();\r
+        setPeriod(newPeriod);\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * フォント描画設定を変更する。\r
+     * @param fontInfo フォント設定\r
+     */\r
+    // TODO スクロール位置の復元\r
+    public void setFontInfo(FontInfo fontInfo){\r
+        this.discussion.setFontInfo(fontInfo);\r
+\r
+        revalidate();\r
+        repaint();\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * 発言表示設定を更新する。\r
+     * @param pref 表示設定\r
+     */\r
+    public void setDialogPref(DialogPref pref){\r
+        this.dialogPref = pref;\r
+        this.discussion.setDialogPref(this.dialogPref);\r
+\r
+        setColorDesign();\r
+        revalidate();\r
+        repaint();\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * ビューポート内の発言ブラウザを返す。\r
+     * @return 内部ブラウザ\r
+     */\r
+    public Discussion getDiscussion(){\r
+        return this.discussion;\r
+    }\r
+\r
+    /**\r
+     * スクロール位置を返す。\r
+     * @return スクロール位置\r
+     */\r
+    public int getVerticalPosition(){\r
+        JScrollBar vt = this.scroller.getVerticalScrollBar();\r
+        int pos = vt.getValue();\r
+        return pos;\r
+    }\r
+\r
+    /**\r
+     * スクロール位置を設定する。\r
+     * @param pos スクロール位置\r
+     */\r
+    public void setVerticalPosition(int pos){\r
+        JScrollBar vt = this.scroller.getVerticalScrollBar();\r
+        vt.setValue(pos);\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     * コンボボックス操作のリスナ。\r
+     * @param event コンボボックス操作イベント {@inheritDoc}\r
+     */\r
+    public void itemStateChanged(ItemEvent event){\r
+        if(event.getStateChange() != ItemEvent.SELECTED) return;\r
+\r
+        Object selected = this.talkSelector.getSelectedItem();\r
+        if( ! (selected instanceof Talk) ) return;\r
+        Talk talk = (Talk) selected;\r
+\r
+        scrollToTalk(talk);\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * 任意の発言が表示されるようスクロールする。\r
+     * @param talk 発言\r
+     */\r
+    public void scrollToTalk(Talk talk){\r
+        if(talk == null) return;\r
+        if(talk.getPeriod() != this.period) return;\r
+\r
+        Rectangle rect = this.discussion.getTalkBounds(talk);\r
+        if(rect == null) return;\r
+\r
+        Rectangle showRect = new Rectangle(rect);\r
+        showRect.y -= 15;\r
+        showRect.height = this.scroller.getHeight();\r
+        this.discussion.scrollRectToVisible(showRect);\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * Talkをアイテムに持つコンボボックス用のセル描画。\r
+     */\r
+    private static class AnchorRenderer extends DefaultListCellRenderer{\r
+\r
+        /**\r
+         * コンストラクタ。\r
+         */\r
+        public AnchorRenderer(){\r
+            super();\r
+            return;\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         * Talkのアンカー表記と発言者名を描画する。\r
+         * @param list {@inheritDoc}\r
+         * @param value {@inheritDoc}\r
+         * @param index {@inheritDoc}\r
+         * @param isSelected {@inheritDoc}\r
+         * @param cellHasFocus {@inheritDoc}\r
+         * @return {@inheritDoc}\r
+         */\r
+        @Override\r
+        public Component getListCellRendererComponent(\r
+                JList list,\r
+                Object value,\r
+                int index,\r
+                boolean isSelected,\r
+                boolean cellHasFocus ){\r
+            Talk talk = null;\r
+            Object newValue = value;\r
+            if(value instanceof Talk){\r
+                talk = (Talk) value;\r
+                newValue = new StringBuilder()\r
+                          .append(talk.getAnchorNotation())\r
+                          .append(' ')\r
+                          .append(talk.getAvatar().getName())\r
+                          .toString();\r
+            }\r
+\r
+            Component superResult =\r
+                    super.getListCellRendererComponent(list,\r
+                                                       newValue,\r
+                                                       index,\r
+                                                       isSelected,\r
+                                                       cellHasFocus);\r
+\r
+            if(talk != null){\r
+                Color bgColor = null;\r
+                if(isSelected){\r
+                    bgColor = COLOR_SELECT;\r
+                }else{\r
+                    TalkType type = talk.getTalkType();\r
+                    bgColor = TalkDraw.getTypedColor(type);\r
+                }\r
+                superResult.setForeground(Color.BLACK);\r
+                superResult.setBackground(bgColor);\r
+            }\r
+\r
+            return superResult;\r
+        }\r
+    }\r
+\r
+    // TODO フィルタ中の発言をプルダウン選択したらどうあるべきか?\r
+}\r