OSDN Git Service

クラスメンバ定義順統一
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / VillageDigest.java
1 /*\r
2  * Village digest GUI\r
3  *\r
4  * License : The MIT License\r
5  * Copyright(c) 2009 olyutorskii\r
6  */\r
7 \r
8 package jp.sourceforge.jindolf;\r
9 \r
10 import java.awt.Container;\r
11 import java.awt.Dimension;\r
12 import java.awt.EventQueue;\r
13 import java.awt.Frame;\r
14 import java.awt.GridBagConstraints;\r
15 import java.awt.GridBagLayout;\r
16 import java.awt.Image;\r
17 import java.awt.Insets;\r
18 import java.awt.LayoutManager;\r
19 import java.awt.Rectangle;\r
20 import java.awt.event.ActionEvent;\r
21 import java.awt.event.ActionListener;\r
22 import java.awt.event.ItemEvent;\r
23 import java.awt.event.ItemListener;\r
24 import java.awt.event.WindowAdapter;\r
25 import java.awt.event.WindowEvent;\r
26 import java.text.DateFormat;\r
27 import java.util.Date;\r
28 import java.util.List;\r
29 import javax.swing.BorderFactory;\r
30 import javax.swing.DefaultComboBoxModel;\r
31 import javax.swing.ImageIcon;\r
32 import javax.swing.JButton;\r
33 import javax.swing.JComboBox;\r
34 import javax.swing.JComponent;\r
35 import javax.swing.JDialog;\r
36 import javax.swing.JLabel;\r
37 import javax.swing.JPanel;\r
38 import javax.swing.JPopupMenu;\r
39 import javax.swing.JScrollPane;\r
40 import javax.swing.JTabbedPane;\r
41 import javax.swing.JTextArea;\r
42 import javax.swing.JViewport;\r
43 import javax.swing.border.Border;\r
44 import jp.sourceforge.jindolf.corelib.GameRole;\r
45 import jp.sourceforge.jindolf.corelib.Team;\r
46 \r
47 /**\r
48  * 決着のついた村のサマリを表示する。\r
49  */\r
50 @SuppressWarnings("serial")\r
51 public class VillageDigest\r
52         extends JDialog\r
53         implements ActionListener,\r
54                    ItemListener {\r
55 \r
56     private static final String FRAMETITLE =\r
57             "村のダイジェスト - " + Jindolf.TITLE;\r
58     private static final String ITEMDELIM = " : ";\r
59 \r
60 \r
61     private final JComponent summaryPanel = buildSummaryPanel();\r
62 \r
63     private final JLabel faceLabel = new JLabel();\r
64     private final ImageIcon faceIcon = new ImageIcon();\r
65     private final JComboBox playerBox = new JComboBox();\r
66     private final DefaultComboBoxModel playerListModel =\r
67             new DefaultComboBoxModel();\r
68     private final JButton prevPlayer = new JButton("↑");\r
69     private final JButton nextPlayer = new JButton("↓");\r
70     private final JLabel roleLabel = new JLabel();\r
71     private final JLabel destinyLabel = new JLabel();\r
72     private final JLabel specialSkillLabel = new JLabel();\r
73     private final JLabel entryLabel = new JLabel();\r
74     private final JLabel idLabel = new JLabel();\r
75     private final WebButton urlLine = new WebButton();\r
76     private final JComponent playerPanel = buildPlayerPanel();\r
77 \r
78     private final JComboBox iconSetBox = new JComboBox();\r
79     private final DefaultComboBoxModel iconSetListModel =\r
80             new DefaultComboBoxModel();\r
81     private final JLabel authorLabel = new JLabel();\r
82     private final JLabel authorUrlLabel = new JLabel();\r
83     private final WebButton iconCatalog = new WebButton();\r
84     private final JButton genCastTableButton =\r
85             new JButton("キャスト表Wiki生成");\r
86     private final JButton copyClipButton =\r
87             new JButton("クリップボードにコピー");\r
88     private final JTextArea templateArea = new JTextArea();\r
89     private final JButton voteButton = new JButton("投票Wiki生成");\r
90     private final JButton vlgWikiButton = new JButton("村詳細Wiki生成");\r
91     private final JComponent clipboardPanel = buildClipboardPanel();\r
92 \r
93     private final JButton closeButton = new JButton("閉じる");\r
94 \r
95     private Village village;\r
96 \r
97     private GameSummary gameSummary;\r
98 \r
99 \r
100     /**\r
101      * コンストラクタ。\r
102      * @param owner 親フレーム\r
103      */\r
104     public VillageDigest(Frame owner){\r
105         super(owner, FRAMETITLE, true);\r
106 \r
107         GUIUtils.modifyWindowAttributes(this, true, false, true);\r
108 \r
109         setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);\r
110         addWindowListener(new WindowAdapter(){\r
111             @Override\r
112             public void windowClosing(WindowEvent event){\r
113                 actionClose();\r
114                 return;\r
115             }\r
116         });\r
117 \r
118         this.faceLabel.setIcon(this.faceIcon);\r
119 \r
120         this.playerBox.setModel(this.playerListModel);\r
121         this.playerBox.addItemListener(this);\r
122 \r
123         this.prevPlayer.setMargin(new Insets(1, 1, 1, 1));\r
124         this.prevPlayer.addActionListener(this);\r
125         this.prevPlayer.setToolTipText("前のプレイヤー");\r
126 \r
127         this.nextPlayer.setMargin(new Insets(1, 1, 1, 1));\r
128         this.nextPlayer.addActionListener(this);\r
129         this.nextPlayer.setToolTipText("次のプレイヤー");\r
130 \r
131         this.iconSetBox.setModel(this.iconSetListModel);\r
132         this.iconSetBox.addItemListener(this);\r
133         for(FaceIconSet iconSet : WolfBBS.getFaceIconSetList()){\r
134             this.iconSetListModel.addElement(iconSet);\r
135         }\r
136 \r
137         this.iconCatalog.setURLText(\r
138                 "http://wolfbbs.jp/"\r
139                 +"%A4%DE%A4%C8%A4%E1%A5%B5%A5%A4%A5%C8%A4%C7"\r
140                 +"%CD%F8%CD%D1%B2%C4%C7%BD%A4%CA%A5%A2%A5%A4"\r
141                 +"%A5%B3%A5%F3%B2%E8%C1%FC.html");\r
142         this.iconCatalog.setCaption("顔アイコン見本ページ");\r
143 \r
144         this.templateArea.setEditable(true);\r
145         this.templateArea.setLineWrap(true);\r
146         Monodizer.monodize(this.templateArea);\r
147         JPopupMenu popup = new TextPopup();\r
148         this.templateArea.setComponentPopupMenu(popup);\r
149 \r
150         this.genCastTableButton.addActionListener(this);\r
151         this.voteButton.addActionListener(this);\r
152         this.vlgWikiButton.addActionListener(this);\r
153         this.copyClipButton.addActionListener(this);\r
154 \r
155         this.closeButton.addActionListener(this);\r
156 \r
157         Monodizer.monodize(this.idLabel);\r
158         Monodizer.monodize(this.authorUrlLabel);\r
159 \r
160         Container content = getContentPane();\r
161         design(content);\r
162 \r
163         return;\r
164     }\r
165 \r
166 \r
167     /**\r
168      * キャプション付き項目をコンテナに追加。\r
169      * @param container コンテナ\r
170      * @param caption 項目キャプション名\r
171      * @param delimiter デリミタ文字\r
172      * @param item 項目アイテム\r
173      */\r
174     private static void addCaptionedItem(Container container,\r
175                                            CharSequence caption,\r
176                                            CharSequence delimiter,\r
177                                            Object item ){\r
178         LayoutManager layout = container.getLayout();\r
179         if( ! (layout instanceof GridBagLayout) ){\r
180             throw new IllegalArgumentException();\r
181         }\r
182 \r
183         JLabel captionLabel   = new JLabel(caption.toString());\r
184         JLabel delimiterLabel = new JLabel(delimiter.toString());\r
185         JComponent itemComp;\r
186         if(item instanceof JComponent){\r
187             itemComp = (JComponent) item;\r
188         }else{\r
189             itemComp = new JLabel(item.toString());\r
190         }\r
191 \r
192         GridBagConstraints constraints = new GridBagConstraints();\r
193 \r
194         constraints.weightx = 0.0;\r
195         constraints.weighty = 0.0;\r
196         constraints.fill    = GridBagConstraints.NONE;\r
197         constraints.insets  = new Insets(2, 2, 2, 2);\r
198 \r
199         constraints.gridwidth = 1;\r
200         constraints.anchor    = GridBagConstraints.NORTHEAST;\r
201         container.add(captionLabel, constraints);\r
202         container.add(delimiterLabel, constraints);\r
203 \r
204         constraints.weightx = 1.0;\r
205         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
206         constraints.anchor    = GridBagConstraints.NORTHWEST;\r
207         container.add(itemComp, constraints);\r
208 \r
209         return;\r
210     }\r
211 \r
212     /**\r
213      * キャプション付き項目をコンテナに追加。\r
214      * @param container コンテナ\r
215      * @param caption 項目キャプション名\r
216      * @param item 項目アイテム\r
217      */\r
218     private static void addCaptionedItem(Container container,\r
219                                            CharSequence caption,\r
220                                            Object item ){\r
221         addCaptionedItem(container, caption, ITEMDELIM, item);\r
222         return;\r
223     }\r
224 \r
225     /**\r
226      * レイアウトの最後に詰め物をする。\r
227      * @param container コンテナ\r
228      */\r
229     private static void addFatPad(Container container){\r
230         LayoutManager layout = container.getLayout();\r
231         if( ! (layout instanceof GridBagLayout) ){\r
232             throw new IllegalArgumentException();\r
233         }\r
234 \r
235         JComponent pad = new JPanel();\r
236 \r
237         GridBagConstraints constraints = new GridBagConstraints();\r
238         constraints.weightx = 1.0;\r
239         constraints.weighty = 1.0;\r
240         constraints.fill    = GridBagConstraints.BOTH;\r
241         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
242         container.add(pad, constraints);\r
243 \r
244         return;\r
245     }\r
246 \r
247     /**\r
248      * GridBagLayoutでレイアウトする空コンポーネントを生成する。\r
249      * @return 空コンポーネント\r
250      */\r
251     private static JComponent createGridBagComponent(){\r
252         JComponent result = new JPanel();\r
253         LayoutManager layout = new GridBagLayout();\r
254         result.setLayout(layout);\r
255         return result;\r
256     }\r
257 \r
258     /**\r
259      * 村サマリ画面の生成。\r
260      * @return 村サマリ画面\r
261      */\r
262     private JComponent buildSummaryPanel(){\r
263         JComponent result = createGridBagComponent();\r
264 \r
265         Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);\r
266         result.setBorder(border);\r
267 \r
268         return result;\r
269     }\r
270 \r
271     /**\r
272      * プレイヤーサマリ画面の生成。\r
273      * @return プレイヤーサマリ画面\r
274      */\r
275     private JComponent buildPlayerPanel(){\r
276         JComponent result = createGridBagComponent();\r
277         GridBagConstraints constraints = new GridBagConstraints();\r
278 \r
279         constraints.weightx = 0.0;\r
280         constraints.weighty = 0.0;\r
281         constraints.fill    = GridBagConstraints.NONE;\r
282         constraints.anchor  = GridBagConstraints.NORTHEAST;\r
283         constraints.insets  = new Insets(2, 2, 2, 2);\r
284         result.add(this.faceLabel, constraints);\r
285 \r
286         result.add(new JLabel(ITEMDELIM), constraints);\r
287 \r
288         constraints.anchor  = GridBagConstraints.NORTHWEST;\r
289         result.add(this.playerBox, constraints);\r
290         result.add(this.prevPlayer, constraints);\r
291         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
292         result.add(this.nextPlayer, constraints);\r
293 \r
294         addCaptionedItem(result, "役職",      this.roleLabel);\r
295         addCaptionedItem(result, "運命",      this.destinyLabel);\r
296         addCaptionedItem(result, "特殊技能",  this.specialSkillLabel);\r
297         addCaptionedItem(result, "エントリ#", this.entryLabel);\r
298         addCaptionedItem(result, "ID",        this.idLabel);\r
299         addCaptionedItem(result, "URL",       this.urlLine);\r
300 \r
301         constraints.weightx = 1.0;\r
302         constraints.weighty = 1.0;\r
303         constraints.fill    = GridBagConstraints.BOTH;\r
304         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
305         result.add(new JPanel(), constraints);\r
306 \r
307         Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);\r
308         result.setBorder(border);\r
309 \r
310         return result;\r
311     }\r
312 \r
313     /**\r
314      * キャスト表生成画面を生成する。\r
315      * @return キャスト表生成画面\r
316      */\r
317     private JComponent buildCastPanel(){\r
318         JComponent result = createGridBagComponent();\r
319         GridBagConstraints constraints = new GridBagConstraints();\r
320 \r
321         constraints.anchor  = GridBagConstraints.NORTHEAST;\r
322         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
323         constraints.insets  = new Insets(2, 2, 2, 2);\r
324         result.add(this.iconCatalog, constraints);\r
325 \r
326         addCaptionedItem(result, "顔アイコンセットを選択", this.iconSetBox);\r
327         addCaptionedItem(result, "作者", this.authorLabel);\r
328         addCaptionedItem(result, "URL", this.authorUrlLabel);\r
329 \r
330         constraints.weightx = 1.0;\r
331         constraints.weighty = 0.0;\r
332         constraints.fill    = GridBagConstraints.NONE;\r
333         constraints.insets  = new Insets(2, 2, 2, 2);\r
334         constraints.anchor  = GridBagConstraints.NORTHEAST;\r
335         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
336         result.add(this.genCastTableButton, constraints);\r
337 \r
338         Border border = BorderFactory.createTitledBorder("キャスト表Wiki生成");\r
339         result.setBorder(border);\r
340 \r
341         return result;\r
342     }\r
343 \r
344     /**\r
345      * 投票Box生成画面を生成する。\r
346      * @return 投票Box生成画面\r
347      */\r
348     private JComponent buildVotePanel(){\r
349         JComponent result = createGridBagComponent();\r
350         GridBagConstraints constraints = new GridBagConstraints();\r
351 \r
352         constraints.weightx = 1.0;\r
353         constraints.weighty = 0.0;\r
354         constraints.fill    = GridBagConstraints.NONE;\r
355         constraints.anchor  = GridBagConstraints.NORTHEAST;\r
356         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
357         constraints.insets  = new Insets(2, 2, 2, 2);\r
358         result.add(this.voteButton, constraints);\r
359 \r
360         Border border = BorderFactory.createTitledBorder("投票Wiki生成");\r
361         result.setBorder(border);\r
362 \r
363         return result;\r
364     }\r
365 \r
366     /**\r
367      * 村詳細Wiki生成画面を生成する。\r
368      * @return 村詳細Wiki生成画面\r
369      */\r
370     private JComponent buildVillageWikiPanel(){\r
371         JComponent result = createGridBagComponent();\r
372         GridBagConstraints constraints = new GridBagConstraints();\r
373 \r
374         constraints.weightx = 1.0;\r
375         constraints.weighty = 0.0;\r
376         constraints.fill    = GridBagConstraints.NONE;\r
377         constraints.anchor  = GridBagConstraints.NORTHEAST;\r
378         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
379         constraints.insets  = new Insets(2, 2, 2, 2);\r
380         result.add(this.vlgWikiButton, constraints);\r
381 \r
382         Border border = BorderFactory.createTitledBorder("村詳細Wiki生成");\r
383         result.setBorder(border);\r
384 \r
385         return result;\r
386     }\r
387 \r
388     /**\r
389      * Wikiテキスト領域GUIの生成。\r
390      * @return Wikiテキスト領域GUI\r
391      */\r
392     private JComponent buildClipText(){\r
393         JComponent result = createGridBagComponent();\r
394         GridBagConstraints constraints = new GridBagConstraints();\r
395 \r
396         Border border;\r
397 \r
398         constraints.insets = new Insets(2, 2, 2, 2);\r
399 \r
400         constraints.weightx   = 0.0;\r
401         constraints.weighty   = 0.0;\r
402         constraints.fill      = GridBagConstraints.NONE;\r
403         constraints.anchor    = GridBagConstraints.NORTHEAST;\r
404         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
405         result.add(this.copyClipButton, constraints);\r
406 \r
407         border = BorderFactory.createEmptyBorder(2, 2, 2, 2);\r
408         this.templateArea.setBorder(border);\r
409         JScrollPane scroller = new JScrollPane();\r
410         JViewport viewPort = scroller.getViewport();\r
411         viewPort.setView(this.templateArea);\r
412         scroller.setHorizontalScrollBarPolicy(\r
413                 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER\r
414         );\r
415         scroller.setMinimumSize(new Dimension(10, 50));\r
416 \r
417         constraints.weightx = 1.0;\r
418         constraints.weighty = 1.0;\r
419         constraints.fill    = GridBagConstraints.BOTH;\r
420         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
421         result.add(scroller, constraints);\r
422 \r
423         border = BorderFactory.createTitledBorder("PukiWikiテキスト");\r
424         result.setBorder(border);\r
425 \r
426         return result;\r
427     }\r
428 \r
429     /**\r
430      * テンプレート生成画面を生成する。\r
431      * @return テンプレート生成画面\r
432      */\r
433     private JComponent buildClipboardPanel(){\r
434         JComponent result = createGridBagComponent();\r
435         GridBagConstraints constraints = new GridBagConstraints();\r
436 \r
437         constraints.insets = new Insets(3, 3, 3, 3);\r
438 \r
439         constraints.weightx = 1.0;\r
440         constraints.weighty = 0.0;\r
441         constraints.fill    = GridBagConstraints.HORIZONTAL;\r
442         constraints.anchor  = GridBagConstraints.NORTHWEST;\r
443         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
444 \r
445         JComponent castPanel = buildCastPanel();\r
446         result.add(castPanel, constraints);\r
447 \r
448         JComponent vlgWikiPanel = buildVillageWikiPanel();\r
449         result.add(vlgWikiPanel, constraints);\r
450 \r
451         JComponent votePanel = buildVotePanel();\r
452         result.add(votePanel, constraints);\r
453 \r
454         constraints.fill    = GridBagConstraints.NONE;\r
455         constraints.anchor  = GridBagConstraints.CENTER;\r
456         result.add(new JLabel("↓↓↓"), constraints);\r
457         constraints.fill    = GridBagConstraints.HORIZONTAL;\r
458         constraints.anchor  = GridBagConstraints.NORTHWEST;\r
459 \r
460         constraints.weightx = 1.0;\r
461         constraints.weighty = 1.0;\r
462         constraints.fill    = GridBagConstraints.BOTH;\r
463         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
464         JComponent clipText = buildClipText();\r
465         result.add(clipText, constraints);\r
466 \r
467         return result;\r
468     }\r
469 \r
470     /**\r
471      * 画面レイアウトを行う。\r
472      * @param container コンテナ\r
473      */\r
474     private void design(Container container){\r
475         LayoutManager layout = new GridBagLayout();\r
476         GridBagConstraints constraints = new GridBagConstraints();\r
477 \r
478         container.setLayout(layout);\r
479 \r
480         JScrollPane scroller1 = new JScrollPane();\r
481         scroller1.getVerticalScrollBar().setUnitIncrement(15);\r
482         scroller1.getHorizontalScrollBar().setUnitIncrement(15);\r
483         JViewport viewPort1 = scroller1.getViewport();\r
484         viewPort1.setView(this.summaryPanel);\r
485 \r
486         JScrollPane scroller2 = new JScrollPane();\r
487         scroller2.getVerticalScrollBar().setUnitIncrement(15);\r
488         scroller2.getHorizontalScrollBar().setUnitIncrement(15);\r
489         JViewport viewPort2 = scroller2.getViewport();\r
490         viewPort2.setView(this.playerPanel);\r
491 \r
492         JTabbedPane tabComp = new JTabbedPane();\r
493         tabComp.add("村詳細", scroller1);\r
494         tabComp.add("プレイヤー詳細", scroller2);\r
495         tabComp.add("まとめサイト用Wiki生成", this.clipboardPanel);\r
496 \r
497         constraints.weightx   = 1.0;\r
498         constraints.weighty   = 1.0;\r
499         constraints.fill      = GridBagConstraints.BOTH;\r
500         constraints.anchor    = GridBagConstraints.NORTHWEST;\r
501         constraints.gridwidth = GridBagConstraints.REMAINDER;\r
502         container.add(tabComp, constraints);\r
503 \r
504         constraints.insets = new Insets(3, 3, 3, 3);\r
505         constraints.weightx = 0.0;\r
506         constraints.weighty = 0.0;\r
507         constraints.fill    = GridBagConstraints.NONE;\r
508         constraints.anchor  = GridBagConstraints.SOUTHEAST;\r
509         container.add(this.closeButton, constraints);\r
510 \r
511         return;\r
512     }\r
513 \r
514     /**\r
515      * このモーダルダイアログを閉じる。\r
516      */\r
517     private void actionClose(){\r
518         setVisible(false);\r
519         dispose();\r
520         return;\r
521     }\r
522 \r
523     /**\r
524      * 村を設定する。\r
525      * @param village 村\r
526      */\r
527     public void setVillage(Village village){\r
528         clear();\r
529 \r
530         this.village = village;\r
531         if(village == null) return;\r
532 \r
533         this.gameSummary = new GameSummary(this.village);\r
534 \r
535         updateSummary();\r
536 \r
537         for(Player player : this.gameSummary.getPlayerList()){\r
538             Avatar avatar = player.getAvatar();\r
539             this.playerListModel.addElement(avatar);\r
540         }\r
541 \r
542         if(this.playerListModel.getSize() >= 2){ // 強制イベント発生\r
543             Object player2nd = this.playerListModel.getElementAt(1);\r
544             this.playerListModel.setSelectedItem(player2nd);\r
545             Object player1st = this.playerListModel.getElementAt(0);\r
546             this.playerListModel.setSelectedItem(player1st);\r
547         }\r
548 \r
549         return;\r
550     }\r
551 \r
552     /**\r
553      * 村詳細画面の更新。\r
554      */\r
555     private void updateSummary(){\r
556         String villageName = this.village.getVillageFullName();\r
557 \r
558         Team winnerTeam = this.gameSummary.getWinnerTeam();\r
559         String wonTeam = winnerTeam.getTeamName();\r
560 \r
561         int avatarNum = this.gameSummary.countAvatarNum();\r
562         String totalMember = "ゲルト + " + (avatarNum - 1) + "名 = "\r
563                             + avatarNum + "名";\r
564 \r
565         JComponent roleDetail = createGridBagComponent();\r
566         for(GameRole role : GameRole.values()){\r
567             List<Player> players = this.gameSummary.getRoledPlayerList(role);\r
568             if(players.size() <= 0) continue;\r
569             String roleName = role.getRoleName();\r
570             addCaptionedItem(roleDetail, roleName, " × ", players.size());\r
571         }\r
572 \r
573         String suddenDeath = this.gameSummary.countSuddenDeath() + "名";\r
574 \r
575         DateFormat dform =\r
576                 DateFormat.getDateTimeInstance(DateFormat.FULL,\r
577                                                DateFormat.FULL);\r
578         Date date;\r
579         date = this.gameSummary.get1stTalkDate();\r
580         String talk1st = dform.format(date);\r
581         date = this.gameSummary.getLastTalkDate();\r
582         String talkLast = dform.format(date);\r
583 \r
584         int limitHour   = this.village.getLimitHour();\r
585         int limitMinute = this.village.getLimitMinute();\r
586         StringBuilder limit = new StringBuilder();\r
587         if(limitHour < 10) limit.append('0');\r
588         limit.append(limitHour).append(':');\r
589         if(limitMinute < 10) limit.append('0');\r
590         limit.append(limitMinute);\r
591 \r
592         JComponent transition = createGridBagComponent();\r
593         for(int day = 1; day < this.village.getPeriodSize(); day++){\r
594             List<Player> players = this.gameSummary.getSurvivorList(day);\r
595             CharSequence roleSeq =\r
596                     GameSummary.getRoleBalanceSequence(players);\r
597             String daySeq;\r
598             Period period = this.village.getPeriod(day);\r
599             daySeq = period.getCaption();\r
600             addCaptionedItem(transition, daySeq, roleSeq);\r
601         }\r
602 \r
603         StringBuilder schedule = new StringBuilder();\r
604         int progressDays = this.village.getProgressDays();\r
605         schedule.append("プロローグ + ")\r
606                 .append(progressDays)\r
607                 .append("日 + エピローグ");\r
608 \r
609         CharSequence exeInfo = this.gameSummary.dumpExecutionInfo();\r
610         CharSequence eatInfo = this.gameSummary.dumpAssaultInfo();\r
611         CharSequence scoreSeer = this.gameSummary.dumpSeerActivity();\r
612         CharSequence scoreHunter = this.gameSummary.dumpHunterActivity();\r
613 \r
614         this.summaryPanel.removeAll();\r
615 \r
616         addCaptionedItem(this.summaryPanel, "村名",     villageName);\r
617         addCaptionedItem(this.summaryPanel, "勝者",     wonTeam);\r
618         addCaptionedItem(this.summaryPanel, "所要日数", schedule);\r
619         addCaptionedItem(this.summaryPanel, "更新時刻", limit);\r
620         addCaptionedItem(this.summaryPanel, "発言開始", talk1st);\r
621         addCaptionedItem(this.summaryPanel, "最終発言", talkLast);\r
622         addCaptionedItem(this.summaryPanel, "参加人数", totalMember);\r
623         addCaptionedItem(this.summaryPanel, "役職内訳", roleDetail);\r
624         addCaptionedItem(this.summaryPanel, "処刑内訳", exeInfo);\r
625         addCaptionedItem(this.summaryPanel, "襲撃内訳", eatInfo);\r
626         addCaptionedItem(this.summaryPanel, "突然死",   suddenDeath);\r
627         addCaptionedItem(this.summaryPanel, "人口推移", transition);\r
628         addCaptionedItem(this.summaryPanel, "占成績", scoreSeer);\r
629         addCaptionedItem(this.summaryPanel, "狩成績", scoreHunter);\r
630 \r
631         addFatPad(this.summaryPanel);\r
632 \r
633         return;\r
634     }\r
635 \r
636     /**\r
637      * アクションイベントの振り分け。\r
638      * @param event アクションイベント\r
639      */\r
640     public void actionPerformed(ActionEvent event){\r
641         Object source = event.getSource();\r
642 \r
643         if(source == this.closeButton){\r
644             actionClose();\r
645         }else if(source == this.copyClipButton){\r
646             actionCopyToClipboard();\r
647         }else if(source == this.genCastTableButton){\r
648             actionGenCastTable();\r
649         }else if(source == this.voteButton){\r
650             actionGenVoteBox();\r
651         }else if(source == this.vlgWikiButton){\r
652             actionGenVillageWiki();\r
653         }else if(source == this.prevPlayer){\r
654             int index = this.playerBox.getSelectedIndex();\r
655             if(index <= 0) return;\r
656             index--;\r
657             this.playerBox.setSelectedIndex(index);\r
658         }else if(source == this.nextPlayer){\r
659             int index = this.playerBox.getSelectedIndex();\r
660             int playerNum = this.playerBox.getItemCount();\r
661             if(index >= playerNum - 1) return;\r
662             index++;\r
663             this.playerBox.setSelectedIndex(index);\r
664         }\r
665 \r
666         return;\r
667     }\r
668 \r
669     /**\r
670      * キャスト表Wikiデータの生成を行う。\r
671      */\r
672     private void actionGenCastTable(){\r
673         Object selected = this.iconSetListModel.getSelectedItem();\r
674         if( ! (selected instanceof FaceIconSet) ) return;\r
675         FaceIconSet iconSet = (FaceIconSet) selected;\r
676 \r
677         CharSequence wikiText = this.gameSummary.dumpCastingBoard(iconSet);\r
678 \r
679         putWikiText(wikiText);\r
680 \r
681         return;\r
682     }\r
683 \r
684     /**\r
685      * 投票Boxを生成する。\r
686      */\r
687     private void actionGenVoteBox(){\r
688         CharSequence wikiText = this.gameSummary.dumpVoteBox();\r
689         putWikiText(wikiText);\r
690         return;\r
691     }\r
692 \r
693     /**\r
694      * 村詳細Wikiを生成する。\r
695      */\r
696     private void actionGenVillageWiki(){\r
697         CharSequence wikiText = this.gameSummary.dumpVillageWiki();\r
698         putWikiText(wikiText);\r
699         return;\r
700     }\r
701 \r
702     /**\r
703      * Wikiテキストをテキストボックスに出力する。\r
704      * スクロール位置は一番上に。\r
705      * @param wikiText Wikiテキスト\r
706      */\r
707     private void putWikiText(CharSequence wikiText){\r
708         this.templateArea.setText(wikiText.toString());\r
709         // 最上部へスクロールアップ\r
710         EventQueue.invokeLater(new Runnable(){\r
711             public void run(){\r
712                 templateArea.scrollRectToVisible(new Rectangle());\r
713             }\r
714         });\r
715         // TODO あらかじめテキストを全選択させておきたい\r
716         return;\r
717     }\r
718 \r
719     /**\r
720      * Wiki文字列をクリップボードへコピーする。\r
721      */\r
722     private void actionCopyToClipboard(){\r
723         CharSequence text = this.templateArea.getText();\r
724         ClipboardAction.copyToClipboard(text);\r
725         return;\r
726     }\r
727 \r
728     /**\r
729      * プレイヤーの選択操作。\r
730      * @param avatar 選択されたAvatar\r
731      */\r
732     private void selectPlayer(Avatar avatar){\r
733         if(avatar == this.playerBox.getItemAt(0)){\r
734             this.prevPlayer.setEnabled(false);\r
735         }else{\r
736             this.prevPlayer.setEnabled(true);\r
737         }\r
738 \r
739         int playerNum = this.playerBox.getItemCount();\r
740         if(avatar == this.playerBox.getItemAt(playerNum - 1)){\r
741             this.nextPlayer.setEnabled(false);\r
742         }else{\r
743             this.nextPlayer.setEnabled(true);\r
744         }\r
745 \r
746         Image image = village.getAvatarFaceImage(avatar);\r
747         this.faceIcon.setImage(image);\r
748         this.faceLabel.setIcon(null);          // なぜかこれが必要\r
749         this.faceLabel.setIcon(this.faceIcon);\r
750 \r
751         Player player = this.gameSummary.getPlayer(avatar);\r
752 \r
753         GameRole role = player.getRole();\r
754         this.roleLabel.setText(role.getRoleName());\r
755 \r
756         String destinyMessage = player.getDestinyMessage();\r
757         this.destinyLabel.setText(destinyMessage);\r
758 \r
759         CharSequence specialSkill = "";\r
760         switch(role){\r
761         case SEER:\r
762             specialSkill = this.gameSummary.dumpSeerActivity();\r
763             break;\r
764         case HUNTER:\r
765             specialSkill = this.gameSummary.dumpHunterActivity();\r
766             break;\r
767         default:\r
768             break;\r
769         }\r
770         this.specialSkillLabel.setText(specialSkill.toString());\r
771 \r
772         this.entryLabel.setText(String.valueOf(player.getEntryNo()));\r
773 \r
774         String userId = player.getIdName();\r
775         this.idLabel.setText(userId);\r
776 \r
777         String urlText = player.getUrlText();\r
778         String caption = urlText;\r
779 \r
780         if(urlText == null || urlText.length() <= 0){\r
781             urlText = WolfBBS.encodeURLFromId(userId);\r
782             caption = "もしかして " + urlText;\r
783         }\r
784 \r
785         this.urlLine.setURLText(urlText);\r
786         this.urlLine.setCaption(caption);\r
787 \r
788         return;\r
789     }\r
790 \r
791     /**\r
792      * 顔アイコンセットの選択操作。\r
793      * @param iconSet 顔アイコンセット\r
794      */\r
795     private void selectIconSet(FaceIconSet iconSet){\r
796         String author  = iconSet.getAuthor();\r
797         String urlText = iconSet.getUrlText();\r
798         this.authorLabel   .setText(author + "氏");\r
799         this.authorUrlLabel.setText(urlText);\r
800         return;\r
801     }\r
802 \r
803     /**\r
804      * コンボボックス操作の受信。\r
805      * @param event コンボボックス操作イベント\r
806      */\r
807     public void itemStateChanged(ItemEvent event){\r
808         int state = event.getStateChange();\r
809         if(state != ItemEvent.SELECTED) return;\r
810 \r
811         Object source = event.getSource();\r
812         Object item = event.getItem();\r
813         if(item == null) return;\r
814 \r
815         if(source == this.playerBox){\r
816             if( ! (item instanceof Avatar) ) return;\r
817             Avatar avatar = (Avatar) item;\r
818             selectPlayer(avatar);\r
819         }else if(source == this.iconSetBox){\r
820             if( ! (item instanceof FaceIconSet) ) return;\r
821             FaceIconSet iconSet = (FaceIconSet) item;\r
822             selectIconSet(iconSet);\r
823         }\r
824 \r
825         return;\r
826     }\r
827 \r
828     /**\r
829      * 表示内容をクリアする。\r
830      */\r
831     private void clear(){\r
832         this.templateArea.setText("");\r
833         this.playerListModel.removeAllElements();\r
834         return;\r
835     }\r
836 \r
837     // TODO ハムスター対応\r
838 }\r