Warning: Can't use blame annotator:
svn blame failed on trunk/src/tmcsim/client/cadclientgui/screens/AssignedIncidents.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/src/tmcsim/client/cadclientgui/screens/AssignedIncidents.java @ 475

Revision 475, 22.7 KB checked in by jdalbey, 7 years ago (diff)

Coordinator.java, AssignedIncidents?.java, UnitStatus?.java, CADMenu.java: Add comments and error messages. Add revision number to CAD Menu.

RevLine 
1package tmcsim.client.cadclientgui.screens;
2
3import java.awt.Color;
4import java.awt.Component;
5import java.awt.Dimension;
6import java.awt.Point;
7import java.awt.Toolkit;
8import java.awt.datatransfer.DataFlavor;
9import java.awt.datatransfer.Transferable;
10import java.awt.event.ComponentEvent;
11import java.awt.event.ComponentListener;
12import java.awt.event.MouseEvent;
13import java.awt.event.MouseListener;
14import java.awt.event.MouseMotionListener;
15import java.rmi.RemoteException;
16import java.util.List;
17import java.util.logging.Level;
18import java.util.logging.Logger;
19import javax.swing.Box;
20import javax.swing.BoxLayout;
21import javax.swing.JFrame;
22import javax.swing.JLabel;
23import javax.swing.JScrollPane;
24import javax.swing.JSeparator;
25import javax.swing.JTable;
26import javax.swing.ListSelectionModel;
27import javax.swing.RowSorter.SortKey;
28import javax.swing.SwingUtilities;
29import javax.swing.TransferHandler;
30import javax.swing.table.DefaultTableModel;
31import javax.swing.table.TableCellRenderer;
32import tmcsim.client.cadclientgui.enums.CADDataEnums;
33import tmcsim.client.cadclientgui.enums.CADScriptTags.UNIT_TAGS;
34import tmcsim.client.cadclientgui.enums.IncidentEnums;
35import tmcsim.client.cadclientgui.enums.TableHeaders;
36import tmcsim.client.cadclientgui.enums.UnitStatusEnums;
37
38/**
39 * This class contains the view and controller for the AssignedIncidents screen.
40 * The view was not built using a GUI builder plug-in (but may want to consider
41 * doing so in the future), and the controller uses listeners to control how the
42 * view and data act.
43 *
44 * @author Vincent
45 */
46public class AssignedIncidents extends JFrame
47{
48    private final String SCREEN_TITLE = "(Shift + F3)  Assigned Incidents";
49    private final Dimension SCREEN_DIMENSIONS = new Dimension(1400, 250);
50    private final Dimension DROP_DOWN_MENU_LABEL_DIMENSIONS = new Dimension(
51            170, 20);
52    private final Dimension DROP_DOWN_MENU_DIMENSIONS = new Dimension(170, 230);
53    private final int COLUMN_WIDTH = 120;
54    private final String[] LABELS =
55    {
56        "Add Resources...", "Greater Alarm...",
57        "Reconfigure", "Open", "Recall Incident", "Cancel", "Reassign",
58        "Link/Append", "Map", "Recall Linked Incidents", "Read Notes",
59        "Page...", "Mail...", "Fax..."
60    };
61    private final String LABEL_SPACING = "     ";
62    private JTable assignedIncidentsTable;
63    private JFrame assignedIncidentsMenu;
64    // labels for the drop down menu
65    private JLabel[] dropDownLabels = new JLabel[LABELS.length];
66    private static Logger clientLogger = Logger.getLogger("tmcsim.client");
67    private long lastLeftClick;// used for double clicking feature
68
69    public AssignedIncidents()
70    {
71        initComponents();
72    }
73
74    private void initComponents()
75    {
76        initializeTable();
77        initController();
78        initializeDropDownMenu();
79
80        JScrollPane scrollpane = new JScrollPane(assignedIncidentsTable);
81        scrollpane.getViewport().setBackground(Color.WHITE);
82
83        setTitle(SCREEN_TITLE);
84        setPreferredSize(SCREEN_DIMENSIONS);
85        getContentPane().add(scrollpane);
86        setResizable(true);
87        pack();
88        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
89        setLocation(0, (int) (dim.getHeight() / 4));
90        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
91        setVisible(false);
92    }
93
94    /*
95     * Initializes the table and prepares the cell renderer for color
96     * management. It initializes the default settings and handles the drag and
97     * drop feature.
98     */
99    private void initializeTable()
100    {
101        assignedIncidentsTable = new JTable()
102        {
103            /*
104             * Custom renderer to set different background/foreground colors
105             * @see javax.swing.JTable#prepareRenderer(javax.swing.table.TableCellRenderer, int, int)
106             */
107            public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
108            {
109                Component comp;
110                // In a rare odd circumstance of timing, this exception is thrown:
111                // http://pastebin.com/A3tZe07a
112                try
113                {
114                    comp = super.prepareRenderer(renderer, row, column);
115                } catch (Exception ex)
116                {
117                    clientLogger.logp(Level.INFO, "AssignedIncidents",
118                            "prepareRenderer", "row=" + row + " col=" + column, ex);
119
120                    // Our workaround is to just return a dummy value.
121                    // It will be erased in the next one second refresh
122                    return new JLabel("?");
123                }
124                // Assign a color to the auxiliary units column, labeled "Unit/s"   
125                comp.setForeground(Color.BLACK);
126                comp.setBackground(Color.CYAN);
127                if (assignedIncidentsTable.getModel().getColumnName(column).equals("Unit/s"))
128                {
129                    //System.out.println("Diagnostic: in AssignedIncidents.prepareRenderer()"); //Commenting this line breaks the client
130                    comp.setBackground(Color.BLACK);
131                    int primaryColumn = 3;
132                    try
133                    {
134                        // get the unit name from the table   JD
135                        String unitname = (String) assignedIncidentsTable.getValueAt(row, primaryColumn);
136                        // Validate that unitname isn't blank ... I think the reason this happens intermittently
137                        // is a race condition in refreshTable() that resulted in blank unitname.
138                        if (unitname != null && unitname.length() > 0)
139                        {
140                            // Fetch the unit's current status from server
141                            UnitStatusEnums ustatus = ScreenManager.theCoordinator.getCadDataUnitStatus(unitname);
142                            // Ad-hoc incidents don't have a status so use WHITE
143                            comp.setForeground(Color.WHITE);
144                            // Decide which color to use for displaying the status
145                            switch (ustatus)
146                            {
147                                case Assignable:
148                                    comp.setForeground(Color.GREEN);
149                                    break;
150                                case Arrived:
151                                    comp.setForeground(Color.YELLOW);
152                                    break;
153                                case Enroute:
154                                    comp.setForeground(Color.CYAN);
155                                    break;
156                            }
157                        }
158                        else
159                        {
160                            System.out.println("Blank unitname found in AssignedIncidents prepareRenderer.");
161                        }
162                    } catch (RemoteException e)
163                    {
164                        System.out.println("RemoteException in AssignedIncidents prepareRenderer: "+ e.getMessage());
165                    }
166                }
167
168                if (getSelectedRow() == row)
169                {
170                    comp.setForeground(Color.WHITE);
171                    comp.setBackground(Color.BLUE);
172                }
173
174                return comp;
175            }
176
177            public Class getColumnClass(int c)
178            {
179                return getValueAt(0, c).getClass();
180            }
181        };
182        // Use a custom renderer to resolve ticket #78
183        assignedIncidentsTable.setDefaultRenderer(Integer.class, new IncidentNumberRenderer());
184
185        assignedIncidentsTable.setOpaque(true);
186        assignedIncidentsTable.setIntercellSpacing(new Dimension(1, 0));
187        assignedIncidentsTable.setGridColor(Color.WHITE);
188        assignedIncidentsTable.getTableHeader().setReorderingAllowed(false);
189        assignedIncidentsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
190        assignedIncidentsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
191        assignedIncidentsTable.setAutoCreateRowSorter(true);
192        assignedIncidentsTable.setModel(new DefaultTableModel());
193
194        ((DefaultTableModel) assignedIncidentsTable.getModel()).setColumnIdentifiers(TableHeaders.ASSIGNED_INCIDENTS_HEADERS);
195
196        assignedIncidentsTable.setTransferHandler(new TransferHandler()
197        {
198            public boolean canImport(TransferHandler.TransferSupport info)
199            {
200                // Check for String flavor
201                if (!info.isDataFlavorSupported(DataFlavor.stringFlavor))
202                {
203                    return false;
204                }
205                return true;
206            }
207
208            public boolean importData(TransferHandler.TransferSupport info)
209            {
210                if (!info.isDrop())
211                {
212                    return false;
213                }
214
215                DefaultTableModel tableModel = (DefaultTableModel) assignedIncidentsTable.getModel();
216                JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
217                int index = dl.getRow();
218
219                // Get the string that is being dropped.
220                Transferable t = info.getTransferable();
221                String data;
222                try
223                {
224                    data = (String) t.getTransferData(DataFlavor.stringFlavor);
225                } catch (Exception e)
226                {
227                    return false;
228                }
229
230                // Perform the actual import
231                int incidentId = (Integer) assignedIncidentsTable.getValueAt(dl.getRow(), 0);
232                try
233                {
234                    ScreenManager.theCoordinator.setCadDataUnitAssignedId(data, incidentId);
235                    ScreenManager.theCoordinator.setCadDataUnitValue(data,
236                            UNIT_TAGS.UNIT_STATUS, UnitStatusEnums.Arrived);
237                    ScreenManager.theCoordinator.addCadDataIncidentAssignedUnitNum(incidentId, data);
238                    ScreenManager.theCoordinator.setCadDataIncidentStatus(incidentId, IncidentEnums.Assigned);
239                } catch (RemoteException e)
240                {
241                    e.printStackTrace();
242                }
243                ScreenManager.refreshScreens();
244                return true;
245            }
246        });
247
248        for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
249        {
250            assignedIncidentsTable.getColumnModel().getColumn(i).setPreferredWidth(120);
251        }
252    }
253
254    /*
255     * Adds the key and mouse listeners for the table and component listener for
256     * screen.
257     */
258    private void initController()
259    {
260        assignedIncidentsTable.addMouseListener(new MouseListener()
261        {
262            public void mouseClicked(MouseEvent e)
263            {
264                if (SwingUtilities.isLeftMouseButton(e))
265                {
266                    // TODO:  Use e.getClickCount() == 2
267                    if (System.currentTimeMillis() - lastLeftClick < 1000)
268                    {
269                        int idColumn = 0;
270                        int selectedRow = assignedIncidentsTable.getSelectedRow();
271                        try
272                        {
273                            int selectedValue = (Integer) assignedIncidentsTable.getValueAt(selectedRow, idColumn);
274                            ScreenManager.openIncidentViewer(selectedValue);
275                        } catch (IndexOutOfBoundsException ex)
276                        {
277                            ex.printStackTrace();
278                        }
279                    }
280                    else
281                    {
282                        lastLeftClick = System.currentTimeMillis();
283                    }
284                }
285                if (SwingUtilities.isRightMouseButton(e))
286                {
287                    // Fixed to force right click to cause the row to be selected. JD
288                    // get the coordinates of the mouse click
289                    Point p = e.getPoint();
290                    // get the row index that contains that coordinate
291                    int rowNumber = assignedIncidentsTable.rowAtPoint(p);
292                    // Get the ListSelectionModel of the JTable
293                    ListSelectionModel model = assignedIncidentsTable.getSelectionModel();
294                    // set the selected interval of rows. Using the "rowNumber"
295                    // variable for the beginning and end selects only that one row.
296                    model.setSelectionInterval(rowNumber, rowNumber);
297                    // go open the drop down menu
298                    openDropDownMenu(e);
299                }
300                else
301                {
302                    closeDropDownMenu();
303                }
304            }
305
306            public void mouseEntered(MouseEvent e)
307            {
308            }
309
310            public void mouseExited(MouseEvent e)
311            {
312            }
313
314            public void mousePressed(MouseEvent e)
315            {
316            }
317
318            public void mouseReleased(MouseEvent e)
319            {
320            }
321        });
322
323        addComponentListener(new ComponentListener()
324        {
325            public void componentHidden(ComponentEvent e)
326            {
327            }
328
329            public void componentMoved(ComponentEvent e)
330            {
331                closeDropDownMenu();
332            }
333
334            public void componentResized(ComponentEvent e)
335            {
336            }
337
338            public void componentShown(ComponentEvent e)
339            {
340            }
341        });
342    }
343
344    /*
345     * Creates the drop down menu that appears when a right click is performed
346     * on the table.
347     */
348    private void initializeDropDownMenu()
349    {
350        Box menu = new Box(BoxLayout.Y_AXIS);
351        initializeDropDownLabels();
352        addLabelsToBox(menu);
353
354        // Sets the highlighted background color, note that it does not become
355        // "Highlighted" until opaque(true) is called
356        setMenuHighlightedBackground(Color.BLUE);
357
358        assignedIncidentsMenu = new JFrame();
359        assignedIncidentsMenu.getContentPane().add(menu);
360        assignedIncidentsMenu.setPreferredSize(DROP_DOWN_MENU_DIMENSIONS);
361        assignedIncidentsMenu.setUndecorated(true);
362        assignedIncidentsMenu.pack();
363        assignedIncidentsMenu.setVisible(false);
364    }
365
366    /*
367     * Sets the text and size and adds a listener to each activated label.
368     */
369    private void initializeDropDownLabels()
370    {
371        for (int i = 0; i < dropDownLabels.length; i++)
372        {
373            dropDownLabels[i] = new JLabel(LABEL_SPACING + LABELS[i]);
374            dropDownLabels[i].setMaximumSize(DROP_DOWN_MENU_LABEL_DIMENSIONS);
375            dropDownLabels[i].setForeground(Color.GRAY);
376        }
377        dropDownLabels[3].setForeground(Color.BLACK);
378        addMouseListenersToLabel(dropDownLabels[3]);
379        dropDownLabels[10].setForeground(Color.BLACK);
380        addMouseListenersToLabel(dropDownLabels[10]);
381    }
382
383    /*
384     * Add the labels to the box in order with separators and spacings in
385     * between.
386     */
387    private void addLabelsToBox(Box menu)
388    {
389        menu.add(dropDownLabels[0]);
390        menu.add(dropDownLabels[1]);
391        menu.add(dropDownLabels[2]);
392
393        menu.add(Box.createVerticalStrut(5));
394        menu.add(new JSeparator());
395        menu.add(Box.createVerticalStrut(5));
396
397        menu.add(dropDownLabels[3]);
398        menu.add(dropDownLabels[4]);
399        menu.add(dropDownLabels[5]);
400        menu.add(dropDownLabels[6]);
401        menu.add(dropDownLabels[7]);
402
403        menu.add(Box.createVerticalStrut(5));
404        menu.add(new JSeparator());
405        menu.add(Box.createVerticalStrut(5));
406
407        menu.add(dropDownLabels[8]);
408        menu.add(dropDownLabels[9]);
409        menu.add(dropDownLabels[10]);
410
411        menu.add(Box.createVerticalStrut(5));
412        menu.add(new JSeparator());
413        menu.add(Box.createVerticalStrut(5));
414
415        menu.add(dropDownLabels[11]);
416        menu.add(dropDownLabels[12]);
417        menu.add(dropDownLabels[13]);
418
419        menu.add(Box.createVerticalStrut(5));
420    }
421
422    /*
423     * Sets the highlighted color(when the mouse is over it) of the JLabels.
424     * Note: the color is not shown until .setOpaque(true) is called.
425     *
426     * @param color the highlighted color
427     */
428    public void setMenuHighlightedBackground(Color color)
429    {
430        for (int i = 0; i < dropDownLabels.length; i++)
431        {
432            dropDownLabels[i].setBackground(color);
433        }
434    }
435
436    /*
437     * Sets all JLabels to not display a highlighted background
438     */
439    public void unSelectAllLabels()
440    {
441        for (int i = 0; i < dropDownLabels.length; i++)
442        {
443            dropDownLabels[i].setOpaque(false);
444        }
445    }
446
447    /*
448     * Sets the label to have a highlighted background.
449     *
450     * @param label the label that is selected/highlighted
451     */
452    public void selectLabel(Object label)
453    {
454        ((JLabel) label).setOpaque(true);
455    }
456
457    /*
458     * Performs the label action depending on which label was clicked.
459     */
460    public void performLabelAction(Object label)
461    {
462        if (label.equals(dropDownLabels[0]))
463        {// Add Resources
464        }
465        else if (label.equals(dropDownLabels[1]))
466        {// Greater Alarm
467        }
468        else if (label.equals(dropDownLabels[2]))
469        {// Reconfigure
470        }
471        else if (label.equals(dropDownLabels[3]))
472        {// Open
473            int idColumn = 0;
474            int selectedRow = assignedIncidentsTable.getSelectedRow();
475            try
476            {
477                int selectedValue = (Integer) assignedIncidentsTable.getValueAt(selectedRow, idColumn);
478                ScreenManager.openIncidentViewer(selectedValue);
479            } catch (IndexOutOfBoundsException ex)
480            {
481                ex.printStackTrace();
482            }
483        }
484        else if (label.equals(dropDownLabels[4]))
485        {// Recall Incident
486        }
487        else if (label.equals(dropDownLabels[5]))
488        {// Cancel
489        }
490        else if (label.equals(dropDownLabels[6]))
491        {// Reassign
492        }
493        else if (label.equals(dropDownLabels[7]))
494        {// Link append
495        }
496        else if (label.equals(dropDownLabels[8]))
497        {// Map
498        }
499        else if (label.equals(dropDownLabels[9]))
500        {// Recall Linked Incidents
501        }
502        else if (label.equals(dropDownLabels[10]))
503        {// Read Notes
504            int idColumn = 0;
505            ScreenManager.openIncidentViewer((Integer) assignedIncidentsTable
506                    .getValueAt(assignedIncidentsTable.getSelectedRow(),
507                    idColumn));
508        }
509        else if (label.equals(dropDownLabels[11]))
510        {// Page
511        }
512        else if (label.equals(dropDownLabels[12]))
513        {// Mail
514        }
515        else if (label.equals(dropDownLabels[13]))
516        {// Fax
517        }
518    }
519
520    /*
521     * Factory method. Adds a mouse listeners to the label. The
522     * MouseMotionListener detects the mouse's location to highlight the label.
523     * The MouseListener detects for clicks and performs the action of the label
524     * designates.
525     */
526    public void addMouseListenersToLabel(JLabel label)
527    {
528        label.addMouseMotionListener(new MouseMotionListener()
529        {
530            public void mouseDragged(MouseEvent e)
531            {
532            }
533
534            public void mouseMoved(MouseEvent e)
535            {
536                unSelectAllLabels();
537                selectLabel(e.getSource());
538                assignedIncidentsMenu.revalidate();
539                assignedIncidentsMenu.repaint();
540            }
541        });
542        label.addMouseListener(new MouseListener()
543        {
544            public void mouseClicked(MouseEvent e)
545            {
546                performLabelAction(e.getSource());
547                unSelectAllLabels();
548                assignedIncidentsMenu.revalidate();
549                assignedIncidentsMenu.repaint();
550                assignedIncidentsMenu.setVisible(false);
551            }
552
553            public void mouseEntered(MouseEvent e)
554            {
555            }
556
557            public void mouseExited(MouseEvent e)
558            {
559            }
560
561            public void mousePressed(MouseEvent e)
562            {
563            }
564
565            public void mouseReleased(MouseEvent e)
566            {
567            }
568        });
569    }
570
571    /*
572     * Displays the menu where the right click occurred.
573     */
574    public void openDropDownMenu(MouseEvent e)
575    {
576        assignedIncidentsMenu.setLocation(e.getX() + this.getX(), e.getY()
577                + this.getY());
578        assignedIncidentsMenu.setVisible(true);
579    }
580
581    /*
582     * Hides the menu.
583     */
584    public void closeDropDownMenu()
585    {
586        unSelectAllLabels();
587        assignedIncidentsMenu.revalidate();
588        assignedIncidentsMenu.repaint();
589        assignedIncidentsMenu.setVisible(false);
590    }
591
592    /*
593     * Refreshes the data in the table by updating all data and repainting the
594     * screen. It saves user preferences(like column sizes, selected row, sorted preferences)
595     * and applies them to the updated model it receives from the server.
596     */
597    public void refreshTable()
598    {
599        //only update info if resize not in progress
600        if (assignedIncidentsTable.getTableHeader().getResizingColumn() == null)
601        {
602            // Note the odd comment in legacy code in prepare renderer:
603            // "//Commenting this line breaks the client"
604            // Maybe because the sout accidentally solves a concurrency problem, slowing down
605            // the prepare Renderer until the RMI call can complete.
606            int index = assignedIncidentsTable.getSelectedRow();
607            int[] columnWidths = new int[20];
608            List<? extends SortKey> keys = assignedIncidentsTable.getRowSorter().getSortKeys();
609            for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
610            {
611                columnWidths[i] = assignedIncidentsTable.getColumnModel().getColumn(i).getWidth();
612            }
613
614            // Update the model here
615            try
616            {
617                assignedIncidentsTable.setModel(ScreenManager.theCoordinator.getCadDataTable(CADDataEnums.TABLE.ASSIGNED_INCIDENTS));
618            } catch (RemoteException ex)
619            {
620                System.out.println("RemoteException in refreshTable method of AssignedIncidents.java");
621                System.out.println(ex.getMessage());
622            }
623
624            for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
625            {
626                assignedIncidentsTable.getColumnModel().getColumn(i).setPreferredWidth(columnWidths[i]);
627            }
628            assignedIncidentsTable.getRowSorter().setSortKeys(keys);
629            assignedIncidentsTable.getSelectionModel().setSelectionInterval(index, index);
630           
631            revalidate();
632            repaint();
633        }
634    }
635
636    /*
637     * Makes screen visible.
638     */
639    public void open()
640    {
641        setVisible(true);
642    }
643
644    /*
645     * Hides screen.
646     */
647    public void close()
648    {
649        setVisible(false);
650    }
651}
Note: See TracBrowser for help on using the repository browser.