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

Revision 290, 21.7 KB checked in by jdalbey, 7 years ago (diff)

IncidentNumberRenderer?.java added to address #78.

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 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
125                comp.setForeground(Color.BLACK);
126                comp.setBackground(Color.CYAN);
127                if (assignedIncidentsTable.getModel().getColumnName(column).equals("Unit/s"))
128                {//4 is the column for "Unit/s"
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
137                        if (!unitname.equals(""))
138                        {
139                            // Fetch the unit's current status from server
140                            UnitStatusEnums ustatus = ScreenManager.theCoordinator.getCadDataUnitStatus(unitname);
141                            // Decide which color to use for displaying the status
142                            switch (ustatus)
143                            {
144                                case Assignable:
145                                    comp.setForeground(Color.GREEN);
146                                    break;
147                                case Arrived:
148                                    comp.setForeground(Color.YELLOW);
149                                    break;
150                                case Enroute:
151                                    comp.setForeground(Color.CYAN);
152                                    break;
153                            }
154                        }
155                    } catch (RemoteException e)
156                    {
157                        e.printStackTrace();
158                    }
159                }
160
161                if (getSelectedRow() == row)
162                {
163                    comp.setForeground(Color.WHITE);
164                    comp.setBackground(Color.BLUE);
165                }
166
167                return comp;
168            }
169
170            public Class getColumnClass(int c)
171            {
172                return getValueAt(0, c).getClass();
173            }
174        };
175        // Use a custom renderer to resolve ticket #78
176        assignedIncidentsTable.setDefaultRenderer(Integer.class, new IncidentNumberRenderer());
177
178        assignedIncidentsTable.setOpaque(true);
179        assignedIncidentsTable.setIntercellSpacing(new Dimension(1, 0));
180        assignedIncidentsTable.setGridColor(Color.WHITE);
181        assignedIncidentsTable.getTableHeader().setReorderingAllowed(false);
182        assignedIncidentsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
183        assignedIncidentsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
184        assignedIncidentsTable.setAutoCreateRowSorter(true);
185        assignedIncidentsTable.setModel(new DefaultTableModel());
186
187        ((DefaultTableModel) assignedIncidentsTable.getModel()).setColumnIdentifiers(TableHeaders.ASSIGNED_INCIDENTS_HEADERS);
188
189        assignedIncidentsTable.setTransferHandler(new TransferHandler()
190        {
191            public boolean canImport(TransferHandler.TransferSupport info)
192            {
193                // Check for String flavor
194                if (!info.isDataFlavorSupported(DataFlavor.stringFlavor))
195                {
196                    return false;
197                }
198                return true;
199            }
200
201            public boolean importData(TransferHandler.TransferSupport info)
202            {
203                if (!info.isDrop())
204                {
205                    return false;
206                }
207
208                DefaultTableModel tableModel = (DefaultTableModel) assignedIncidentsTable.getModel();
209                JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
210                int index = dl.getRow();
211
212                // Get the string that is being dropped.
213                Transferable t = info.getTransferable();
214                String data;
215                try
216                {
217                    data = (String) t.getTransferData(DataFlavor.stringFlavor);
218                } catch (Exception e)
219                {
220                    return false;
221                }
222
223                // Perform the actual import
224                int incidentId = (Integer) assignedIncidentsTable.getValueAt(dl.getRow(), 0);
225                try
226                {
227                    ScreenManager.theCoordinator.setCadDataUnitAssignedId(data, incidentId);
228                    ScreenManager.theCoordinator.setCadDataUnitValue(data,
229                            UNIT_TAGS.UNIT_STATUS, UnitStatusEnums.Arrived);
230                    ScreenManager.theCoordinator.addCadDataIncidentAssignedUnitNum(incidentId, data);
231                    ScreenManager.theCoordinator.setCadDataIncidentStatus(incidentId, IncidentEnums.Assigned);
232                } catch (RemoteException e)
233                {
234                    e.printStackTrace();
235                }
236                ScreenManager.refreshScreens();
237                return true;
238            }
239        });
240
241        for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
242        {
243            assignedIncidentsTable.getColumnModel().getColumn(i).setPreferredWidth(120);
244        }
245    }
246
247    /*
248     * Adds the key and mouse listeners for the table and component listener for
249     * screen.
250     */
251    private void initController()
252    {
253        assignedIncidentsTable.addMouseListener(new MouseListener()
254        {
255            public void mouseClicked(MouseEvent e)
256            {
257                if (SwingUtilities.isLeftMouseButton(e))
258                {
259                    // TODO:  Use e.getClickCount() == 2
260                    if (System.currentTimeMillis() - lastLeftClick < 1000)
261                    {
262                        int idColumn = 0;
263                        int selectedRow = assignedIncidentsTable.getSelectedRow();
264                        try
265                        {
266                            int selectedValue = (Integer) assignedIncidentsTable.getValueAt(selectedRow, idColumn);
267                            ScreenManager.openIncidentViewer(selectedValue);
268                        } catch (IndexOutOfBoundsException ex)
269                        {
270                            ex.printStackTrace();
271                        }
272                    }
273                    else
274                    {
275                        lastLeftClick = System.currentTimeMillis();
276                    }
277                }
278                if (SwingUtilities.isRightMouseButton(e))
279                {
280                    // Fixed to force right click to cause the row to be selected. JD
281                    // get the coordinates of the mouse click
282                    Point p = e.getPoint();
283                    // get the row index that contains that coordinate
284                    int rowNumber = assignedIncidentsTable.rowAtPoint(p);
285                    // Get the ListSelectionModel of the JTable
286                    ListSelectionModel model = assignedIncidentsTable.getSelectionModel();
287                    // set the selected interval of rows. Using the "rowNumber"
288                    // variable for the beginning and end selects only that one row.
289                    model.setSelectionInterval(rowNumber, rowNumber);
290                    // go open the drop down menu
291                    openDropDownMenu(e);
292                }
293                else
294                {
295                    closeDropDownMenu();
296                }
297            }
298
299            public void mouseEntered(MouseEvent e)
300            {
301            }
302
303            public void mouseExited(MouseEvent e)
304            {
305            }
306
307            public void mousePressed(MouseEvent e)
308            {
309            }
310
311            public void mouseReleased(MouseEvent e)
312            {
313            }
314        });
315
316        addComponentListener(new ComponentListener()
317        {
318            public void componentHidden(ComponentEvent e)
319            {
320            }
321
322            public void componentMoved(ComponentEvent e)
323            {
324                closeDropDownMenu();
325            }
326
327            public void componentResized(ComponentEvent e)
328            {
329            }
330
331            public void componentShown(ComponentEvent e)
332            {
333            }
334        });
335    }
336
337    /*
338     * Creates the drop down menu that appears when a right click is performed
339     * on the table.
340     */
341    private void initializeDropDownMenu()
342    {
343        Box menu = new Box(BoxLayout.Y_AXIS);
344        initializeDropDownLabels();
345        addLabelsToBox(menu);
346
347        // Sets the highlighted background color, note that it does not become
348        // "Highlighted" until opaque(true) is called
349        setMenuHighlightedBackground(Color.BLUE);
350
351        assignedIncidentsMenu = new JFrame();
352        assignedIncidentsMenu.getContentPane().add(menu);
353        assignedIncidentsMenu.setPreferredSize(DROP_DOWN_MENU_DIMENSIONS);
354        assignedIncidentsMenu.setUndecorated(true);
355        assignedIncidentsMenu.pack();
356        assignedIncidentsMenu.setVisible(false);
357    }
358
359    /*
360     * Sets the text and size and adds a listener to each activated label.
361     */
362    private void initializeDropDownLabels()
363    {
364        for (int i = 0; i < dropDownLabels.length; i++)
365        {
366            dropDownLabels[i] = new JLabel(LABEL_SPACING + LABELS[i]);
367            dropDownLabels[i].setMaximumSize(DROP_DOWN_MENU_LABEL_DIMENSIONS);
368            dropDownLabels[i].setForeground(Color.GRAY);
369        }
370        dropDownLabels[3].setForeground(Color.BLACK);
371        addMouseListenersToLabel(dropDownLabels[3]);
372        dropDownLabels[10].setForeground(Color.BLACK);
373        addMouseListenersToLabel(dropDownLabels[10]);
374    }
375
376    /*
377     * Add the labels to the box in order with separators and spacings in
378     * between.
379     */
380    private void addLabelsToBox(Box menu)
381    {
382        menu.add(dropDownLabels[0]);
383        menu.add(dropDownLabels[1]);
384        menu.add(dropDownLabels[2]);
385
386        menu.add(Box.createVerticalStrut(5));
387        menu.add(new JSeparator());
388        menu.add(Box.createVerticalStrut(5));
389
390        menu.add(dropDownLabels[3]);
391        menu.add(dropDownLabels[4]);
392        menu.add(dropDownLabels[5]);
393        menu.add(dropDownLabels[6]);
394        menu.add(dropDownLabels[7]);
395
396        menu.add(Box.createVerticalStrut(5));
397        menu.add(new JSeparator());
398        menu.add(Box.createVerticalStrut(5));
399
400        menu.add(dropDownLabels[8]);
401        menu.add(dropDownLabels[9]);
402        menu.add(dropDownLabels[10]);
403
404        menu.add(Box.createVerticalStrut(5));
405        menu.add(new JSeparator());
406        menu.add(Box.createVerticalStrut(5));
407
408        menu.add(dropDownLabels[11]);
409        menu.add(dropDownLabels[12]);
410        menu.add(dropDownLabels[13]);
411
412        menu.add(Box.createVerticalStrut(5));
413    }
414
415    /*
416     * Sets the highlighted color(when the mouse is over it) of the JLabels.
417     * Note: the color is not shown until .setOpaque(true) is called.
418     *
419     * @param color the highlighted color
420     */
421    public void setMenuHighlightedBackground(Color color)
422    {
423        for (int i = 0; i < dropDownLabels.length; i++)
424        {
425            dropDownLabels[i].setBackground(color);
426        }
427    }
428
429    /*
430     * Sets all JLabels to not display a highlighted background
431     */
432    public void unSelectAllLabels()
433    {
434        for (int i = 0; i < dropDownLabels.length; i++)
435        {
436            dropDownLabels[i].setOpaque(false);
437        }
438    }
439
440    /*
441     * Sets the label to have a highlighted background.
442     *
443     * @param label the label that is selected/highlighted
444     */
445    public void selectLabel(Object label)
446    {
447        ((JLabel) label).setOpaque(true);
448    }
449
450    /*
451     * Performs the label action depending on which label was clicked.
452     */
453    public void performLabelAction(Object label)
454    {
455        if (label.equals(dropDownLabels[0]))
456        {// Add Resources
457        }
458        else if (label.equals(dropDownLabels[1]))
459        {// Greater Alarm
460        }
461        else if (label.equals(dropDownLabels[2]))
462        {// Reconfigure
463        }
464        else if (label.equals(dropDownLabels[3]))
465        {// Open
466            int idColumn = 0;
467            int selectedRow = assignedIncidentsTable.getSelectedRow();
468            try
469            {
470                int selectedValue = (Integer) assignedIncidentsTable.getValueAt(selectedRow, idColumn);
471                ScreenManager.openIncidentViewer(selectedValue);
472            } catch (IndexOutOfBoundsException ex)
473            {
474                ex.printStackTrace();
475            }
476        }
477        else if (label.equals(dropDownLabels[4]))
478        {// Recall Incident
479        }
480        else if (label.equals(dropDownLabels[5]))
481        {// Cancel
482        }
483        else if (label.equals(dropDownLabels[6]))
484        {// Reassign
485        }
486        else if (label.equals(dropDownLabels[7]))
487        {// Link append
488        }
489        else if (label.equals(dropDownLabels[8]))
490        {// Map
491        }
492        else if (label.equals(dropDownLabels[9]))
493        {// Recall Linked Incidents
494        }
495        else if (label.equals(dropDownLabels[10]))
496        {// Read Notes
497            int idColumn = 0;
498            ScreenManager.openIncidentViewer((Integer) assignedIncidentsTable
499                    .getValueAt(assignedIncidentsTable.getSelectedRow(),
500                    idColumn));
501        }
502        else if (label.equals(dropDownLabels[11]))
503        {// Page
504        }
505        else if (label.equals(dropDownLabels[12]))
506        {// Mail
507        }
508        else if (label.equals(dropDownLabels[13]))
509        {// Fax
510        }
511    }
512
513    /*
514     * Factory method. Adds a mouse listeners to the label. The
515     * MouseMotionListener detects the mouse's location to highlight the label.
516     * The MouseListener detects for clicks and performs the action of the label
517     * designates.
518     */
519    public void addMouseListenersToLabel(JLabel label)
520    {
521        label.addMouseMotionListener(new MouseMotionListener()
522        {
523            public void mouseDragged(MouseEvent e)
524            {
525            }
526
527            public void mouseMoved(MouseEvent e)
528            {
529                unSelectAllLabels();
530                selectLabel(e.getSource());
531                assignedIncidentsMenu.revalidate();
532                assignedIncidentsMenu.repaint();
533            }
534        });
535        label.addMouseListener(new MouseListener()
536        {
537            public void mouseClicked(MouseEvent e)
538            {
539                performLabelAction(e.getSource());
540                unSelectAllLabels();
541                assignedIncidentsMenu.revalidate();
542                assignedIncidentsMenu.repaint();
543                assignedIncidentsMenu.setVisible(false);
544            }
545
546            public void mouseEntered(MouseEvent e)
547            {
548            }
549
550            public void mouseExited(MouseEvent e)
551            {
552            }
553
554            public void mousePressed(MouseEvent e)
555            {
556            }
557
558            public void mouseReleased(MouseEvent e)
559            {
560            }
561        });
562    }
563
564    /*
565     * Displays the menu where the right click occurred.
566     */
567    public void openDropDownMenu(MouseEvent e)
568    {
569        assignedIncidentsMenu.setLocation(e.getX() + this.getX(), e.getY()
570                + this.getY());
571        assignedIncidentsMenu.setVisible(true);
572    }
573
574    /*
575     * Hides the menu.
576     */
577    public void closeDropDownMenu()
578    {
579        unSelectAllLabels();
580        assignedIncidentsMenu.revalidate();
581        assignedIncidentsMenu.repaint();
582        assignedIncidentsMenu.setVisible(false);
583    }
584
585    /*
586     * Refreshes the data in the table by updating all data and repainting the
587     * screen. It saves user preferences(like column sizes, selected row, sorted preferences)
588     * and applies them to the updated model it receives from the server.
589     */
590    public void refreshTable()
591    {
592
593        if (assignedIncidentsTable.getTableHeader().getResizingColumn() == null)
594        {//only update info if resize not in progress
595            try
596            {
597                int index = assignedIncidentsTable.getSelectedRow();
598                int[] columnWidths = new int[20];
599                List<? extends SortKey> keys = assignedIncidentsTable.getRowSorter().getSortKeys();
600                for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
601                {
602                    columnWidths[i] = assignedIncidentsTable.getColumnModel().getColumn(i).getWidth();
603                }
604
605                assignedIncidentsTable.setModel(ScreenManager.theCoordinator.getCadDataTable(CADDataEnums.TABLE.ASSIGNED_INCIDENTS));
606
607                for (int i = 0; i < assignedIncidentsTable.getColumnCount(); i++)
608                {
609                    assignedIncidentsTable.getColumnModel().getColumn(i).setPreferredWidth(columnWidths[i]);
610                }
611                assignedIncidentsTable.getRowSorter().setSortKeys(keys);
612                assignedIncidentsTable.getSelectionModel().setSelectionInterval(index, index);
613            } catch (RemoteException e)
614            {
615                e.printStackTrace();
616            }
617            revalidate();
618            repaint();
619        }
620    }
621
622    /*
623     * Makes screen visible.
624     */
625    public void open()
626    {
627        setVisible(true);
628    }
629
630    /*
631     * Hides screen.
632     */
633    public void close()
634    {
635        setVisible(false);
636    }
637}
Note: See TracBrowser for help on using the repository browser.