~ubuntu-branches/ubuntu/precise/triplea/precise

« back to all changes in this revision

Viewing changes to src/games/strategy/triplea/ui/CommentPanel.java

  • Committer: Package Import Robot
  • Author(s): Scott Howard
  • Date: 2011-11-11 21:40:11 UTC
  • Revision ID: package-import@ubuntu.com-20111111214011-sehf2rwat36o2xqf
Tags: upstream-1.3.2.2
ImportĀ upstreamĀ versionĀ 1.3.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package games.strategy.triplea.ui;
 
2
/*
 
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
 
12
 */
 
13
 
 
14
/*
 
15
 * CommentPanel.java Swing ui for comment logging.
 
16
 * 
 
17
 * Created on September 24, 2007
 
18
 */
 
19
 
 
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;
 
26
 
 
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;
 
33
import java.util.Map;
 
34
import java.util.regex.Matcher;
 
35
import java.util.regex.Pattern;
 
36
 
 
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;
 
56
 
 
57
/**
 
58
 * A Comment logging window.  
 
59
 * 
 
60
 * @author Tony Clayton
 
61
 */
 
62
public class CommentPanel extends JPanel
 
63
{
 
64
    
 
65
    private JTextPane m_text;
 
66
    private JScrollPane m_scrollPane;
 
67
    private JTextField m_nextMessage;
 
68
    
 
69
    private JButton m_save;
 
70
 
 
71
    private GameData m_data;
 
72
    private TripleAFrame m_frame;
 
73
    private Map<PlayerID, Icon> m_iconMap;
 
74
 
 
75
 
 
76
    private final SimpleAttributeSet bold = new SimpleAttributeSet();
 
77
    private final SimpleAttributeSet italic = new SimpleAttributeSet();
 
78
    private final SimpleAttributeSet normal = new SimpleAttributeSet();
 
79
 
 
80
    public CommentPanel(TripleAFrame frame, GameData data)
 
81
    {
 
82
        m_frame = frame;
 
83
        m_data = data;
 
84
        init();
 
85
    }
 
86
    
 
87
    private void init()
 
88
    {
 
89
        createComponents();
 
90
        layoutComponents();
 
91
        setupKeyMap();
 
92
 
 
93
        StyleConstants.setBold(bold, true);
 
94
        StyleConstants.setItalic(italic, true);
 
95
        setSize(300, 200);
 
96
 
 
97
        loadHistory();
 
98
        setupListeners();
 
99
    }
 
100
 
 
101
    private void layoutComponents()
 
102
    {
 
103
 
 
104
        Container content = this;
 
105
        content.setLayout(new BorderLayout());
 
106
        m_scrollPane = new JScrollPane(m_text);
 
107
        
 
108
        content.add(m_scrollPane, BorderLayout.CENTER);
 
109
 
 
110
        
 
111
        content.add(m_scrollPane, BorderLayout.CENTER);
 
112
 
 
113
        JPanel savePanel = new JPanel();
 
114
        savePanel.setLayout(new BorderLayout());
 
115
        savePanel.add(m_nextMessage, BorderLayout.CENTER);
 
116
        savePanel.add(m_save, BorderLayout.WEST);
 
117
 
 
118
        content.add(savePanel, BorderLayout.SOUTH);
 
119
    }
 
120
 
 
121
    private void createComponents()
 
122
    {
 
123
 
 
124
        m_text = new JTextPane();
 
125
        m_text.setEditable(false);
 
126
        m_text.setFocusable(false);
 
127
 
 
128
        m_nextMessage = new JTextField(10);
 
129
        //when enter is pressed, send the message
 
130
        
 
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);
 
135
 
 
136
        // create icon map
 
137
        m_iconMap = new HashMap<PlayerID, Icon>();
 
138
        for (PlayerID playerId : m_data.getPlayerList().getPlayers())
 
139
        {
 
140
            m_iconMap.put(playerId, new ImageIcon(m_frame.getUIContext().getFlagImageFactory().getSmallFlag( playerId )));
 
141
        }
 
142
        
 
143
    }
 
144
 
 
145
    private void setupListeners()
 
146
    {
 
147
        m_data.getHistory().addTreeModelListener(new TreeModelListener()
 
148
        {
 
149
            public void treeNodesChanged(TreeModelEvent e)
 
150
            {
 
151
            }
 
152
            public void treeNodesInserted(TreeModelEvent e)
 
153
            {
 
154
            }
 
155
            public void treeNodesRemoved(TreeModelEvent e)
 
156
            {
 
157
            }
 
158
            public void treeStructureChanged(TreeModelEvent e)
 
159
            {
 
160
 
 
161
                final TreeModelEvent tme = e;
 
162
                Runnable runner = new Runnable()
 
163
                {
 
164
                    public void run()
 
165
                    {
 
166
                        m_data.acquireReadLock();
 
167
                        try
 
168
                        {
 
169
                            Document doc = m_text.getDocument();
 
170
 
 
171
                            HistoryNode node = (HistoryNode)(tme.getTreePath().getLastPathComponent());
 
172
                            String title = node.getTitle();
 
173
 
 
174
                            Pattern p = Pattern.compile("^COMMENT: (.*)");
 
175
                            Matcher m = p.matcher(title);
 
176
                            if(m.matches())
 
177
                            {
 
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);
 
182
                                try
 
183
                                {
 
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);
 
189
                                } 
 
190
                                catch (BadLocationException ble)
 
191
                                {
 
192
                                    ble.printStackTrace();
 
193
                                }
 
194
                            }
 
195
                        }
 
196
                        finally
 
197
                        {
 
198
                            m_data.releaseReadLock();
 
199
                        }
 
200
                    }
 
201
                };
 
202
                //invoke in the swing event thread
 
203
                if (SwingUtilities.isEventDispatchThread())
 
204
                    runner.run();
 
205
                else
 
206
                    SwingUtilities.invokeLater(runner);
 
207
            }
 
208
        });
 
