source: tmcsimulator/trunk/src/tmcsim/client/cadscreens/view/CADFooterView.java @ 2

Revision 2, 21.9 KB checked in by jdalbey, 10 years ago (diff)

Initial Import of project files

Line 
1package tmcsim.client.cadscreens.view;
2
3
4import java.awt.Color;
5import java.util.Observable;
6import java.util.Observer;
7import java.util.TreeMap;
8import java.util.logging.Level;
9import java.util.logging.Logger;
10
11import javax.swing.JTextPane;
12import javax.swing.text.BadLocationException;
13import javax.swing.text.Document;
14import javax.swing.text.Style;
15import javax.swing.text.StyleConstants;
16import javax.swing.text.StyleContext;
17
18import tmcsim.common.CADEnums.CADScreenNum;
19import tmcsim.common.CADEnums.TEXT_STYLES;
20
21
22/**
23 * CADFooterView is the base view class for the footer information displayed on
24 * all CAD Screens.  The footer is used to display the following information to
25 * the user:
26 * <br>
27 * <ul>
28 * <li>Information Messages</li>
29 * <li>CAD Date</li>
30 * <li>CAD Time</li>
31 * <li>Screen Updates</li>
32 * <li>Page Scrolling</li>
33 * <li>Queued Message Count/Update</li>
34 * <li>Current CAD Screen Number</li>
35 * </ul>
36 * <br>
37 * The refreshView() method is used to add text/style pairs for the footer to the
38 * local Document object.  Update methods are provided to modify values from the 
39 * previous list.  These updates only modify the portion of the footer that has
40 * changed.  This reduces redraw of the entire footer everytime a single value
41 * changes.
42 *
43 *
44 * @author Matthew Cechini
45 * @version
46 */
47public class CADFooterView implements Observer {
48   
49    /** Error Logger.  */
50    private static Logger viewLogger = Logger.getLogger("tmcsim.client.cadscreens");
51
52    /** Font size for text displayed on CAD Screen */
53    private static final int FONT_SIZE = 15;
54   
55    /** Maximum information message length */
56    private static final int MAX_INFO_MESSAGE_LENGTH   = 50;   
57   
58    /**
59     * Enumeration containing document position values for specific text items.
60     * @author Matthew Cechini
61     */
62    private static enum DOCUMENT_POSITIONS {
63        /** Document position of the screen update status. */
64        UPDATE_STATUS_DOC_POS    (260),
65        /** Document position of the CAD date. */
66        CAD_DATE_DOC_POS         (245),
67        /** Document position of the CAD time. */
68        CAD_TIME_DOC_POS         (250),
69        /** Document position of the routed messages count. */
70        ROUTED_MESSAGE_DOC_POS   (297),
71        /** Document position of the page scrolling text. */
72        PAGE_SCROLLING_DOC_POS   (272),
73        /** Document position of the information message text. */
74        INFO_MESSAGE_DOC_POS     (81);
75       
76        public int pos;
77       
78        private DOCUMENT_POSITIONS(int p) {
79            pos = p;
80        }
81       
82    }
83
84    /** Document displaying CAD Screen text. */
85    private Document  theDoc    = null;
86
87    /** JTextPane displaying CAD Screen text. */
88    private JTextPane stylePane = null;
89   
90    /** Current page scrolling text. */
91    private String pageScrolling  = null; 
92   
93    /** Current CAD Date text. */ 
94    private String theCADDate     = null;
95   
96    /** Current CAD Time text. */
97    private String theCADTime     = null;
98   
99    /** Current number of routed messages. */
100    private int numberRoutedMessages;
101
102    /** Current flag of whether there are unread routed messages. */
103    private boolean unreadRoutedMessages;
104   
105    /** Current CAD Screen number. */
106    private CADScreenNum currentCADScreenNum;
107
108    /** Current update status for all CAD screens. */
109    private TreeMap<CADScreenNum, Boolean> screenUpdateMap;
110   
111    /**
112     * Constructor.  Initialize data elements and styles.
113     *
114     * @param viewDoc Target Document for text display.
115     */
116    public CADFooterView(Document viewDoc) {
117       
118        numberRoutedMessages = 0;
119        currentCADScreenNum  = CADScreenNum.ONE;
120        unreadRoutedMessages = false;
121        screenUpdateMap      = new TreeMap<CADScreenNum, Boolean>();
122       
123        for(CADScreenNum screen : CADScreenNum.orderedList()) {
124            screenUpdateMap.put(screen, false);
125        }
126       
127        theDoc = viewDoc;       
128        initStyles();   
129           
130    }
131
132    /**
133     * This method implements the Observer interface method.  The footer
134     * is set up to observe the main cad screen and listen for page
135     * scrolling text updates.  The update Object argument is cast
136     * to a string and the page scrolling text is replaced in the
137     * footer's display Document.
138     */
139    public void update(Observable o, Object arg) {
140       
141        pageScrolling = (String)arg;
142       
143        try {
144            if(theDoc.getLength() > 0) {
145                theDoc.remove(
146                        DOCUMENT_POSITIONS.PAGE_SCROLLING_DOC_POS.pos, 
147                        pageScrolling.length());
148               
149                theDoc.insertString(
150                        DOCUMENT_POSITIONS.PAGE_SCROLLING_DOC_POS.pos, 
151                        pageScrolling,
152                        stylePane.getStyle(TEXT_STYLES.YELLOW.style));
153            }
154        }
155        catch( BadLocationException ble) {
156            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
157        }
158    }
159   
160    /**
161     * Sets the footer's current CADScreen number.
162     *
163     * @param screenNum New CADScreen number.
164     */
165    public void setCADScreenNum(CADScreenNum screenNum) {
166        currentCADScreenNum = screenNum;
167    }
168
169    /**
170     * This method updates the CAD Screen update portion of the footer.
171     * The screenUpdateMap is updated with the new update boolean
172     * values from the parameter map.  The footer text is then
173     * updated with the new updates.  Screens with an update appear
174     * in yellow text, those without in green.   
175     *
176     * @param newStatus Map of CADScreenNum objects and their boolean update
177     * values. Map entries for all CADScreenNum values are not needed.
178     */
179    public void updateStatus(TreeMap<CADScreenNum, Boolean> newUpdates) {       
180
181        for(CADScreenNum screen : CADScreenNum.orderedList()) {
182            if(newUpdates.get(screen) != null) { 
183                screenUpdateMap.put(screen, newUpdates.get(screen));
184            }
185        }
186
187        try {
188            if(theDoc.getLength() > 0) {       
189                for(CADScreenNum screen : CADScreenNum.orderedList()) {
190                    if(newUpdates.get(screen) != null && newUpdates.get(screen)) {
191                        theDoc.remove(
192                                DOCUMENT_POSITIONS.UPDATE_STATUS_DOC_POS.pos + 
193                                ((screen.intNum-1)*3), 1);
194                        theDoc.insertString(
195                                DOCUMENT_POSITIONS.UPDATE_STATUS_DOC_POS.pos + 
196                                ((screen.intNum-1)*3), 
197                                String.valueOf(screen.intNum),
198                                stylePane.getStyle(TEXT_STYLES.YELLOW.style));
199                    }
200                }
201            }
202        }
203        catch (BadLocationException ble) {
204            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
205        }
206    }
207   
208    /**
209     * This method updates the date portion of the footer.  Only
210     * those digits in the date that have changed are changed.
211     *
212     * @param newDate The new date with format: MMYY
213     */
214    public void updateDate(String newDate) {
215       
216        try {
217            if(theDoc.getLength() > 0) {
218                for(int i = 0; i < 4; i++) {             
219                    if(theCADDate.charAt(i) != newDate.charAt(i)) {
220                        theDoc.remove(
221                                DOCUMENT_POSITIONS.CAD_DATE_DOC_POS.pos+(i), 1);
222                        theDoc.insertString(
223                                DOCUMENT_POSITIONS.CAD_DATE_DOC_POS.pos + (i), 
224                                String.valueOf(newDate.charAt(i)),
225                                stylePane.getStyle(TEXT_STYLES.GREEN.style));
226                    }
227                }
228            }
229        }
230        catch (BadLocationException ble) {
231            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
232        }   
233        finally {
234            theCADDate = newDate;
235        }
236       
237    }
238   
239    /**
240     * This method updates the time portion of the footer.  Only
241     * those digits in the time that have changed are changed.
242     *
243     * @param newTime The new time with format: HHMM
244     */
245    public void updateTime(String newTime) {
246       
247        try {
248            if(theDoc.getLength() > 0) {
249                for(int i = 0; i < 4; i++) {
250             
251                    if(theCADTime.charAt(i) != newTime.charAt(i)) {
252                        theDoc.remove(
253                                DOCUMENT_POSITIONS.CAD_TIME_DOC_POS.pos +(i), 1);
254                        theDoc.insertString(
255                                DOCUMENT_POSITIONS.CAD_TIME_DOC_POS.pos + (i), 
256                                String.valueOf(newTime.charAt(i)),
257                                stylePane.getStyle(TEXT_STYLES.GREEN.style));
258                    }
259                }
260            }
261        }
262        catch (BadLocationException ble) {
263            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
264        }       
265        finally {
266            theCADTime = newTime;
267        }
268    }   
269   
270    /**
271     * This method updates the queued messages portion of the footer.  The
272     * parameter boolean value specifies whether there are unread messages
273     * or not.  If unread messages exist, the number of messages is highlighted
274     * with green and the text is displayed yellow.  If there are no unread
275     * messages, the text is displayed unhighlighted and with green text.
276     *
277     * @param unread Boolean flag to toggle unread message highlighting.  true
278     * if unread messages exist, false if not.
279     */
280    public void updateUnreadMessages(Boolean unread) {
281        unreadRoutedMessages = unread;
282       
283        try {
284            if(theDoc.getLength() > 0) {
285           
286                theDoc.remove(
287                        DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
288                        String.valueOf(numberRoutedMessages).length());
289               
290                if(unreadRoutedMessages) { 
291                    theDoc.insertString(
292                            DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
293                            String.valueOf(numberRoutedMessages), 
294                            stylePane.getStyle(TEXT_STYLES.GREEN_HIGHLIGHT.style));
295                }
296                else {
297                    theDoc.insertString(
298                            DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
299                            String.valueOf(numberRoutedMessages), 
300                            stylePane.getStyle(TEXT_STYLES.GREEN.style));
301                }
302            }
303        }
304        catch (BadLocationException ble) {
305            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
306        }
307       
308    }
309   
310    /**
311     * This method updates the queued messages portion of the footer.  The
312     * parameter value is used to update the number of received routed
313     * messages to this CAD position.  The current number of messages is
314     * removed from the document and replaced with the new number.  If the
315     * number of messages is 0, the text is written in yellow, else the text
316     * is written in green.
317     *
318     * @param newMessageCount Number of routed messages.
319     */
320    public void updateRoutedMessageCount(Integer newMessageCount) {
321       
322        numberRoutedMessages = newMessageCount;
323       
324        try {
325            if(theDoc.getLength() > 0) {
326           
327                theDoc.remove(
328                        DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
329                        newMessageCount.toString().length());
330                if(numberRoutedMessages > 0) { 
331                    theDoc.insertString(
332                            DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
333                            String.valueOf(numberRoutedMessages), 
334                            stylePane.getStyle(TEXT_STYLES.YELLOW.style));
335                }
336                else {
337                    theDoc.insertString(
338                            DOCUMENT_POSITIONS.ROUTED_MESSAGE_DOC_POS.pos, 
339                            String.valueOf(numberRoutedMessages), 
340                            stylePane.getStyle(TEXT_STYLES.GREEN.style));
341                }
342            }
343        }
344        catch (BadLocationException ble) {
345            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
346        }
347    }       
348   
349   
350    /**
351     * This method displays an informational message on the info line of the
352     * footer.  The message to be displayed will be truncated to the maximum
353     * length which specified by the final static MAX_INFO_MESSAGE_LENGTH.
354     * Text output is written in white.
355     *
356     * @param message Message to display.
357     */
358    public void displayInfoMessage(String message) {
359        try {
360           
361            theDoc.remove(
362                    DOCUMENT_POSITIONS.INFO_MESSAGE_DOC_POS.pos, 
363                    MAX_INFO_MESSAGE_LENGTH);
364           
365            //TODO test truncation
366            if(message.length() > MAX_INFO_MESSAGE_LENGTH)
367                message = message.substring(0, MAX_INFO_MESSAGE_LENGTH);
368           
369            while(message.length() < MAX_INFO_MESSAGE_LENGTH)
370                message += " ";
371           
372            theDoc.insertString(
373                    DOCUMENT_POSITIONS.INFO_MESSAGE_DOC_POS.pos, 
374                    message,
375                    stylePane.getStyle(TEXT_STYLES.WHITE.style));
376        }
377        catch (BadLocationException ble) {
378            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
379        }
380    }
381   
382   
383    /**
384     * This method clears the display Document object and then adds text/style
385     * pairs to create the footer display document. A leading line of 80 '='
386     * characters in aqua is added for CAD Screen formatting, followed by a
387     * blank line used to display info messages. The footer items then added in
388     * the following order:
389     *
390     * <ul>
391     * <li>CAD Date</li>
392     * <li>CAD Time</li>
393     * <li>Screen Updates</li>
394     * <li>Page Scrolling</li>
395     * <li>Queued Message Count/Update</li>
396     * <li>Current CAD Screen Number</li>
397     * </ul>
398     */ 
399    public void refreshView() { 
400        try {
401                   
402            theDoc.remove(0, theDoc.getLength());
403         
404            //Load the text pane with styled text.
405           
406            theDoc.insertString(theDoc.getLength(), "==========================" +
407                    "======================================================\n", 
408                    stylePane.getStyle(TEXT_STYLES.AQUA.style));
409            theDoc.insertString(theDoc.getLength(), rPad("", 80) + "\n", 
410                    stylePane.getStyle(TEXT_STYLES.BLACK.style));       
411            theDoc.insertString(theDoc.getLength(), rPad("", 80) + "\n", 
412                    stylePane.getStyle(TEXT_STYLES.AQUA.style));   
413            theDoc.insertString(theDoc.getLength(), theCADDate +"/",
414                    stylePane.getStyle(TEXT_STYLES.GREEN.style));   
415            theDoc.insertString(theDoc.getLength(), rPad(theCADTime, 5),
416                    stylePane.getStyle(TEXT_STYLES.GREEN.style));                               
417                                                             
418            theDoc.insertString(theDoc.getLength(), "REF: ",
419                    stylePane.getStyle(TEXT_STYLES.GREEN.style));   
420
421            for(CADScreenNum screen : CADScreenNum.orderedList()) {
422                if(screenUpdateMap.get(screen)) {
423                      theDoc.insertString(theDoc.getLength(), String.valueOf(screen.intNum), 
424                              stylePane.getStyle(TEXT_STYLES.YELLOW.style));       
425                }
426                else {
427                      theDoc.insertString(theDoc.getLength(), String.valueOf(screen.intNum), 
428                              stylePane.getStyle(TEXT_STYLES.GREEN.style)); 
429                }
430                theDoc.insertString(theDoc.getLength(), "  ",
431                        stylePane.getStyle(TEXT_STYLES.GREEN.style));   
432            }
433                                                                         
434            theDoc.insertString(theDoc.getLength(), pageScrolling,
435                                stylePane.getStyle(TEXT_STYLES.YELLOW.style));                                                               
436   
437            theDoc.insertString(theDoc.getLength(), rPad(lPad("CAD: 0  0  0", 18), 20), 
438                    stylePane.getStyle(TEXT_STYLES.GREEN.style));                   
439           
440            if(unreadRoutedMessages)                 
441                theDoc.insertString(theDoc.getLength(), String.valueOf(numberRoutedMessages),
442                        stylePane.getStyle(TEXT_STYLES.GREEN_HIGHLIGHT.style));                 
443            else 
444                theDoc.insertString(theDoc.getLength(), String.valueOf(numberRoutedMessages),
445                        stylePane.getStyle(TEXT_STYLES.GREEN.style));
446           
447            theDoc.insertString(theDoc.getLength(), lPad("CLETS: 0 0", 13), 
448                                       stylePane.getStyle(TEXT_STYLES.GREEN.style));
449            theDoc.insertString(theDoc.getLength(), rPad(lPad("MIS: 0", 8), 10), 
450                       stylePane.getStyle(TEXT_STYLES.GREEN.style));
451                             
452            theDoc.insertString(theDoc.getLength(), String.valueOf(currentCADScreenNum.intNum), 
453                                       stylePane.getStyle("red"));                               
454                     
455        } 
456        catch (BadLocationException ble) {
457            viewLogger.log(Level.SEVERE, "Exception in updating view document.", ble);
458        }
459       
460    }   
461       
462    /**
463     * Method pads the parameter string with spaces to the right
464     * of the string until the string length is equal to the parameter
465     * length.  If the parameter width is less than the length of the
466     * parameter String, no action is taken.
467     *
468     * @param str String to pad.
469     * @param width Desired string length.
470     * @return Padded string.
471     */
472    protected String rPad(String str, int width) 
473    {
474        StringBuffer buf = new StringBuffer(str);
475        while(buf.length() < width)
476            buf.append(" ");
477       
478        return buf.toString();     
479    }
480   
481    /**
482     * Method pads the parameter string with spaces to the left
483     * of the string until the string length is equal to the parameter
484     * length.  If the parameter width is less than the length of the
485     * parameter String, no action is taken.
486     *
487     * @param str String to pad.
488     * @param width Desired string length.
489     * @return Padded string.
490     */   
491    protected String lPad(String str, int width) 
492    {
493        StringBuffer buf = new StringBuffer(str);
494        while(buf.length() < width)
495            buf.insert(0, " ");
496       
497        return buf.toString();     
498    }
499   
500    /**
501     * This method intializes the stylePane with the styles found in the
502     * TEXT_STYLES enumeration that are needed for footer display.
503     * The value of the static FONT_SIZE is used for text sizing, along
504     * with the COURIER font style.
505     */
506    private void initStyles() {
507             
508        stylePane = new JTextPane();
509             
510        Style def = StyleContext.getDefaultStyleContext().
511                                        getStyle(StyleContext.DEFAULT_STYLE);
512                                       
513        Style regular = stylePane.addStyle(TEXT_STYLES.REGULAR.style, def);
514        StyleConstants.setFontFamily(def, TEXT_STYLES.COURIER.style);                                       
515                                       
516        Style s = stylePane.addStyle(TEXT_STYLES.ITALIC.style, regular);
517        StyleConstants.setItalic(s, true);
518
519        s = stylePane.addStyle(TEXT_STYLES.BOLD.style, regular);
520        StyleConstants.setBold(s, true);
521       
522        s = stylePane.addStyle(TEXT_STYLES.BLUE.style, regular);
523        StyleConstants.ColorConstants.setForeground(s, Color.blue);
524        StyleConstants.setFontSize(s, FONT_SIZE);
525       
526        s = stylePane.addStyle(TEXT_STYLES.AQUA.style, regular);
527        StyleConstants.ColorConstants.setForeground(s, new Color(0,128,128));
528        StyleConstants.setFontSize(s, FONT_SIZE); 
529       
530        s = stylePane.addStyle(TEXT_STYLES.RED.style, regular);
531        StyleConstants.ColorConstants.setForeground(s, Color.red);           
532        StyleConstants.setFontSize(s, FONT_SIZE);
533       
534        s = stylePane.addStyle(TEXT_STYLES.GRAY.style, regular);
535        StyleConstants.ColorConstants.setForeground(s, Color.gray);           
536        StyleConstants.setFontSize(s, FONT_SIZE);
537       
538        s = stylePane.addStyle(TEXT_STYLES.CYAN.style, regular);
539        StyleConstants.ColorConstants.setForeground(s, Color.cyan);           
540        StyleConstants.setFontSize(s, FONT_SIZE);               
541
542        s = stylePane.addStyle(TEXT_STYLES.YELLOW.style, regular);
543        StyleConstants.ColorConstants.setForeground(s, Color.yellow);           
544        StyleConstants.setFontSize(s, FONT_SIZE); 
545
546        s = stylePane.addStyle(TEXT_STYLES.WHITE.style, regular);
547        StyleConstants.ColorConstants.setForeground(s, Color.white);           
548        StyleConstants.setFontSize(s, FONT_SIZE); 
549
550        s = stylePane.addStyle(TEXT_STYLES.GREEN.style, regular);
551        StyleConstants.ColorConstants.setForeground(s, Color.green);           
552        StyleConstants.setFontSize(s, FONT_SIZE); 
553       
554        s = stylePane.addStyle(TEXT_STYLES.REVERSE_GREEN.style, regular);         
555        StyleConstants.ColorConstants.setBackground(s, Color.green);           
556        StyleConstants.ColorConstants.setForeground(s, Color.black); 
557        StyleConstants.setFontSize(s, FONT_SIZE);   
558
559        s = stylePane.addStyle(TEXT_STYLES.GREEN_HIGHLIGHT.style, regular);         
560        StyleConstants.ColorConstants.setBackground(s, Color.green);           
561        StyleConstants.ColorConstants.setForeground(s, Color.yellow); 
562        StyleConstants.setFontSize(s, FONT_SIZE);       
563       
564    }
565}
Note: See TracBrowser for help on using the repository browser.