-/*\r
- * Village digest GUI\r
- *\r
- * Copyright(c) 2009 olyutorskii\r
- * $Id: VillageDigest.java 956 2009-12-13 15:14:07Z olyutorskii $\r
- */\r
-\r
-package jp.sourceforge.jindolf;\r
-\r
-import java.awt.Container;\r
-import java.awt.Dimension;\r
-import java.awt.EventQueue;\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.Rectangle;\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.WindowAdapter;\r
-import java.awt.event.WindowEvent;\r
-import java.text.DateFormat;\r
-import java.util.Date;\r
-import java.util.List;\r
-import javax.swing.BorderFactory;\r
-import javax.swing.DefaultComboBoxModel;\r
-import javax.swing.ImageIcon;\r
-import javax.swing.JButton;\r
-import javax.swing.JComboBox;\r
-import javax.swing.JComponent;\r
-import javax.swing.JDialog;\r
-import javax.swing.JLabel;\r
-import javax.swing.JPanel;\r
-import javax.swing.JPopupMenu;\r
-import javax.swing.JScrollPane;\r
-import javax.swing.JTabbedPane;\r
-import javax.swing.JTextArea;\r
-import javax.swing.JViewport;\r
-import javax.swing.border.Border;\r
-import jp.sourceforge.jindolf.corelib.GameRole;\r
-import jp.sourceforge.jindolf.corelib.Team;\r
-\r
-/**\r
- * 決着のついた村のサマリを表示する。\r
- */\r
-@SuppressWarnings("serial")\r
-public class VillageDigest\r
- extends JDialog\r
- implements ActionListener,\r
- ItemListener {\r
-\r
- private static final String FRAMETITLE =\r
- "村のダイジェスト - " + Jindolf.TITLE;\r
- private static final String ITEMDELIM = " : ";\r
-\r
- /**\r
- * キャプション付き項目をコンテナに追加。\r
- * @param container コンテナ\r
- * @param caption 項目キャプション名\r
- * @param delimiter デリミタ文字\r
- * @param item 項目アイテム\r
- */\r
- private static void addCaptionedItem(Container container,\r
- CharSequence caption,\r
- CharSequence delimiter,\r
- Object item ){\r
- LayoutManager layout = container.getLayout();\r
- if( ! (layout instanceof GridBagLayout) ){\r
- throw new IllegalArgumentException();\r
- }\r
-\r
- JLabel captionLabel = new JLabel(caption.toString());\r
- JLabel delimiterLabel = new JLabel(delimiter.toString());\r
- JComponent itemComp;\r
- if(item instanceof JComponent){\r
- itemComp = (JComponent) item;\r
- }else{\r
- itemComp = new JLabel(item.toString());\r
- }\r
-\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
-\r
- constraints.gridwidth = 1;\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- container.add(captionLabel, constraints);\r
- container.add(delimiterLabel, constraints);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
- container.add(itemComp, constraints);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * キャプション付き項目をコンテナに追加。\r
- * @param container コンテナ\r
- * @param caption 項目キャプション名\r
- * @param item 項目アイテム\r
- */\r
- private static void addCaptionedItem(Container container,\r
- CharSequence caption,\r
- Object item ){\r
- addCaptionedItem(container, caption, ITEMDELIM, item);\r
- return;\r
- }\r
-\r
- /**\r
- * レイアウトの最後に詰め物をする。\r
- * @param container コンテナ\r
- */\r
- private static void addFatPad(Container container){\r
- LayoutManager layout = container.getLayout();\r
- if( ! (layout instanceof GridBagLayout) ){\r
- throw new IllegalArgumentException();\r
- }\r
-\r
- JComponent pad = new JPanel();\r
-\r
- GridBagConstraints constraints = new GridBagConstraints();\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- container.add(pad, constraints);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * GridBagLayoutでレイアウトする空コンポーネントを生成する。\r
- * @return 空コンポーネント\r
- */\r
- private static JComponent createGridBagComponent(){\r
- JComponent result = new JPanel();\r
- LayoutManager layout = new GridBagLayout();\r
- result.setLayout(layout);\r
- return result;\r
- }\r
-\r
- private final JComponent summaryPanel = buildSummaryPanel();\r
-\r
- private final JLabel faceLabel = new JLabel();\r
- private final ImageIcon faceIcon = new ImageIcon();\r
- private final JComboBox playerBox = new JComboBox();\r
- private final DefaultComboBoxModel playerListModel =\r
- new DefaultComboBoxModel();\r
- private final JButton prevPlayer = new JButton("↑");\r
- private final JButton nextPlayer = new JButton("↓");\r
- private final JLabel roleLabel = new JLabel();\r
- private final JLabel destinyLabel = new JLabel();\r
- private final JLabel specialSkillLabel = new JLabel();\r
- private final JLabel entryLabel = new JLabel();\r
- private final JLabel idLabel = new JLabel();\r
- private final WebButton urlLine = new WebButton();\r
- private final JComponent playerPanel = buildPlayerPanel();\r
-\r
- private final JComboBox iconSetBox = new JComboBox();\r
- private final DefaultComboBoxModel iconSetListModel =\r
- new DefaultComboBoxModel();\r
- private final JLabel authorLabel = new JLabel();\r
- private final JLabel authorUrlLabel = new JLabel();\r
- private final WebButton iconCatalog = new WebButton();\r
- private final JButton genCastTableButton =\r
- new JButton("キャスト表Wiki生成");\r
- private final JButton copyClipButton =\r
- new JButton("クリップボードにコピー");\r
- private final JTextArea templateArea = new JTextArea();\r
- private final JButton voteButton = new JButton("投票Wiki生成");\r
- private final JButton vlgWikiButton = new JButton("村詳細Wiki生成");\r
- private final JComponent clipboardPanel = buildClipboardPanel();\r
-\r
- private final JButton closeButton = new JButton("閉じる");\r
-\r
- private Village village;\r
-\r
- private GameSummary gameSummary;\r
-\r
- /**\r
- * コンストラクタ。\r
- * @param owner 親フレーム\r
- */\r
- public VillageDigest(Frame owner){\r
- super(owner, FRAMETITLE, true);\r
-\r
- GUIUtils.modifyWindowAttributes(this, true, false, true);\r
-\r
- setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);\r
- addWindowListener(new WindowAdapter(){\r
- @Override\r
- public void windowClosing(WindowEvent event){\r
- actionClose();\r
- return;\r
- }\r
- });\r
-\r
- this.faceLabel.setIcon(this.faceIcon);\r
-\r
- this.playerBox.setModel(this.playerListModel);\r
- this.playerBox.addItemListener(this);\r
-\r
- this.prevPlayer.setMargin(new Insets(1, 1, 1, 1));\r
- this.prevPlayer.addActionListener(this);\r
- this.prevPlayer.setToolTipText("前のプレイヤー");\r
-\r
- this.nextPlayer.setMargin(new Insets(1, 1, 1, 1));\r
- this.nextPlayer.addActionListener(this);\r
- this.nextPlayer.setToolTipText("次のプレイヤー");\r
-\r
- this.iconSetBox.setModel(this.iconSetListModel);\r
- this.iconSetBox.addItemListener(this);\r
- for(FaceIconSet iconSet : WolfBBS.getFaceIconSetList()){\r
- this.iconSetListModel.addElement(iconSet);\r
- }\r
-\r
- this.iconCatalog.setURLText(\r
- "http://wolfbbs.jp/"\r
- +"%A4%DE%A4%C8%A4%E1%A5%B5%A5%A4%A5%C8%A4%C7"\r
- +"%CD%F8%CD%D1%B2%C4%C7%BD%A4%CA%A5%A2%A5%A4"\r
- +"%A5%B3%A5%F3%B2%E8%C1%FC.html");\r
- this.iconCatalog.setCaption("顔アイコン見本ページ");\r
-\r
- this.templateArea.setEditable(true);\r
- this.templateArea.setLineWrap(true);\r
- Monodizer.monodize(this.templateArea);\r
- JPopupMenu popup = new TextPopup();\r
- this.templateArea.setComponentPopupMenu(popup);\r
-\r
- this.genCastTableButton.addActionListener(this);\r
- this.voteButton.addActionListener(this);\r
- this.vlgWikiButton.addActionListener(this);\r
- this.copyClipButton.addActionListener(this);\r
-\r
- this.closeButton.addActionListener(this);\r
-\r
- Monodizer.monodize(this.idLabel);\r
- Monodizer.monodize(this.authorUrlLabel);\r
-\r
- Container content = getContentPane();\r
- design(content);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 村サマリ画面の生成。\r
- * @return 村サマリ画面\r
- */\r
- private JComponent buildSummaryPanel(){\r
- JComponent result = createGridBagComponent();\r
-\r
- Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * プレイヤーサマリ画面の生成。\r
- * @return プレイヤーサマリ画面\r
- */\r
- private JComponent buildPlayerPanel(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
- result.add(this.faceLabel, constraints);\r
-\r
- result.add(new JLabel(ITEMDELIM), constraints);\r
-\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
- result.add(this.playerBox, constraints);\r
- result.add(this.prevPlayer, constraints);\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- result.add(this.nextPlayer, constraints);\r
-\r
- addCaptionedItem(result, "役職", this.roleLabel);\r
- addCaptionedItem(result, "運命", this.destinyLabel);\r
- addCaptionedItem(result, "特殊技能", this.specialSkillLabel);\r
- addCaptionedItem(result, "エントリ#", this.entryLabel);\r
- addCaptionedItem(result, "ID", this.idLabel);\r
- addCaptionedItem(result, "URL", this.urlLine);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- result.add(new JPanel(), constraints);\r
-\r
- Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * キャスト表生成画面を生成する。\r
- * @return キャスト表生成画面\r
- */\r
- private JComponent buildCastPanel(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
- result.add(this.iconCatalog, constraints);\r
-\r
- addCaptionedItem(result, "顔アイコンセットを選択", this.iconSetBox);\r
- addCaptionedItem(result, "作者", this.authorLabel);\r
- addCaptionedItem(result, "URL", this.authorUrlLabel);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- result.add(this.genCastTableButton, constraints);\r
-\r
- Border border = BorderFactory.createTitledBorder("キャスト表Wiki生成");\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * 投票Box生成画面を生成する。\r
- * @return 投票Box生成画面\r
- */\r
- private JComponent buildVotePanel(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
- result.add(this.voteButton, constraints);\r
-\r
- Border border = BorderFactory.createTitledBorder("投票Wiki生成");\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * 村詳細Wiki生成画面を生成する。\r
- * @return 村詳細Wiki生成画面\r
- */\r
- private JComponent buildVillageWikiPanel(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
- result.add(this.vlgWikiButton, constraints);\r
-\r
- Border border = BorderFactory.createTitledBorder("村詳細Wiki生成");\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * Wikiテキスト領域GUIの生成。\r
- * @return Wikiテキスト領域GUI\r
- */\r
- private JComponent buildClipText(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- Border border;\r
-\r
- constraints.insets = new Insets(2, 2, 2, 2);\r
-\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.NORTHEAST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- result.add(this.copyClipButton, constraints);\r
-\r
- border = BorderFactory.createEmptyBorder(2, 2, 2, 2);\r
- this.templateArea.setBorder(border);\r
- JScrollPane scroller = new JScrollPane();\r
- JViewport viewPort = scroller.getViewport();\r
- viewPort.setView(this.templateArea);\r
- scroller.setHorizontalScrollBarPolicy(\r
- JScrollPane.HORIZONTAL_SCROLLBAR_NEVER\r
- );\r
- scroller.setMinimumSize(new Dimension(10, 50));\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- result.add(scroller, constraints);\r
-\r
- border = BorderFactory.createTitledBorder("PukiWikiテキスト");\r
- result.setBorder(border);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * テンプレート生成画面を生成する。\r
- * @return テンプレート生成画面\r
- */\r
- private JComponent buildClipboardPanel(){\r
- JComponent result = createGridBagComponent();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- constraints.insets = new Insets(3, 3, 3, 3);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
-\r
- JComponent castPanel = buildCastPanel();\r
- result.add(castPanel, constraints);\r
-\r
- JComponent vlgWikiPanel = buildVillageWikiPanel();\r
- result.add(vlgWikiPanel, constraints);\r
-\r
- JComponent votePanel = buildVotePanel();\r
- result.add(votePanel, constraints);\r
-\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.CENTER;\r
- result.add(new JLabel("↓↓↓"), constraints);\r
- constraints.fill = GridBagConstraints.HORIZONTAL;\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- JComponent clipText = buildClipText();\r
- result.add(clipText, constraints);\r
-\r
- return result;\r
- }\r
-\r
- /**\r
- * 画面レイアウトを行う。\r
- * @param container コンテナ\r
- */\r
- private void design(Container container){\r
- LayoutManager layout = new GridBagLayout();\r
- GridBagConstraints constraints = new GridBagConstraints();\r
-\r
- container.setLayout(layout);\r
-\r
- JScrollPane scroller1 = new JScrollPane();\r
- scroller1.getVerticalScrollBar().setUnitIncrement(15);\r
- scroller1.getHorizontalScrollBar().setUnitIncrement(15);\r
- JViewport viewPort1 = scroller1.getViewport();\r
- viewPort1.setView(this.summaryPanel);\r
-\r
- JScrollPane scroller2 = new JScrollPane();\r
- scroller2.getVerticalScrollBar().setUnitIncrement(15);\r
- scroller2.getHorizontalScrollBar().setUnitIncrement(15);\r
- JViewport viewPort2 = scroller2.getViewport();\r
- viewPort2.setView(this.playerPanel);\r
-\r
- JTabbedPane tabComp = new JTabbedPane();\r
- tabComp.add("村詳細", scroller1);\r
- tabComp.add("プレイヤー詳細", scroller2);\r
- tabComp.add("まとめサイト用Wiki生成", this.clipboardPanel);\r
-\r
- constraints.weightx = 1.0;\r
- constraints.weighty = 1.0;\r
- constraints.fill = GridBagConstraints.BOTH;\r
- constraints.anchor = GridBagConstraints.NORTHWEST;\r
- constraints.gridwidth = GridBagConstraints.REMAINDER;\r
- container.add(tabComp, constraints);\r
-\r
- constraints.insets = new Insets(3, 3, 3, 3);\r
- constraints.weightx = 0.0;\r
- constraints.weighty = 0.0;\r
- constraints.fill = GridBagConstraints.NONE;\r
- constraints.anchor = GridBagConstraints.SOUTHEAST;\r
- container.add(this.closeButton, constraints);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * このモーダルダイアログを閉じる。\r
- */\r
- private void actionClose(){\r
- setVisible(false);\r
- dispose();\r
- return;\r
- }\r
-\r
- /**\r
- * 村を設定する。\r
- * @param village 村\r
- */\r
- public void setVillage(Village village){\r
- clear();\r
-\r
- this.village = village;\r
- if(village == null) return;\r
-\r
- this.gameSummary = new GameSummary(this.village);\r
-\r
- updateSummary();\r
-\r
- for(Player player : this.gameSummary.getPlayerList()){\r
- Avatar avatar = player.getAvatar();\r
- this.playerListModel.addElement(avatar);\r
- }\r
-\r
- if(this.playerListModel.getSize() >= 2){ // 強制イベント発生\r
- Object player2nd = this.playerListModel.getElementAt(1);\r
- this.playerListModel.setSelectedItem(player2nd);\r
- Object player1st = this.playerListModel.getElementAt(0);\r
- this.playerListModel.setSelectedItem(player1st);\r
- }\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 村詳細画面の更新。\r
- */\r
- private void updateSummary(){\r
- String villageName = this.village.getVillageFullName();\r
-\r
- Team winnerTeam = this.gameSummary.getWinnerTeam();\r
- String wonTeam = winnerTeam.getTeamName();\r
-\r
- int avatarNum = this.gameSummary.countAvatarNum();\r
- String totalMember = "ゲルト + " + (avatarNum - 1) + "名 = "\r
- + avatarNum + "名";\r
-\r
- JComponent roleDetail = createGridBagComponent();\r
- for(GameRole role : GameRole.values()){\r
- List<Player> players = this.gameSummary.getRoledPlayerList(role);\r
- if(players.size() <= 0) continue;\r
- String roleName = role.getRoleName();\r
- addCaptionedItem(roleDetail, roleName, " × ", players.size());\r
- }\r
-\r
- String suddenDeath = this.gameSummary.countSuddenDeath() + "名";\r
-\r
- DateFormat dform =\r
- DateFormat.getDateTimeInstance(DateFormat.FULL,\r
- DateFormat.FULL);\r
- Date date;\r
- date = this.gameSummary.get1stTalkDate();\r
- String talk1st = dform.format(date);\r
- date = this.gameSummary.getLastTalkDate();\r
- String talkLast = dform.format(date);\r
-\r
- int limitHour = this.village.getLimitHour();\r
- int limitMinute = this.village.getLimitMinute();\r
- StringBuilder limit = new StringBuilder();\r
- if(limitHour < 10) limit.append('0');\r
- limit.append(limitHour).append(':');\r
- if(limitMinute < 10) limit.append('0');\r
- limit.append(limitMinute);\r
-\r
- JComponent transition = createGridBagComponent();\r
- for(int day = 1; day < this.village.getPeriodSize(); day++){\r
- List<Player> players = this.gameSummary.getSurvivorList(day);\r
- CharSequence roleSeq =\r
- GameSummary.getRoleBalanceSequence(players);\r
- String daySeq;\r
- Period period = this.village.getPeriod(day);\r
- daySeq = period.getCaption();\r
- addCaptionedItem(transition, daySeq, roleSeq);\r
- }\r
-\r
- StringBuilder schedule = new StringBuilder();\r
- int progressDays = this.village.getProgressDays();\r
- schedule.append("プロローグ + ")\r
- .append(progressDays)\r
- .append("日 + エピローグ");\r
-\r
- CharSequence exeInfo = this.gameSummary.dumpExecutionInfo();\r
- CharSequence eatInfo = this.gameSummary.dumpAssaultInfo();\r
- CharSequence scoreSeer = this.gameSummary.dumpSeerActivity();\r
- CharSequence scoreHunter = this.gameSummary.dumpHunterActivity();\r
-\r
- this.summaryPanel.removeAll();\r
-\r
- addCaptionedItem(this.summaryPanel, "村名", villageName);\r
- addCaptionedItem(this.summaryPanel, "勝者", wonTeam);\r
- addCaptionedItem(this.summaryPanel, "所要日数", schedule);\r
- addCaptionedItem(this.summaryPanel, "更新時刻", limit);\r
- addCaptionedItem(this.summaryPanel, "発言開始", talk1st);\r
- addCaptionedItem(this.summaryPanel, "最終発言", talkLast);\r
- addCaptionedItem(this.summaryPanel, "参加人数", totalMember);\r
- addCaptionedItem(this.summaryPanel, "役職内訳", roleDetail);\r
- addCaptionedItem(this.summaryPanel, "処刑内訳", exeInfo);\r
- addCaptionedItem(this.summaryPanel, "襲撃内訳", eatInfo);\r
- addCaptionedItem(this.summaryPanel, "突然死", suddenDeath);\r
- addCaptionedItem(this.summaryPanel, "人口推移", transition);\r
- addCaptionedItem(this.summaryPanel, "占成績", scoreSeer);\r
- addCaptionedItem(this.summaryPanel, "狩成績", scoreHunter);\r
-\r
- addFatPad(this.summaryPanel);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * アクションイベントの振り分け。\r
- * @param event アクションイベント\r
- */\r
- public void actionPerformed(ActionEvent event){\r
- Object source = event.getSource();\r
-\r
- if(source == this.closeButton){\r
- actionClose();\r
- }else if(source == this.copyClipButton){\r
- actionCopyToClipboard();\r
- }else if(source == this.genCastTableButton){\r
- actionGenCastTable();\r
- }else if(source == this.voteButton){\r
- actionGenVoteBox();\r
- }else if(source == this.vlgWikiButton){\r
- actionGenVillageWiki();\r
- }else if(source == this.prevPlayer){\r
- int index = this.playerBox.getSelectedIndex();\r
- if(index <= 0) return;\r
- index--;\r
- this.playerBox.setSelectedIndex(index);\r
- }else if(source == this.nextPlayer){\r
- int index = this.playerBox.getSelectedIndex();\r
- int playerNum = this.playerBox.getItemCount();\r
- if(index >= playerNum - 1) return;\r
- index++;\r
- this.playerBox.setSelectedIndex(index);\r
- }\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * キャスト表Wikiデータの生成を行う。\r
- */\r
- private void actionGenCastTable(){\r
- Object selected = this.iconSetListModel.getSelectedItem();\r
- if( ! (selected instanceof FaceIconSet) ) return;\r
- FaceIconSet iconSet = (FaceIconSet) selected;\r
-\r
- CharSequence wikiText = this.gameSummary.dumpCastingBoard(iconSet);\r
-\r
- putWikiText(wikiText);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 投票Boxを生成する。\r
- */\r
- private void actionGenVoteBox(){\r
- CharSequence wikiText = this.gameSummary.dumpVoteBox();\r
- putWikiText(wikiText);\r
- return;\r
- }\r
-\r
- /**\r
- * 村詳細Wikiを生成する。\r
- */\r
- private void actionGenVillageWiki(){\r
- CharSequence wikiText = this.gameSummary.dumpVillageWiki();\r
- putWikiText(wikiText);\r
- return;\r
- }\r
-\r
- /**\r
- * Wikiテキストをテキストボックスに出力する。\r
- * スクロール位置は一番上に。\r
- * @param wikiText Wikiテキスト\r
- */\r
- private void putWikiText(CharSequence wikiText){\r
- this.templateArea.setText(wikiText.toString());\r
- // 最上部へスクロールアップ\r
- EventQueue.invokeLater(new Runnable(){\r
- public void run(){\r
- templateArea.scrollRectToVisible(new Rectangle());\r
- }\r
- });\r
- // TODO あらかじめテキストを全選択させておきたい\r
- return;\r
- }\r
-\r
- /**\r
- * Wiki文字列をクリップボードへコピーする。\r
- */\r
- private void actionCopyToClipboard(){\r
- CharSequence text = this.templateArea.getText();\r
- ClipboardAction.copyToClipboard(text);\r
- return;\r
- }\r
-\r
- /**\r
- * プレイヤーの選択操作。\r
- * @param avatar 選択されたAvatar\r
- */\r
- private void selectPlayer(Avatar avatar){\r
- if(avatar == this.playerBox.getItemAt(0)){\r
- this.prevPlayer.setEnabled(false);\r
- }else{\r
- this.prevPlayer.setEnabled(true);\r
- }\r
-\r
- int playerNum = this.playerBox.getItemCount();\r
- if(avatar == this.playerBox.getItemAt(playerNum - 1)){\r
- this.nextPlayer.setEnabled(false);\r
- }else{\r
- this.nextPlayer.setEnabled(true);\r
- }\r
-\r
- Image image = village.getAvatarFaceImage(avatar);\r
- this.faceIcon.setImage(image);\r
- this.faceLabel.setIcon(null); // なぜかこれが必要\r
- this.faceLabel.setIcon(this.faceIcon);\r
-\r
- Player player = this.gameSummary.getPlayer(avatar);\r
-\r
- GameRole role = player.getRole();\r
- this.roleLabel.setText(role.getRoleName());\r
-\r
- String destinyMessage = player.getDestinyMessage();\r
- this.destinyLabel.setText(destinyMessage);\r
-\r
- CharSequence specialSkill = "";\r
- switch(role){\r
- case SEER:\r
- specialSkill = this.gameSummary.dumpSeerActivity();\r
- break;\r
- case HUNTER:\r
- specialSkill = this.gameSummary.dumpHunterActivity();\r
- break;\r
- default:\r
- break;\r
- }\r
- this.specialSkillLabel.setText(specialSkill.toString());\r
-\r
- this.entryLabel.setText(String.valueOf(player.getEntryNo()));\r
-\r
- String userId = player.getIdName();\r
- this.idLabel.setText(userId);\r
-\r
- String urlText = player.getUrlText();\r
- String caption = urlText;\r
-\r
- if(urlText == null || urlText.length() <= 0){\r
- urlText = WolfBBS.encodeURLFromId(userId);\r
- caption = "もしかして " + urlText;\r
- }\r
-\r
- this.urlLine.setURLText(urlText);\r
- this.urlLine.setCaption(caption);\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 顔アイコンセットの選択操作。\r
- * @param iconSet 顔アイコンセット\r
- */\r
- private void selectIconSet(FaceIconSet iconSet){\r
- String author = iconSet.getAuthor();\r
- String urlText = iconSet.getUrlText();\r
- this.authorLabel .setText(author + "氏");\r
- this.authorUrlLabel.setText(urlText);\r
- return;\r
- }\r
-\r
- /**\r
- * コンボボックス操作の受信。\r
- * @param event コンボボックス操作イベント\r
- */\r
- public void itemStateChanged(ItemEvent event){\r
- int state = event.getStateChange();\r
- if(state != ItemEvent.SELECTED) return;\r
-\r
- Object source = event.getSource();\r
- Object item = event.getItem();\r
- if(item == null) return;\r
-\r
- if(source == this.playerBox){\r
- if( ! (item instanceof Avatar) ) return;\r
- Avatar avatar = (Avatar) item;\r
- selectPlayer(avatar);\r
- }else if(source == this.iconSetBox){\r
- if( ! (item instanceof FaceIconSet) ) return;\r
- FaceIconSet iconSet = (FaceIconSet) item;\r
- selectIconSet(iconSet);\r
- }\r
-\r
- return;\r
- }\r
-\r
- /**\r
- * 表示内容をクリアする。\r
- */\r
- private void clear(){\r
- this.templateArea.setText("");\r
- this.playerListModel.removeAllElements();\r
- return;\r
- }\r
-\r
- // TODO ハムスター対応\r
-}\r
+/*
+ * Village digest GUI
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sfjp.jindolf.summary;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+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.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+import javax.swing.BorderFactory;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JViewport;
+import javax.swing.border.Border;
+import jp.sfjp.jindolf.data.Avatar;
+import jp.sfjp.jindolf.data.Period;
+import jp.sfjp.jindolf.data.Player;
+import jp.sfjp.jindolf.data.Village;
+import jp.sfjp.jindolf.dxchg.ClipboardAction;
+import jp.sfjp.jindolf.dxchg.FaceIconSet;
+import jp.sfjp.jindolf.dxchg.TextPopup;
+import jp.sfjp.jindolf.dxchg.WebButton;
+import jp.sfjp.jindolf.dxchg.WolfBBS;
+import jp.sfjp.jindolf.util.GUIUtils;
+import jp.sfjp.jindolf.util.Monodizer;
+import jp.sourceforge.jindolf.corelib.GameRole;
+import jp.sourceforge.jindolf.corelib.Team;
+
+/**
+ * 決着のついた村のダイジェストを表示する。
+ */
+@SuppressWarnings("serial")
+public class VillageDigest
+ extends JDialog
+ implements ActionListener,
+ ItemListener {
+
+ private static final String ITEMDELIM = " : ";
+
+
+ private final JComponent summaryPanel = buildSummaryPanel();
+
+ private final JLabel faceLabel = new JLabel();
+ private final ImageIcon faceIcon = new ImageIcon();
+ private final JComboBox<Avatar> playerBox = new JComboBox<>();
+ private final DefaultComboBoxModel<Avatar> playerListModel =
+ new DefaultComboBoxModel<>();
+ private final JButton prevPlayer = new JButton("↑");
+ private final JButton nextPlayer = new JButton("↓");
+ private final JLabel roleLabel = new JLabel();
+ private final JLabel destinyLabel = new JLabel();
+ private final JLabel specialSkillLabel = new JLabel();
+ private final JLabel entryLabel = new JLabel();
+ private final JLabel idLabel = new JLabel();
+ private final WebButton urlLine = new WebButton();
+ private final JComponent playerPanel = buildPlayerPanel();
+
+ private final JComboBox<FaceIconSet> iconSetBox = new JComboBox<>();
+ private final DefaultComboBoxModel<FaceIconSet> iconSetListModel =
+ new DefaultComboBoxModel<>();
+ private final JLabel authorLabel = new JLabel();
+ private final JLabel authorUrlLabel = new JLabel();
+ private final WebButton iconCatalog = new WebButton();
+ private final JButton genCastTableButton =
+ new JButton("キャスト表Wiki生成");
+ private final JButton copyClipButton =
+ new JButton("クリップボードにコピー");
+ private final JTextArea templateArea = new JTextArea();
+ private final JButton voteButton = new JButton("投票Wiki生成");
+ private final JButton vlgWikiButton = new JButton("村詳細Wiki生成");
+ private final JComponent clipboardPanel = buildClipboardPanel();
+
+ private final JButton closeButton = new JButton("閉じる");
+
+ private Village village;
+
+ private GameSummary gameSummary;
+
+
+ /**
+ * コンストラクタ。
+ * @param owner 親フレーム
+ */
+ public VillageDigest(Frame owner){
+ super(owner);
+ setModal(true);
+
+ GUIUtils.modifyWindowAttributes(this, true, false, true);
+
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ addWindowListener(new WindowAdapter(){
+ @Override
+ public void windowClosing(WindowEvent event){
+ actionClose();
+ return;
+ }
+ });
+
+ this.faceLabel.setIcon(this.faceIcon);
+
+ this.playerBox.setModel(this.playerListModel);
+ this.playerBox.addItemListener(this);
+
+ this.prevPlayer.setMargin(new Insets(1, 1, 1, 1));
+ this.prevPlayer.addActionListener(this);
+ this.prevPlayer.setToolTipText("前のプレイヤー");
+
+ this.nextPlayer.setMargin(new Insets(1, 1, 1, 1));
+ this.nextPlayer.addActionListener(this);
+ this.nextPlayer.setToolTipText("次のプレイヤー");
+
+ this.iconSetBox.setModel(this.iconSetListModel);
+ this.iconSetBox.addItemListener(this);
+ for(FaceIconSet iconSet : WolfBBS.getFaceIconSetList()){
+ this.iconSetListModel.addElement(iconSet);
+ }
+
+ this.iconCatalog.setURLText(
+ "http://wolfbbs.jp/"
+ +"%A4%DE%A4%C8%A4%E1%A5%B5%A5%A4%A5%C8%A4%C7"
+ +"%CD%F8%CD%D1%B2%C4%C7%BD%A4%CA%A5%A2%A5%A4"
+ +"%A5%B3%A5%F3%B2%E8%C1%FC.html");
+ this.iconCatalog.setCaption("顔アイコン見本ページ");
+
+ this.templateArea.setEditable(true);
+ this.templateArea.setLineWrap(true);
+ Monodizer.monodize(this.templateArea);
+ JPopupMenu popup = new TextPopup();
+ this.templateArea.setComponentPopupMenu(popup);
+
+ this.genCastTableButton.addActionListener(this);
+ this.voteButton.addActionListener(this);
+ this.vlgWikiButton.addActionListener(this);
+ this.copyClipButton.addActionListener(this);
+
+ this.closeButton.addActionListener(this);
+
+ Monodizer.monodize(this.idLabel);
+ Monodizer.monodize(this.authorUrlLabel);
+
+ Container content = getContentPane();
+ design(content);
+
+ return;
+ }
+
+
+ /**
+ * キャプション付き項目をコンテナに追加。
+ * @param container コンテナ
+ * @param caption 項目キャプション名
+ * @param delimiter デリミタ文字
+ * @param item 項目アイテム
+ */
+ private static void addCaptionedItem(Container container,
+ CharSequence caption,
+ CharSequence delimiter,
+ Object item ){
+ LayoutManager layout = container.getLayout();
+ if( ! (layout instanceof GridBagLayout) ){
+ throw new IllegalArgumentException();
+ }
+
+ JLabel captionLabel = new JLabel(caption.toString());
+ JLabel delimiterLabel = new JLabel(delimiter.toString());
+ JComponent itemComp;
+ if(item instanceof JComponent){
+ itemComp = (JComponent) item;
+ }else{
+ itemComp = new JLabel(item.toString());
+ }
+
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.insets = new Insets(2, 2, 2, 2);
+
+ constraints.gridwidth = 1;
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ container.add(captionLabel, constraints);
+ container.add(delimiterLabel, constraints);
+
+ constraints.weightx = 1.0;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+ container.add(itemComp, constraints);
+
+ return;
+ }
+
+ /**
+ * キャプション付き項目をコンテナに追加。
+ * @param container コンテナ
+ * @param caption 項目キャプション名
+ * @param item 項目アイテム
+ */
+ private static void addCaptionedItem(Container container,
+ CharSequence caption,
+ Object item ){
+ addCaptionedItem(container, caption, ITEMDELIM, item);
+ return;
+ }
+
+ /**
+ * レイアウトの最後に詰め物をする。
+ * @param container コンテナ
+ */
+ private static void addFatPad(Container container){
+ LayoutManager layout = container.getLayout();
+ if( ! (layout instanceof GridBagLayout) ){
+ throw new IllegalArgumentException();
+ }
+
+ JComponent pad = new JPanel();
+
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ container.add(pad, constraints);
+
+ return;
+ }
+
+ /**
+ * GridBagLayoutでレイアウトする空コンポーネントを生成する。
+ * @return 空コンポーネント
+ */
+ private static JComponent createGridBagComponent(){
+ JComponent result = new JPanel();
+ LayoutManager layout = new GridBagLayout();
+ result.setLayout(layout);
+ return result;
+ }
+
+ /**
+ * 村サマリ画面の生成。
+ * @return 村サマリ画面
+ */
+ private JComponent buildSummaryPanel(){
+ JComponent result = createGridBagComponent();
+
+ Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * プレイヤーサマリ画面の生成。
+ * @return プレイヤーサマリ画面
+ */
+ private JComponent buildPlayerPanel(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.insets = new Insets(2, 2, 2, 2);
+ result.add(this.faceLabel, constraints);
+
+ result.add(new JLabel(ITEMDELIM), constraints);
+
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+ result.add(this.playerBox, constraints);
+ result.add(this.prevPlayer, constraints);
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ result.add(this.nextPlayer, constraints);
+
+ addCaptionedItem(result, "役職", this.roleLabel);
+ addCaptionedItem(result, "運命", this.destinyLabel);
+ addCaptionedItem(result, "特殊技能", this.specialSkillLabel);
+ addCaptionedItem(result, "エントリ#", this.entryLabel);
+ addCaptionedItem(result, "ID", this.idLabel);
+ addCaptionedItem(result, "URL", this.urlLine);
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ result.add(new JPanel(), constraints);
+
+ Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * キャスト表生成画面を生成する。
+ * @return キャスト表生成画面
+ */
+ private JComponent buildCastPanel(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.insets = new Insets(2, 2, 2, 2);
+ result.add(this.iconCatalog, constraints);
+
+ addCaptionedItem(result, "顔アイコンセットを選択", this.iconSetBox);
+ addCaptionedItem(result, "作者", this.authorLabel);
+ addCaptionedItem(result, "URL", this.authorUrlLabel);
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.insets = new Insets(2, 2, 2, 2);
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ result.add(this.genCastTableButton, constraints);
+
+ Border border = BorderFactory.createTitledBorder("キャスト表Wiki生成");
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * 投票Box生成画面を生成する。
+ * @return 投票Box生成画面
+ */
+ private JComponent buildVotePanel(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.insets = new Insets(2, 2, 2, 2);
+ result.add(this.voteButton, constraints);
+
+ Border border = BorderFactory.createTitledBorder("投票Wiki生成");
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * 村詳細Wiki生成画面を生成する。
+ * @return 村詳細Wiki生成画面
+ */
+ private JComponent buildVillageWikiPanel(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ constraints.insets = new Insets(2, 2, 2, 2);
+ result.add(this.vlgWikiButton, constraints);
+
+ Border border = BorderFactory.createTitledBorder("村詳細Wiki生成");
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * Wikiテキスト領域GUIの生成。
+ * @return Wikiテキスト領域GUI
+ */
+ private JComponent buildClipText(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ Border border;
+
+ constraints.insets = new Insets(2, 2, 2, 2);
+
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.NORTHEAST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ result.add(this.copyClipButton, constraints);
+
+ border = BorderFactory.createEmptyBorder(2, 2, 2, 2);
+ this.templateArea.setBorder(border);
+ JScrollPane scroller = new JScrollPane();
+ JViewport viewPort = scroller.getViewport();
+ viewPort.setView(this.templateArea);
+ scroller.setHorizontalScrollBarPolicy(
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
+ );
+ scroller.setMinimumSize(new Dimension(10, 50));
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ result.add(scroller, constraints);
+
+ border = BorderFactory.createTitledBorder("PukiWikiテキスト");
+ result.setBorder(border);
+
+ return result;
+ }
+
+ /**
+ * テンプレート生成画面を生成する。
+ * @return テンプレート生成画面
+ */
+ private JComponent buildClipboardPanel(){
+ JComponent result = createGridBagComponent();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ constraints.insets = new Insets(3, 3, 3, 3);
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+
+ JComponent castPanel = buildCastPanel();
+ result.add(castPanel, constraints);
+
+ JComponent vlgWikiPanel = buildVillageWikiPanel();
+ result.add(vlgWikiPanel, constraints);
+
+ JComponent votePanel = buildVotePanel();
+ result.add(votePanel, constraints);
+
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.CENTER;
+ result.add(new JLabel("↓↓↓"), constraints);
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ JComponent clipText = buildClipText();
+ result.add(clipText, constraints);
+
+ return result;
+ }
+
+ /**
+ * 画面レイアウトを行う。
+ * @param container コンテナ
+ */
+ private void design(Container container){
+ LayoutManager layout = new GridBagLayout();
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ container.setLayout(layout);
+
+ JScrollPane scroller1 = new JScrollPane();
+ scroller1.getVerticalScrollBar().setUnitIncrement(15);
+ scroller1.getHorizontalScrollBar().setUnitIncrement(15);
+ JViewport viewPort1 = scroller1.getViewport();
+ viewPort1.setView(this.summaryPanel);
+
+ JScrollPane scroller2 = new JScrollPane();
+ scroller2.getVerticalScrollBar().setUnitIncrement(15);
+ scroller2.getHorizontalScrollBar().setUnitIncrement(15);
+ JViewport viewPort2 = scroller2.getViewport();
+ viewPort2.setView(this.playerPanel);
+
+ JTabbedPane tabComp = new JTabbedPane();
+ tabComp.add("村詳細", scroller1);
+ tabComp.add("プレイヤー詳細", scroller2);
+ tabComp.add("まとめサイト用Wiki生成", this.clipboardPanel);
+
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+ constraints.gridwidth = GridBagConstraints.REMAINDER;
+ container.add(tabComp, constraints);
+
+ constraints.insets = new Insets(3, 3, 3, 3);
+ constraints.weightx = 0.0;
+ constraints.weighty = 0.0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.anchor = GridBagConstraints.SOUTHEAST;
+ container.add(this.closeButton, constraints);
+
+ return;
+ }
+
+ /**
+ * このモーダルダイアログを閉じる。
+ */
+ private void actionClose(){
+ setVisible(false);
+ dispose();
+ return;
+ }
+
+ /**
+ * 村を設定する。
+ * @param village 村
+ */
+ public void setVillage(Village village){
+ clear();
+
+ this.village = village;
+ if(village == null) return;
+
+ this.gameSummary = new GameSummary(this.village);
+
+ updateSummary();
+
+ for(Player player : this.gameSummary.getPlayerList()){
+ Avatar avatar = player.getAvatar();
+ this.playerListModel.addElement(avatar);
+ }
+
+ if(this.playerListModel.getSize() >= 2){ // 強制イベント発生
+ Object player2nd = this.playerListModel.getElementAt(1);
+ this.playerListModel.setSelectedItem(player2nd);
+ Object player1st = this.playerListModel.getElementAt(0);
+ this.playerListModel.setSelectedItem(player1st);
+ }
+
+ return;
+ }
+
+ /**
+ * 村詳細画面の更新。
+ */
+ private void updateSummary(){
+ String villageName = this.village.getVillageFullName();
+
+ Team winnerTeam = this.gameSummary.getWinnerTeam();
+ String wonTeam = winnerTeam.getTeamName();
+
+ int avatarNum = this.gameSummary.countAvatarNum();
+ String totalMember = "ゲルト + " + (avatarNum - 1) + "名 = "
+ + avatarNum + "名";
+
+ JComponent roleDetail = createGridBagComponent();
+ for(GameRole role : GameRole.values()){
+ List<Player> players = this.gameSummary.getRoledPlayerList(role);
+ if(players.size() <= 0) continue;
+ String roleName = role.getRoleName();
+ addCaptionedItem(roleDetail, roleName, " × ", players.size());
+ }
+
+ String suddenDeath = this.gameSummary.countSuddenDeath() + "名";
+
+ DateFormat dform =
+ DateFormat.getDateTimeInstance(DateFormat.FULL,
+ DateFormat.FULL);
+ Date date;
+ date = this.gameSummary.get1stTalkDate();
+ String talk1st = dform.format(date);
+ date = this.gameSummary.getLastTalkDate();
+ String talkLast = dform.format(date);
+
+ int limitHour = this.village.getLimitHour();
+ int limitMinute = this.village.getLimitMinute();
+ StringBuilder limit = new StringBuilder();
+ if(limitHour < 10) limit.append('0');
+ limit.append(limitHour).append(':');
+ if(limitMinute < 10) limit.append('0');
+ limit.append(limitMinute);
+
+ JComponent transition = createGridBagComponent();
+ for(int day = 1; day < this.village.getPeriodSize(); day++){
+ List<Player> players = this.gameSummary.getSurvivorList(day);
+ CharSequence roleSeq =
+ GameSummary.getRoleBalanceSequence(players);
+ String daySeq;
+ Period period = this.village.getPeriod(day);
+ daySeq = period.getCaption();
+ addCaptionedItem(transition, daySeq, roleSeq);
+ }
+
+ StringBuilder schedule = new StringBuilder();
+ int progressDays = this.village.getProgressDays();
+ schedule.append("プロローグ + ")
+ .append(progressDays)
+ .append("日 + エピローグ");
+
+ CharSequence exeInfo = this.gameSummary.dumpExecutionInfo();
+ CharSequence eatInfo = this.gameSummary.dumpAssaultInfo();
+ CharSequence scoreSeer = this.gameSummary.dumpSeerActivity();
+ CharSequence scoreHunter = this.gameSummary.dumpHunterActivity();
+
+ this.summaryPanel.removeAll();
+
+ addCaptionedItem(this.summaryPanel, "村名", villageName);
+ addCaptionedItem(this.summaryPanel, "勝者", wonTeam);
+ addCaptionedItem(this.summaryPanel, "所要日数", schedule);
+ addCaptionedItem(this.summaryPanel, "更新時刻", limit);
+ addCaptionedItem(this.summaryPanel, "発言開始", talk1st);
+ addCaptionedItem(this.summaryPanel, "最終発言", talkLast);
+ addCaptionedItem(this.summaryPanel, "参加人数", totalMember);
+ addCaptionedItem(this.summaryPanel, "役職内訳", roleDetail);
+ addCaptionedItem(this.summaryPanel, "処刑内訳", exeInfo);
+ addCaptionedItem(this.summaryPanel, "襲撃内訳", eatInfo);
+ addCaptionedItem(this.summaryPanel, "突然死", suddenDeath);
+ addCaptionedItem(this.summaryPanel, "人口推移", transition);
+ addCaptionedItem(this.summaryPanel, "占成績", scoreSeer);
+ addCaptionedItem(this.summaryPanel, "狩成績", scoreHunter);
+
+ addFatPad(this.summaryPanel);
+
+ return;
+ }
+
+ /**
+ * アクションイベントの振り分け。
+ * @param event アクションイベント
+ */
+ @Override
+ public void actionPerformed(ActionEvent event){
+ Object source = event.getSource();
+
+ if(source == this.closeButton){
+ actionClose();
+ }else if(source == this.copyClipButton){
+ actionCopyToClipboard();
+ }else if(source == this.genCastTableButton){
+ actionGenCastTable();
+ }else if(source == this.voteButton){
+ actionGenVoteBox();
+ }else if(source == this.vlgWikiButton){
+ actionGenVillageWiki();
+ }else if(source == this.prevPlayer){
+ int index = this.playerBox.getSelectedIndex();
+ if(index <= 0) return;
+ index--;
+ this.playerBox.setSelectedIndex(index);
+ }else if(source == this.nextPlayer){
+ int index = this.playerBox.getSelectedIndex();
+ int playerNum = this.playerBox.getItemCount();
+ if(index >= playerNum - 1) return;
+ index++;
+ this.playerBox.setSelectedIndex(index);
+ }
+
+ return;
+ }
+
+ /**
+ * キャスト表Wikiデータの生成を行う。
+ */
+ private void actionGenCastTable(){
+ Object selected = this.iconSetListModel.getSelectedItem();
+ if( ! (selected instanceof FaceIconSet) ) return;
+ FaceIconSet iconSet = (FaceIconSet) selected;
+
+ CharSequence wikiText = this.gameSummary.dumpCastingBoard(iconSet);
+
+ putWikiText(wikiText);
+
+ return;
+ }
+
+ /**
+ * 投票Boxを生成する。
+ */
+ private void actionGenVoteBox(){
+ CharSequence wikiText = this.gameSummary.dumpVoteBox();
+ putWikiText(wikiText);
+ return;
+ }
+
+ /**
+ * 村詳細Wikiを生成する。
+ */
+ private void actionGenVillageWiki(){
+ CharSequence wikiText = this.gameSummary.dumpVillageWiki();
+ putWikiText(wikiText);
+ return;
+ }
+
+ /**
+ * Wikiテキストをテキストボックスに出力する。
+ * スクロール位置は一番上に。
+ * @param wikiText Wikiテキスト
+ */
+ private void putWikiText(CharSequence wikiText){
+ this.templateArea.setText(wikiText.toString());
+ // 最上部へスクロールアップ
+ EventQueue.invokeLater(new Runnable(){
+ @Override
+ public void run(){
+ JTextArea area = VillageDigest.this.templateArea;
+ area.scrollRectToVisible(new Rectangle());
+ }
+ });
+ // TODO あらかじめテキストを全選択させておきたい
+ return;
+ }
+
+ /**
+ * Wiki文字列をクリップボードへコピーする。
+ */
+ private void actionCopyToClipboard(){
+ CharSequence text = this.templateArea.getText();
+ ClipboardAction.copyToClipboard(text);
+ return;
+ }
+
+ /**
+ * プレイヤーの選択操作。
+ * @param avatar 選択されたAvatar
+ */
+ private void selectPlayer(Avatar avatar){
+ if(avatar == this.playerBox.getItemAt(0)){
+ this.prevPlayer.setEnabled(false);
+ }else{
+ this.prevPlayer.setEnabled(true);
+ }
+
+ int playerNum = this.playerBox.getItemCount();
+ if(avatar == this.playerBox.getItemAt(playerNum - 1)){
+ this.nextPlayer.setEnabled(false);
+ }else{
+ this.nextPlayer.setEnabled(true);
+ }
+
+ Image image = this.village.getAvatarFaceImage(avatar);
+ this.faceIcon.setImage(image);
+ this.faceLabel.setIcon(null); // なぜかこれが必要
+ this.faceLabel.setIcon(this.faceIcon);
+
+ Player player = this.gameSummary.getPlayer(avatar);
+
+ GameRole role = player.getRole();
+ this.roleLabel.setText(role.getRoleName());
+
+ String destinyMessage = player.getDestinyMessage();
+ this.destinyLabel.setText(destinyMessage);
+
+ CharSequence specialSkill = "";
+ switch(role){
+ case SEER:
+ specialSkill = this.gameSummary.dumpSeerActivity();
+ break;
+ case HUNTER:
+ specialSkill = this.gameSummary.dumpHunterActivity();
+ break;
+ default:
+ break;
+ }
+ this.specialSkillLabel.setText(specialSkill.toString());
+
+ this.entryLabel.setText(String.valueOf(player.getEntryNo()));
+
+ String userId = player.getIdName();
+ this.idLabel.setText(userId);
+
+ String urlText = player.getUrlText();
+ String caption = urlText;
+
+ if(urlText == null || urlText.length() <= 0){
+ urlText = WolfBBS.encodeURLFromId(userId);
+ caption = "もしかして " + urlText;
+ }
+
+ this.urlLine.setURLText(urlText);
+ this.urlLine.setCaption(caption);
+
+ return;
+ }
+
+ /**
+ * 顔アイコンセットの選択操作。
+ * @param iconSet 顔アイコンセット
+ */
+ private void selectIconSet(FaceIconSet iconSet){
+ String author = iconSet.getAuthor();
+ String urlText = iconSet.getUrlText();
+ this.authorLabel .setText(author + "氏");
+ this.authorUrlLabel.setText(urlText);
+ return;
+ }
+
+ /**
+ * コンボボックス操作の受信。
+ * @param event コンボボックス操作イベント
+ */
+ @Override
+ public void itemStateChanged(ItemEvent event){
+ int state = event.getStateChange();
+ if(state != ItemEvent.SELECTED) return;
+
+ Object source = event.getSource();
+ Object item = event.getItem();
+ if(item == null) return;
+
+ if(source == this.playerBox){
+ if( ! (item instanceof Avatar) ) return;
+ Avatar avatar = (Avatar) item;
+ selectPlayer(avatar);
+ }else if(source == this.iconSetBox){
+ if( ! (item instanceof FaceIconSet) ) return;
+ FaceIconSet iconSet = (FaceIconSet) item;
+ selectIconSet(iconSet);
+ }
+
+ return;
+ }
+
+ /**
+ * 表示内容をクリアする。
+ */
+ private void clear(){
+ this.templateArea.setText("");
+ this.playerListModel.removeAllElements();
+ return;
+ }
+
+ // TODO ハムスター対応
+}