-/*\r
- * summary of day panel\r
- *\r
- * License : The MIT License\r
- * Copyright(c) 2008 olyutorskii\r
- */\r
-\r
-package jp.sourceforge.jindolf;\r
-\r
-import java.awt.Color;\r
-import java.awt.Component;\r
-import java.awt.Container;\r
-import java.awt.Dimension;\r
-import java.awt.Frame;\r
-import java.awt.GridBagConstraints;\r
-import java.awt.GridBagLayout;\r
-import java.awt.Image;\r
-import java.awt.Insets;\r
-import java.awt.LayoutManager;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.ItemEvent;\r
-import java.awt.event.ItemListener;\r
-import java.awt.event.WindowEvent;\r
-import java.awt.event.WindowListener;\r
-import java.text.NumberFormat;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.SortedSet;\r
-import java.util.TreeSet;\r
-import javax.swing.ImageIcon;\r
-import javax.swing.JButton;\r
-import javax.swing.JComboBox;\r
-import javax.swing.JDialog;\r
-import javax.swing.JLabel;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JSeparator;\r
-import javax.swing.JTable;\r
-import javax.swing.ListSelectionModel;\r
-import javax.swing.SwingConstants;\r
-import javax.swing.table.DefaultTableCellRenderer;\r
-import javax.swing.table.DefaultTableModel;\r
-import javax.swing.table.TableColumn;\r
-import javax.swing.table.TableColumnModel;\r
-import jp.sourceforge.jindolf.corelib.TalkType;\r
-\r
-/**\r
- * その日ごとの集計。\r
- */\r
-@SuppressWarnings("serial")\r
-public class DaySummary extends JDialog\r
- implements WindowListener, ActionListener, ItemListener{\r
-\r
- private static final String FRAMETITLE =\r
- "発言集計 - " + Jindolf.TITLE;\r
- private static final NumberFormat AVERAGE_FORM;\r
- private static final String PUBTALK = "白発言";\r
- private static final String WOLFTALK = "赤発言";\r
- private static final String GRAVETALK = "青発言";\r
- private static final String PRVTALK = "灰発言";\r
- private static final String ALLTALK = "全発言";\r
- private static final int HORIZONTAL_GAP = 5;\r
- private static final int VERTICAL_GAP = 1;\r
- private static final Color COLOR_ALL = new Color(0xffff80);\r
-\r
- static{\r
- AVERAGE_FORM = NumberFormat.getInstance();\r
- AVERAGE_FORM.setMaximumFractionDigits(1);\r
- AVERAGE_FORM.setMinimumFractionDigits(1);\r
- }\r
-\r
-\r
- private final DefaultTableModel tableModel;\r
- private final TableColumn avatarColumn;\r
-\r
- private final JTable tableComp;\r
- private final JComboBox typeSelector = new JComboBox();\r
- private final JButton closeButton = new JButton("閉じる");\r
- private final JLabel caption = new JLabel();\r
- private final JLabel totalSum = new JLabel();\r
-\r
- private TalkType talkFilter;\r
- private Period period;\r
-\r
-\r
- /**\r
- * コンストラクタ。\r
- * 集計結果を表示するモーダルダイアログを生成する。\r
- * @param owner オーナー\r
- */\r
- public DaySummary(Frame owner){\r
- super(owner, FRAMETITLE, true);\r
-\r
- GUIUtils.modifyWindowAttributes(this, true, false, true);\r
-\r
- setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);\r
- addWindowListener(this);\r
-\r
- this.tableModel = createInitModel();\r
- this.tableComp = new JTable();\r
- this.tableComp.setModel(this.tableModel);\r
- this.tableComp.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
- this.tableComp.setIntercellSpacing(\r
- new Dimension(HORIZONTAL_GAP, VERTICAL_GAP) );\r
- this.tableComp.setDefaultEditor(Object.class, null);\r
- this.tableComp.setDefaultRenderer(Object.class, new CustomRenderer());\r
- this.tableComp.setShowGrid(true);\r
-\r
- TableColumnModel tcolModel = this.tableComp.getColumnModel();\r
-\r
- this.avatarColumn = tcolModel.getColumn(0);\r
-\r
- DefaultTableCellRenderer renderer;\r
-\r
- renderer = new DefaultTableCellRenderer();\r
- renderer.setHorizontalAlignment(SwingConstants.RIGHT);\r
- tcolModel.getColumn(1).setCellRenderer(renderer);\r
-\r
- renderer = new DefaultTableCellRenderer();\r
- renderer.setHorizontalAlignment(SwingConstants.RIGHT);\r
- tcolModel.getColumn(2).setCellRenderer(renderer);\r
-\r
- renderer = new DefaultTableCellRenderer();\r
- renderer.setHorizontalAlignment(SwingConstants.RIGHT);\r
- tcolModel.getColumn(3).setCellRenderer(renderer);\r
-\r
- this.typeSelector.addItem(PUBTALK);\r
- this.typeSelector.addItem(WOLFTALK);\r
- this.typeSelector.addItem(GRAVETALK);\r
- this.typeSelector.addItem(PRVTALK);\r
- this.typeSelector.addItem(ALLTALK);\r
-\r
- this.closeButton.addActionListener(this);\r
- this.typeSelector.addItemListener(this);\r
-\r
- this.typeSelector.setSelectedItem(null);\r
- this.typeSelector.setSelectedItem(PUBTALK);\r
-\r
- design();\r
-\r
- clearModel();\r
-\r
- return;\r
- }\r
-\r
-\r
- /**\r
- * 初期のデータモデルを生成する。\r
- * @return データモデル\r
- */\r
- private static DefaultTableModel createInitModel(){\r
- DefaultTableModel result;\r
- result = new DefaultTableModel();\r
-\r
- Object[] rowHeads = {"名前", "発言回数", "平均文字列長", "最終発言"};\r
- result.setColumnCount(rowHeads.length);\r
- result.setColumnIdentifiers(rowHeads);\r
-\r
- return result;\r
- }\r
-\r
-\r
- /**\r
- * テーブルをクリアする。\r
- */\r
- private void clearModel(){\r
- int rows = this.tableModel.getRowCount();\r
- for(int ct = 1; ct <= rows; ct++){\r
- this.tableModel.removeRow(0);\r
- }\r
- }\r
-\r
- /**\r
- * 行を追加する。\r
- * @param avatar アバター\r
- * @param talkCount 発言回数\r
- * @param totalChars 発言文字総数\r
- * @param lastTime 最終発言時刻\r
- */\r
- private void appendRow(Avatar avatar,\r
- Integer talkCount,\r
- Integer totalChars,\r
- String lastTime ){\r
- String talks = talkCount + " 回";\r
-\r
- double average;\r
- if(talkCount <= 0) average = 0.0;\r
- else average = (double)totalChars / (double)talkCount;\r
- String chars = AVERAGE_FORM.format(average) + " 文字";\r
-\r
- Object[] row = {avatar, talks, chars, lastTime};\r
- int rowIndex = this.tableModel.getRowCount();\r
-\r
- this.tableModel.insertRow(rowIndex, row);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * デザインを行う。\r
- */\r
- private void design(){\r
- Container content = getContentPane();\r
-\r
- LayoutManager layout = new GridBagLayout();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
- content.setLayout(layout);\r
-\r
- constraints.insets = new Insets(5, 5, 5, 5);\r
-\r
- constraints.gridwidth = 1;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.WEST;\r
- content.add(this.caption, constraints);\r
-\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.fill = GridBagConstraints.NONE;\r
- content.add(this.typeSelector, constraints);\r
-\r
- JScrollPane scroller = new JScrollPane(this.tableComp);\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- content.add(scroller, constraints);\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.WEST;\r
- content.add(this.totalSum, constraints);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- content.add(new JSeparator(), constraints);\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.EAST;\r
- content.add(this.closeButton, constraints);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 与えられたPeriodで集計を更新する。\r
- * @param newPeriod 日\r
- */\r
- public void summaryPeriod(Period newPeriod){\r
- this.period = newPeriod;\r
- summaryPeriod();\r
- }\r
-\r
- /**\r
- * 集計を更新する。\r
- */\r
- private void summaryPeriod(){\r
- clearModel();\r
-\r
- if(this.period == null) return;\r
-\r
- SortedSet<Avatar> avatarSet = new TreeSet<Avatar>();\r
- Map<Avatar, Integer> talkCount = new HashMap<Avatar, Integer>();\r
- Map<Avatar, Integer> totalChars = new HashMap<Avatar, Integer>();\r
- Map<Avatar, Talk> lastTalk = new HashMap<Avatar, Talk>();\r
-\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
- if( this.talkFilter != null\r
- && talk.getTalkType() != this.talkFilter) continue;\r
-\r
- Avatar avatar = talk.getAvatar();\r
-\r
- Integer counts = talkCount.get(avatar);\r
- if(counts == null) counts = Integer.valueOf(0);\r
- counts++;\r
- talkCount.put(avatar, counts);\r
-\r
- Integer total = totalChars.get(avatar);\r
- if(total == null) total = Integer.valueOf(0);\r
- total += talk.getTotalChars();\r
- totalChars.put(avatar, total);\r
-\r
- lastTalk.put(avatar, talk);\r
-\r
- avatarSet.add(avatar);\r
- }\r
-\r
- int sum = 0;\r
- for(Avatar avatar : avatarSet){\r
- Integer counts = talkCount.get(avatar);\r
- Integer total = totalChars.get(avatar);\r
- String lastTime = lastTalk.get(avatar).getAnchorNotation();\r
- appendRow(avatar, counts, total, lastTime);\r
- sum += counts;\r
- }\r
-\r
- this.totalSum.setText("合計:" + sum + " 発言");\r
-\r
- Village village = this.period.getVillage();\r
- String villageName = village.getVillageName();\r
- String periodCaption = this.period.getCaption();\r
- this.caption.setText(villageName + "村 " + periodCaption);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowActivated(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowDeactivated(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowIconified(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowDeiconified(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowOpened(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * ダイアログのクローズボタン押下処理を行う。\r
- * @param event ウィンドウ変化イベント {@inheritDoc}\r
- */\r
- @Override\r
- public void windowClosing(WindowEvent event){\r
- close();\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * @param event {@inheritDoc}\r
- */\r
- @Override\r
- public void windowClosed(WindowEvent event){\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * クローズボタン押下処理。\r
- * @param event イベント {@inheritDoc}\r
- */\r
- @Override\r
- public void actionPerformed(ActionEvent event){\r
- if(event.getSource() != this.closeButton) return;\r
- close();\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * コンボボックス操作処理。\r
- * @param event イベント {@inheritDoc}\r
- */\r
- @Override\r
- public void itemStateChanged(ItemEvent event){\r
- if(event.getStateChange() != ItemEvent.SELECTED) return;\r
-\r
- Object selected = this.typeSelector.getSelectedItem();\r
- if (selected == PUBTALK) this.talkFilter = TalkType.PUBLIC;\r
- else if(selected == WOLFTALK) this.talkFilter = TalkType.WOLFONLY;\r
- else if(selected == GRAVETALK) this.talkFilter = TalkType.GRAVE;\r
- else if(selected == PRVTALK) this.talkFilter = TalkType.PRIVATE;\r
- else if(selected == ALLTALK) this.talkFilter = null;\r
-\r
- summaryPeriod();\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * このパネルを閉じる。\r
- */\r
- private void close(){\r
- clearModel();\r
- this.period = null;\r
- setVisible(false);\r
- return;\r
- }\r
-\r
- /**\r
- * Avatar 顔イメージ描画用カスタムセルレンダラ。\r
- */\r
- private class CustomRenderer extends DefaultTableCellRenderer{\r
-\r
- /**\r
- * コンストラクタ。\r
- */\r
- public CustomRenderer(){\r
- super();\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * セルに{@link Avatar}がきたら顔アイコンと名前を表示する。\r
- * @param value {@inheritDoc}\r
- */\r
- @Override\r
- public void setValue(Object value){\r
- if(value instanceof Avatar){\r
- Avatar avatar = (Avatar) value;\r
-\r
- Village village = DaySummary.this.period.getVillage();\r
- Image image = village.getAvatarFaceImage(avatar);\r
- if(image == null) image = village.getGraveImage();\r
- if(image != null){\r
- ImageIcon icon = new ImageIcon(image);\r
- setIcon(icon);\r
- }\r
-\r
- setText(avatar.getName());\r
-\r
- Dimension prefSize = getPreferredSize();\r
-\r
- int cellHeight = VERTICAL_GAP * 2 + prefSize.height;\r
- if(DaySummary.this.tableComp.getRowHeight() < cellHeight){\r
- DaySummary.this.tableComp.setRowHeight(cellHeight);\r
- }\r
-\r
- int cellWidth = HORIZONTAL_GAP * 2 + prefSize.width;\r
- if( DaySummary.this.avatarColumn.getPreferredWidth()\r
- < cellWidth ){\r
- DaySummary.this.avatarColumn.setPreferredWidth(cellWidth);\r
- }\r
-\r
- return;\r
- }\r
-\r
- super.setValue(value);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * {@inheritDoc}\r
- * 統計種別によってセル色を変える。\r
- * @param table {@inheritDoc}\r
- * @param value {@inheritDoc}\r
- * @param isSelected {@inheritDoc}\r
- * @param hasFocus {@inheritDoc}\r
- * @param row {@inheritDoc}\r
- * @param column {@inheritDoc}\r
- * @return {@inheritDoc}\r
- */\r
- @Override\r
- public Component getTableCellRendererComponent(JTable table,\r
- Object value,\r
- boolean isSelected,\r
- boolean hasFocus,\r
- int row,\r
- int column ){\r
- Component result = super.getTableCellRendererComponent(table,\r
- value,\r
- isSelected,\r
- hasFocus,\r
- row,\r
- column );\r
-\r
- Object selected = DaySummary.this.typeSelector.getSelectedItem();\r
- Color bgColor = null;\r
- if(selected == PUBTALK){\r
- bgColor = TalkDraw.COLOR_PUBLIC;\r
- }else if(selected == WOLFTALK){\r
- bgColor = TalkDraw.COLOR_WOLFONLY;\r
- }else if(selected == GRAVETALK){\r
- bgColor = TalkDraw.COLOR_GRAVE;\r
- }else if(selected == PRVTALK){\r
- bgColor = TalkDraw.COLOR_PRIVATE;\r
- }else if(selected == ALLTALK){\r
- bgColor = COLOR_ALL;\r
- }else{\r
- assert false;\r
- return null;\r
- }\r
-\r
- result.setForeground(Color.BLACK);\r
- result.setBackground(bgColor);\r
-\r
- return result;\r
- }\r
- }\r
-\r
-}\r
+/*
+ * summary of day panel
+ *
+ * License : The MIT License
+ * Copyright(c) 2008 olyutorskii
+ */
+
+package jp.sourceforge.jindolf;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.text.NumberFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import jp.sourceforge.jindolf.corelib.TalkType;
+
+/**
+ * その日ごとの集計。
+ */
+@SuppressWarnings("serial")
+public class DaySummary extends JDialog
+ implements WindowListener, ActionListener, ItemListener{
+
+ private static final String FRAMETITLE =
+ "発言集計 - " + Jindolf.TITLE;
+ private static final NumberFormat AVERAGE_FORM;
+ private static final String PUBTALK = "白発言";
+ private static final String WOLFTALK = "赤発言";
+ private static final String GRAVETALK = "青発言";
+ private static final String PRVTALK = "灰発言";
+ private static final String ALLTALK = "全発言";
+ private static final int HORIZONTAL_GAP = 5;
+ private static final int VERTICAL_GAP = 1;
+ private static final Color COLOR_ALL = new Color(0xffff80);
+
+ static{
+ AVERAGE_FORM = NumberFormat.getInstance();
+ AVERAGE_FORM.setMaximumFractionDigits(1);
+ AVERAGE_FORM.setMinimumFractionDigits(1);
+ }
+
+
+ private final DefaultTableModel tableModel;
+ private final TableColumn avatarColumn;
+
+ private final JTable tableComp;
+ private final JComboBox typeSelector = new JComboBox();
+ private final JButton closeButton = new JButton("閉じる");
+ private final JLabel caption = new JLabel();
+ private final JLabel totalSum = new JLabel();
+
+ private TalkType talkFilter;
+ private Period period;
+
+
+ /**
+ * コンストラクタ。
+ * 集計結果を表示するモーダルダイアログを生成する。
+ * @param owner オーナー
+ */
+ public DaySummary(Frame owner){
+ super(owner, FRAMETITLE, true);
+
+ GUIUtils.modifyWindowAttributes(this, true, false, true);
+
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ addWindowListener(this);
+
+ this.tableModel = createInitModel();
+ this.tableComp = new JTable();
+ this.tableComp.setModel(this.tableModel);
+ this.tableComp.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ this.tableComp.setIntercellSpacing(
+ new Dimension(HORIZONTAL_GAP, VERTICAL_GAP) );
+ this.tableComp.setDefaultEditor(Object.class, null);
+ this.tableComp.setDefaultRenderer(Object.class, new CustomRenderer());
+ this.tableComp.setShowGrid(true);
+
+ TableColumnModel tcolModel = this.tableComp.getColumnModel();
+
+ this.avatarColumn = tcolModel.getColumn(0);
+
+ DefaultTableCellRenderer renderer;
+
+ renderer = new DefaultTableCellRenderer();
+ renderer.setHorizontalAlignment(SwingConstants.RIGHT);
+ tcolModel.getColumn(1).setCellRenderer(renderer);
+
+ renderer = new DefaultTableCellRenderer();
+ renderer.setHorizontalAlignment(SwingConstants.RIGHT);
+ tcolModel.getColumn(2).setCellRenderer(renderer);
+
+ renderer = new DefaultTableCellRenderer();
+ renderer.setHorizontalAlignment(SwingConstants.RIGHT);
+ tcolModel.getColumn(3).setCellRenderer(renderer);
+
+ this.typeSelector.addItem(PUBTALK);
+ this.typeSelector.addItem(WOLFTALK);
+ this.typeSelector.addItem(GRAVETALK);
+ this.typeSelector.addItem(PRVTALK);
+ this.typeSelector.addItem(ALLTALK);
+
+ this.closeButton.addActionListener(this);
+ this.typeSelector.addItemListener(this);
+
+ this.typeSelector.setSelectedItem(null);
+ this.typeSelector.setSelectedItem(PUBTALK);
+
+ design();
+
+ clearModel();
+
+ return;
+ }
+
+
+ /**
+ * 初期のデータモデルを生成する。
+ * @return データモデル
+ */
+ private static DefaultTableModel createInitModel(){
+ DefaultTableModel result;
+ result = new DefaultTableModel();
+
+ Object[] rowHeads = {"名前", "発言回数", "平均文字列長", "最終発言"};
+ result.setColumnCount(rowHeads.length);
+ result.setColumnIdentifiers(rowHeads);
+
+ return result;
+ }
+
+
+ /**
+ * テーブルをクリアする。
+ */
+ private void clearModel(){
+ int rows = this.tableModel.getRowCount();
+ for(int ct = 1; ct <= rows; ct++){
+ this.tableModel.removeRow(0);
+ }
+ }
+
+ /**
+ * 行を追加する。
+ * @param avatar アバター
+ * @param talkCount 発言回数
+ * @param totalChars 発言文字総数
+ * @param lastTime 最終発言時刻
+ */
+ private void appendRow(Avatar avatar,
+ Integer talkCount,
+ Integer totalChars,
+ String lastTime ){
+ String talks = talkCount + " 回";
+
+ double average;
+ if(talkCount <= 0) average = 0.0;
+ else average = (double)totalChars / (double)talkCount;
+ String chars = AVERAGE_FORM.format(average) + " 文字";
+
+ Object[] row = {avatar, talks, chars, lastTime};
+ int rowIndex = this.tableModel.getRowCount();
+
+ this.tableModel.insertRow(rowIndex, row);
+
+ return;
+ }
+
+ /**
+ * デザインを行う。
+ */
+ private void design(){
+ Container content = getContentPane();
+
+ LayoutManager layout = new GridBagLayout();
+ GridBagConstraints constraints = new GridBagConstraints();
+ content.setLayout(layout);
+
+ constraints.insets = new Insets(5, 5, 5, 5);
+
+ constraints.gridwidth = 1;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.WEST;
+ content.add(this.caption, constraints);
+
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.fill = GridBagConstraints.NONE;
+ content.add(this.typeSelector, constraints);
+
+ JScrollPane scroller = new JScrollPane(this.tableComp);
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ content.add(scroller, constraints);
+
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.WEST;
+ content.add(this.totalSum, constraints);
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ content.add(new JSeparator(), constraints);
+
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.EAST;
+ content.add(this.closeButton, constraints);
+
+ return;
+ }
+
+ /**
+ * 与えられたPeriodで集計を更新する。
+ * @param newPeriod 日
+ */
+ public void summaryPeriod(Period newPeriod){
+ this.period = newPeriod;
+ summaryPeriod();
+ }
+
+ /**
+ * 集計を更新する。
+ */
+ private void summaryPeriod(){
+ clearModel();
+
+ if(this.period == null) return;
+
+ SortedSet<Avatar> avatarSet = new TreeSet<Avatar>();
+ Map<Avatar, Integer> talkCount = new HashMap<Avatar, Integer>();
+ Map<Avatar, Integer> totalChars = new HashMap<Avatar, Integer>();
+ Map<Avatar, Talk> lastTalk = new HashMap<Avatar, Talk>();
+
+ List<Topic> topicList = this.period.getTopicList();
+ for(Topic topic : topicList){
+ if( ! (topic instanceof Talk)) continue;
+ Talk talk = (Talk) topic;
+ if(talk.getTalkCount() <= 0) continue;
+ if( this.talkFilter != null
+ && talk.getTalkType() != this.talkFilter) continue;
+
+ Avatar avatar = talk.getAvatar();
+
+ Integer counts = talkCount.get(avatar);
+ if(counts == null) counts = Integer.valueOf(0);
+ counts++;
+ talkCount.put(avatar, counts);
+
+ Integer total = totalChars.get(avatar);
+ if(total == null) total = Integer.valueOf(0);
+ total += talk.getTotalChars();
+ totalChars.put(avatar, total);
+
+ lastTalk.put(avatar, talk);
+
+ avatarSet.add(avatar);
+ }
+
+ int sum = 0;
+ for(Avatar avatar : avatarSet){
+ Integer counts = talkCount.get(avatar);
+ Integer total = totalChars.get(avatar);
+ String lastTime = lastTalk.get(avatar).getAnchorNotation();
+ appendRow(avatar, counts, total, lastTime);
+ sum += counts;
+ }
+
+ this.totalSum.setText("合計:" + sum + " 発言");
+
+ Village village = this.period.getVillage();
+ String villageName = village.getVillageName();
+ String periodCaption = this.period.getCaption();
+ this.caption.setText(villageName + "村 " + periodCaption);
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowActivated(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowDeactivated(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowIconified(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowDeiconified(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowOpened(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ダイアログのクローズボタン押下処理を行う。
+ * @param event ウィンドウ変化イベント {@inheritDoc}
+ */
+ @Override
+ public void windowClosing(WindowEvent event){
+ close();
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @param event {@inheritDoc}
+ */
+ @Override
+ public void windowClosed(WindowEvent event){
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * クローズボタン押下処理。
+ * @param event イベント {@inheritDoc}
+ */
+ @Override
+ public void actionPerformed(ActionEvent event){
+ if(event.getSource() != this.closeButton) return;
+ close();
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * コンボボックス操作処理。
+ * @param event イベント {@inheritDoc}
+ */
+ @Override
+ public void itemStateChanged(ItemEvent event){
+ if(event.getStateChange() != ItemEvent.SELECTED) return;
+
+ Object selected = this.typeSelector.getSelectedItem();
+ if (selected == PUBTALK) this.talkFilter = TalkType.PUBLIC;
+ else if(selected == WOLFTALK) this.talkFilter = TalkType.WOLFONLY;
+ else if(selected == GRAVETALK) this.talkFilter = TalkType.GRAVE;
+ else if(selected == PRVTALK) this.talkFilter = TalkType.PRIVATE;
+ else if(selected == ALLTALK) this.talkFilter = null;
+
+ summaryPeriod();
+
+ return;
+ }
+
+ /**
+ * このパネルを閉じる。
+ */
+ private void close(){
+ clearModel();
+ this.period = null;
+ setVisible(false);
+ return;
+ }
+
+ /**
+ * Avatar 顔イメージ描画用カスタムセルレンダラ。
+ */
+ private class CustomRenderer extends DefaultTableCellRenderer{
+
+ /**
+ * コンストラクタ。
+ */
+ public CustomRenderer(){
+ super();
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * セルに{@link Avatar}がきたら顔アイコンと名前を表示する。
+ * @param value {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object value){
+ if(value instanceof Avatar){
+ Avatar avatar = (Avatar) value;
+
+ Village village = DaySummary.this.period.getVillage();
+ Image image = village.getAvatarFaceImage(avatar);
+ if(image == null) image = village.getGraveImage();
+ if(image != null){
+ ImageIcon icon = new ImageIcon(image);
+ setIcon(icon);
+ }
+
+ setText(avatar.getName());
+
+ Dimension prefSize = getPreferredSize();
+
+ int cellHeight = VERTICAL_GAP * 2 + prefSize.height;
+ if(DaySummary.this.tableComp.getRowHeight() < cellHeight){
+ DaySummary.this.tableComp.setRowHeight(cellHeight);
+ }
+
+ int cellWidth = HORIZONTAL_GAP * 2 + prefSize.width;
+ if( DaySummary.this.avatarColumn.getPreferredWidth()
+ < cellWidth ){
+ DaySummary.this.avatarColumn.setPreferredWidth(cellWidth);
+ }
+
+ return;
+ }
+
+ super.setValue(value);
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 統計種別によってセル色を変える。
+ * @param table {@inheritDoc}
+ * @param value {@inheritDoc}
+ * @param isSelected {@inheritDoc}
+ * @param hasFocus {@inheritDoc}
+ * @param row {@inheritDoc}
+ * @param column {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column ){
+ Component result = super.getTableCellRendererComponent(table,
+ value,
+ isSelected,
+ hasFocus,
+ row,
+ column );
+
+ Object selected = DaySummary.this.typeSelector.getSelectedItem();
+ Color bgColor = null;
+ if(selected == PUBTALK){
+ bgColor = TalkDraw.COLOR_PUBLIC;
+ }else if(selected == WOLFTALK){
+ bgColor = TalkDraw.COLOR_WOLFONLY;
+ }else if(selected == GRAVETALK){
+ bgColor = TalkDraw.COLOR_GRAVE;
+ }else if(selected == PRVTALK){
+ bgColor = TalkDraw.COLOR_PRIVATE;
+ }else if(selected == ALLTALK){
+ bgColor = COLOR_ALL;
+ }else{
+ assert false;
+ return null;
+ }
+
+ result.setForeground(Color.BLACK);
+ result.setBackground(bgColor);
+
+ return result;
+ }
+ }
+
+}