1
package games.strategy.triplea.ui;
3
* This program is free software; you can redistribute it and/or modify it under
4
* the terms of the GNU General Public License as published by the Free Software
5
* Foundation; either version 2 of the License, or (at your option) any later
6
* version. This program is distributed in the hope that it will be useful, but
7
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
9
* details. You should have received a copy of the GNU General Public License
10
* along with this program; if not, write to the Free Software Foundation, Inc.,
11
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
* CommentPanel.java Swing ui for comment logging.
17
* Created on September 24, 2007
20
import games.strategy.engine.data.GameData;
21
import games.strategy.engine.data.PlayerID;
22
import games.strategy.engine.history.HistoryNode;
23
import games.strategy.engine.history.Round;
24
import games.strategy.engine.history.Step;
25
import games.strategy.triplea.delegate.remote.IEditDelegate;
27
import java.awt.BorderLayout;
28
import java.awt.Container;
29
import java.awt.Insets;
30
import java.awt.event.ActionEvent;
31
import java.util.Enumeration;
32
import java.util.HashMap;
34
import java.util.regex.Matcher;
35
import java.util.regex.Pattern;
37
import javax.swing.AbstractAction;
38
import javax.swing.Action;
39
import javax.swing.BoundedRangeModel;
40
import javax.swing.Icon;
41
import javax.swing.ImageIcon;
42
import javax.swing.InputMap;
43
import javax.swing.JButton;
44
import javax.swing.JPanel;
45
import javax.swing.JScrollPane;
46
import javax.swing.JTextField;
47
import javax.swing.JTextPane;
48
import javax.swing.KeyStroke;
49
import javax.swing.SwingUtilities;
50
import javax.swing.event.TreeModelEvent;
51
import javax.swing.event.TreeModelListener;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
54
import javax.swing.text.SimpleAttributeSet;
55
import javax.swing.text.StyleConstants;
58
* A Comment logging window.
60
* @author Tony Clayton
62
public class CommentPanel extends JPanel
65
private JTextPane m_text;
66
private JScrollPane m_scrollPane;
67
private JTextField m_nextMessage;
69
private JButton m_save;
71
private GameData m_data;
72
private TripleAFrame m_frame;
73
private Map<PlayerID, Icon> m_iconMap;
76
private final SimpleAttributeSet bold = new SimpleAttributeSet();
77
private final SimpleAttributeSet italic = new SimpleAttributeSet();
78
private final SimpleAttributeSet normal = new SimpleAttributeSet();
80
public CommentPanel(TripleAFrame frame, GameData data)
93
StyleConstants.setBold(bold, true);
94
StyleConstants.setItalic(italic, true);
101
private void layoutComponents()
104
Container content = this;
105
content.setLayout(new BorderLayout());
106
m_scrollPane = new JScrollPane(m_text);
108
content.add(m_scrollPane, BorderLayout.CENTER);
111
content.add(m_scrollPane, BorderLayout.CENTER);
113
JPanel savePanel = new JPanel();
114
savePanel.setLayout(new BorderLayout());
115
savePanel.add(m_nextMessage, BorderLayout.CENTER);
116
savePanel.add(m_save, BorderLayout.WEST);
118
content.add(savePanel, BorderLayout.SOUTH);
121
private void createComponents()
124
m_text = new JTextPane();
125
m_text.setEditable(false);
126
m_text.setFocusable(false);
128
m_nextMessage = new JTextField(10);
129
//when enter is pressed, send the message
131
Insets inset = new Insets(3, 3, 3, 3);
132
m_save = new JButton(m_saveAction);
133
m_save.setMargin(inset);
134
m_save.setFocusable(false);
137
m_iconMap = new HashMap<PlayerID, Icon>();
138
for (PlayerID playerId : m_data.getPlayerList().getPlayers())
140
m_iconMap.put(playerId, new ImageIcon(m_frame.getUIContext().getFlagImageFactory().getSmallFlag( playerId )));
145
private void setupListeners()
147
m_data.getHistory().addTreeModelListener(new TreeModelListener()
149
public void treeNodesChanged(TreeModelEvent e)
152
public void treeNodesInserted(TreeModelEvent e)
155
public void treeNodesRemoved(TreeModelEvent e)
158
public void treeStructureChanged(TreeModelEvent e)
161
final TreeModelEvent tme = e;
162
Runnable runner = new Runnable()
166
m_data.acquireReadLock();
169
Document doc = m_text.getDocument();
171
HistoryNode node = (HistoryNode)(tme.getTreePath().getLastPathComponent());
172
String title = node.getTitle();
174
Pattern p = Pattern.compile("^COMMENT: (.*)");
175
Matcher m = p.matcher(title);
178
PlayerID playerId = m_data.getSequence().getStep().getPlayerID();
179
int round = m_data.getSequence().getRound();
180
String player = playerId.getName();
181
Icon icon = m_iconMap.get(playerId);
184
//insert into ui document
185
String prefix = " " + player + "("+round+") : ";
186
m_text.insertIcon(icon);
187
doc.insertString(doc.getLength(), prefix, bold);
188
doc.insertString(doc.getLength(), m.group(1) + "\n", normal);
190
catch (BadLocationException ble)
192
ble.printStackTrace();
198
m_data.releaseReadLock();
202
//invoke in the swing event thread
203
if (SwingUtilities.isEventDispatchThread())
206
SwingUtilities.invokeLater(runner);
213
private void setupKeyMap()
215
InputMap nextMessageKeymap = m_nextMessage.getInputMap();
216
nextMessageKeymap.put(KeyStroke.getKeyStroke('\n'), m_saveAction);
220
private void cleanupKeyMap()
222
InputMap nextMessageKeymap = m_nextMessage.getInputMap();
223
nextMessageKeymap.remove(KeyStroke.getKeyStroke('\n') );
226
private void loadHistory()
228
Document doc = m_text.getDocument();
229
HistoryNode rootNode = (HistoryNode) m_data.getHistory().getRoot();
231
Enumeration nodeEnum = rootNode.preorderEnumeration();
232
Pattern p = Pattern.compile("^COMMENT: (.*)");
237
while (nodeEnum.hasMoreElements())
239
HistoryNode node = (HistoryNode)nodeEnum.nextElement();
241
if (node instanceof Round)
246
else if (node instanceof Step)
248
PlayerID playerId = ((Step)node).getPlayerID();
249
if (playerId != null)
251
player = playerId.getName();
252
icon = m_iconMap.get(playerId);
258
String title = node.getTitle();
259
Matcher m = p.matcher(title);
264
//insert into ui document
265
String prefix = " " + player + "("+round+") : ";
266
m_text.insertIcon(icon);
267
doc.insertString(doc.getLength(), prefix, bold);
268
doc.insertString(doc.getLength(), m.group(1) + "\n", normal);
269
} catch (BadLocationException ble)
271
ble.printStackTrace();
281
public void addMessage(final String message)
283
Runnable runner = new Runnable()
290
Document doc = m_text.getDocument();
293
IEditDelegate delegate = m_frame.getEditDelegate();
295
if (delegate == null)
296
error = "You can only add comments during your turn";
298
error = delegate.addComment(message);
302
doc.insertString(doc.getLength(), error + "\n", italic);
305
} catch (BadLocationException ble)
307
ble.printStackTrace();
312
BoundedRangeModel scrollModel = m_scrollPane.getVerticalScrollBar().getModel();
313
scrollModel.setValue(scrollModel.getMaximum());
319
//invoke in the swing event thread
320
if (SwingUtilities.isEventDispatchThread())
323
SwingUtilities.invokeLater(runner);
328
* Show only the first n lines
330
public static void trimLines(Document doc, int lineCount)
332
if(doc.getLength() < lineCount)
337
String text = doc.getText(0, doc.getLength());
338
int returnsFound = 0;
340
for(int i = text.length() - 1; i >= 0; i--)
342
if(text.charAt(i) == '\n')
346
if(returnsFound == lineCount)
353
} catch (BadLocationException e)
363
private Action m_saveAction = new AbstractAction("Add Comment")
366
public void actionPerformed(ActionEvent e)
368
if (m_nextMessage.getText().trim().length() == 0)
372
addMessage(m_nextMessage.getText());
373
m_nextMessage.setText("");
377
public void cleanUp()