OSDN Git Service

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