209
 
 
210
    }
 
211
 
 
212
 
 
213
    private void setupKeyMap()
 
214
    {
 
215
        InputMap nextMessageKeymap = m_nextMessage.getInputMap();
 
216
        nextMessageKeymap.put(KeyStroke.getKeyStroke('\n'), m_saveAction);
 
217
    }
 
218
    
 
219
 
 
220
    private void cleanupKeyMap()
 
221
    {
 
222
        InputMap nextMessageKeymap = m_nextMessage.getInputMap();
 
223
        nextMessageKeymap.remove(KeyStroke.getKeyStroke('\n') );
 
224
    }
 
225
    
 
226
    private void loadHistory()
 
227
    {
 
228
        Document doc = m_text.getDocument();
 
229
        HistoryNode rootNode = (HistoryNode) m_data.getHistory().getRoot();
 
230
 
 
231
        Enumeration nodeEnum = rootNode.preorderEnumeration();
 
232
        Pattern p = Pattern.compile("^COMMENT: (.*)");
 
233
        String player = "";
 
234
        int round = 0;
 
235
        Icon icon = null;
 
236
        
 
237
        while (nodeEnum.hasMoreElements())
 
238
        {
 
239
            HistoryNode node = (HistoryNode)nodeEnum.nextElement();
 
240
 
 
241
            if (node instanceof Round)
 
242
            {
 
243
                round++;
 
244
                continue;
 
245
            }
 
246
            else if (node instanceof Step)
 
247
            {
 
248
                PlayerID playerId = ((Step)node).getPlayerID();
 
249
                if (playerId != null)
 
250
                {
 
251
                    player = playerId.getName();
 
252
                    icon = m_iconMap.get(playerId);
 
253
                }
 
254
                continue;
 
255
            }
 
256
            else
 
257
            {
 
258
                String title = node.getTitle();
 
259
                Matcher m = p.matcher(title);
 
260
                if(m.matches())
 
261
                {
 
262
                    try
 
263
                    {
 
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)
 
270
                    {
 
271
                        ble.printStackTrace();
 
272
                    }
 
273
                 
 
274
                }
 
275
            }
 
276
        }
 
277
    }
 
278
    
 
279
 
 
280
    /** thread safe */
 
281
    public void addMessage(final String message)
 
282
    {
 
283
        Runnable runner = new Runnable()
 
284
        {
 
285
            public void run()
 
286
            {
 
287
                
 
288
                try
 
289
                {
 
290
                    Document doc = m_text.getDocument();
 
291
 
 
292
                    //save history entry
 
293
                    IEditDelegate delegate = m_frame.getEditDelegate();
 
294
                    String error;
 
295
                    if (delegate == null)
 
296
                        error = "You can only add comments during your turn";
 
297
                    else
 
298
                        error = delegate.addComment(message);
 
299
 
 
300
                    if (error != null)
 
301
                    {
 
302
                        doc.insertString(doc.getLength(), error + "\n", italic);
 
303
                    }
 
304
 
 
305
                } catch (BadLocationException ble)
 
306
                {
 
307
                    ble.printStackTrace();
 
308
                } 
 
309
 
 
310
 
 
311
             
 
312
                BoundedRangeModel scrollModel = m_scrollPane.getVerticalScrollBar().getModel();
 
313
                scrollModel.setValue(scrollModel.getMaximum());
 
314
            }
 
315
 
 
316
           
 
317
        };
 
318
 
 
319
        //invoke in the swing event thread
 
320
        if (SwingUtilities.isEventDispatchThread())
 
321
            runner.run();
 
322
        else
 
323
            SwingUtilities.invokeLater(runner);
 
324
    }
 
325
    
 
326
 
 
327
    /**
 
328
     * Show only the first n lines
 
329
     */
 
330
    public static void trimLines(Document doc, int lineCount)
 
331
    {
 
332
        if(doc.getLength() < lineCount)
 
333
            return;
 
334
        
 
335
        try
 
336
        {
 
337
            String text = doc.getText(0, doc.getLength());
 
338
            int returnsFound = 0;
 
339
            
 
340
            for(int i = text.length() - 1; i >= 0; i--)
 
341
            {
 
342
                if(text.charAt(i) == '\n')
 
343
                {
 
344
                    returnsFound ++;
 
345
                }
 
346
                if(returnsFound == lineCount)
 
347
                {
 
348
                    doc.remove(0, i);
 
349
                    return;
 
350
                }
 
351
                
 
352
            }
 
353
        } catch (BadLocationException e)
 
354
        {
 
355
            e.printStackTrace();
 
356
        }
 
357
        
 
358
        
 
359
        
 
360
        
 
361
    }
 
362
    
 
363
    private Action m_saveAction = new AbstractAction("Add Comment")
 
364
    {
 
365
 
 
366
        public void actionPerformed(ActionEvent e)
 
367
        {
 
368
            if (m_nextMessage.getText().trim().length() == 0)
 
369
                return;
 
370
         
 
371
            
 
372
            addMessage(m_nextMessage.getText());
 
373
            m_nextMessage.setText("");
 
374
        }
 
375
    };
 
376
 
 
377
    public void cleanUp()
 
378
    {
 
379
        cleanupKeyMap();        
 
380
    }
 
381
    
 
382
}
 
383