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

Revision 63, 21.3 KB checked in by jdalbey, 9 years ago (diff)

AssignedIncidents?, UnitStatus? add try-catch to prepareRenderer to handle bizarre timing exception

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