/* * To change this template, choose Tools | Templates and open the template in * the editor. */ /* * EmergencyMonitorPanel.java * * Created on Apr 28, 2011, 10:43:44 PM */ package com.wordpress.salaboy.emergencyservice.monitor; import com.wordpress.salaboy.context.tracking.ContextTrackingProvider; import com.wordpress.salaboy.context.tracking.ContextTrackingService; import com.wordpress.salaboy.emergencyservice.util.AlertsIconListRenderer; import com.wordpress.salaboy.messaging.MessageConsumerWorker; import com.wordpress.salaboy.messaging.MessageConsumerWorkerHandler; import com.wordpress.salaboy.messaging.MessageFactory; import com.wordpress.salaboy.model.messages.*; import com.wordpress.salaboy.model.messages.patient.HeartBeatMessage; import com.wordpress.salaboy.model.messages.patient.PatientMonitorAlertMessage; import com.wordpress.salaboy.model.persistence.PersistenceService; import com.wordpress.salaboy.model.persistence.PersistenceServiceProvider; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.UIManager; import org.hornetq.api.core.HornetQException; /** * * @author esteban * @author salaboy */ public class EmergencyMonitorPanel extends javax.swing.JPanel { private ImageIcon map; private MessageConsumerWorker gpsWorker; private MessageConsumerWorker heartBeatWorker; private MessageConsumerWorker patientMonitorAlertWorker; private MessageConsumerWorker vehicleHitsEmergencyWorker; private MessageConsumerWorker vehicleHitsHospitalWorker; private MessageConsumerWorker waterTankDecreaseWorker; private MessageConsumerWorker waterTankIncreaseWorker; private MessageConsumerWorker waterPumpTiltWorker; private MessageConsumerWorker outOfWaterWorker; private MessageConsumerWorker waterRefillWorker; private String callId; private List<String> alerts = new ArrayList<String>(); private Map<String, Boolean> vehicleHitEmergency = new HashMap<String, Boolean>(); private Map<String, Boolean> vehicleHitHospital = new HashMap<String, Boolean>(); private final PersistenceService persistenceService; private final ContextTrackingService trackingService; private Map<String, FireTruckStatusJPanel> fireTruckPanels = new HashMap<String, FireTruckStatusJPanel>(); private String emergencyId; /** Creates new form EmergencyMonitorPanel */ public EmergencyMonitorPanel(String callId) throws IOException { this.callId = callId; persistenceService = PersistenceServiceProvider.getPersistenceService(); trackingService = ContextTrackingProvider.getTrackingService(); emergencyId = trackingService.getEmergencyAttachedToCall(callId); initComponents(); loadMapImage(); startQueueListeners(); startPulseEmulator(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jPanel2 = new javax.swing.JPanel(); jScrollPane3 = new javax.swing.JScrollPane(); lstAlerts = new javax.swing.JList(); btnClear1 = new javax.swing.JButton(); jEmergencyTabbedPane = new javax.swing.JTabbedPane(); jPanel1 = new javax.swing.JPanel(); lblMap = new javax.swing.JLabel(); btnClear = new javax.swing.JButton(); jPanel3 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); auditLogjTextArea = new javax.swing.JTextArea(); jButton1 = new javax.swing.JButton(); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Alerts")); lstAlerts.setPreferredSize(new java.awt.Dimension(200, 0)); jScrollPane3.setViewportView(lstAlerts); lstAlerts.setCellRenderer(new AlertsIconListRenderer()); btnClear1.setText("Clear"); btnClear1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnClear1ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(btnClear1) .addComponent(jScrollPane3)) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnClear1)) ); jPanel1.setName("GPS"); // NOI18N jPanel1.setPreferredSize(new java.awt.Dimension(200, 200)); lblMap.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); lblMap.setPreferredSize(new java.awt.Dimension(305, 208)); btnClear.setText("Clear"); btnClear.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnClearActionPerformed(evt); } }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(51, 51, 51) .addComponent(lblMap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(161, 161, 161) .addComponent(btnClear))) .addContainerGap(108, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(lblMap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnClear) .addContainerGap()) ); jEmergencyTabbedPane.addTab("GPS", jPanel1); auditLogjTextArea.setColumns(20); auditLogjTextArea.setRows(5); jScrollPane1.setViewportView(auditLogjTextArea); auditLogjTextArea.setText(persistenceService.loadReport(this.callId).getReportString()); jButton1.setText("Refresh"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 464, Short.MAX_VALUE) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jButton1) .addContainerGap()) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 214, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jButton1) .addContainerGap()) ); jEmergencyTabbedPane.addTab("Live Report", jPanel3); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jEmergencyTabbedPane) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jEmergencyTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 291, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); }// </editor-fold>//GEN-END:initComponents private void btnClear1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClear1ActionPerformed this.alerts.clear(); DefaultListModel emptyModel = new DefaultListModel(); this.lstAlerts.setModel(emptyModel); }//GEN-LAST:event_btnClear1ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed System.out.println("Get REPORT FOR CALL ID="+this.callId); auditLogjTextArea.setText(persistenceService.loadReport(this.callId).getReportString()); }//GEN-LAST:event_jButton1ActionPerformed private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed this.loadMapImage(); }//GEN-LAST:event_btnClearActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextArea auditLogjTextArea; private javax.swing.JButton btnClear; private javax.swing.JButton btnClear1; private javax.swing.JButton jButton1; private javax.swing.JTabbedPane jEmergencyTabbedPane; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane3; private javax.swing.JLabel lblMap; private javax.swing.JList lstAlerts; // End of variables declaration//GEN-END:variables private void startQueueListeners() { gpsWorker = new MessageConsumerWorker("vehicleGPS" + callId, new MessageConsumerWorkerHandler<VehicleHitsCornerMessage>() { @Override public void handleMessage(VehicleHitsCornerMessage message) { System.out.println("CallId = "+callId +" -> Vehicle Id= "+message.getVehicleId()); if (message.getEmergencyId().equals(callId)) { paintVehiclePosition(message.getVehicleId(), message.getCornerX(), message.getCornerY()); } } }); heartBeatWorker = new MessageConsumerWorker("vehicleHeartBeat" + callId, new MessageConsumerWorkerHandler<HeartBeatMessage>() { @Override public void handleMessage(HeartBeatMessage message) { if (message.getEmergencyId().equals(emergencyId)) { processHeartBeat(message.getVehicleId(), message.getHeartBeatValue(), message.getTime()); } } }); patientMonitorAlertWorker = new MessageConsumerWorker("patientMonitorAlerts" + callId, new MessageConsumerWorkerHandler<PatientMonitorAlertMessage>() { @Override public void handleMessage(PatientMonitorAlertMessage message) { if (message.getEmergencyId().equals(emergencyId)) { addAlert(message.getVehicleId(), message.getTime(), message.getMessage()); } } }); //Vehicle Hits an Emergency Selected Worker vehicleHitsEmergencyWorker = new MessageConsumerWorker("vehicleHitsEmergencyMonitorPanel" + callId, new MessageConsumerWorkerHandler<VehicleHitsEmergencyMessage>() { @Override public void handleMessage(VehicleHitsEmergencyMessage vehicleHitsEmergencyMessage) { vehicleHitEmergency.put(vehicleHitsEmergencyMessage.getVehicleId(), Boolean.TRUE); //ProceduresMGMTService.getInstance().patientPickUpNotification(new PatientPickUpEvent(vehicleHitsEmergencyMessage.getCallId(), vehicleHitsEmergencyMessage.getVehicleId(), vehicleHitsEmergencyMessage.getTime())); } }); //Vehicle Hits an Hospital Selected Worker vehicleHitsHospitalWorker = new MessageConsumerWorker("vehicleHitsHospitalMonitorPanel" + callId, new MessageConsumerWorkerHandler<VehicleHitsHospitalMessage>() { @Override public void handleMessage(VehicleHitsHospitalMessage vehicleHitsHospitalMessage) { vehicleHitHospital.put(vehicleHitsHospitalMessage.getVehicleId(), Boolean.TRUE); cleanupPanel(); } }); waterTankDecreaseWorker = new MessageConsumerWorker("FTwaterDecreaseMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckDecreaseWaterLevelMessage>() { @Override public void handleMessage(FireTruckDecreaseWaterLevelMessage message) { if (message.getEmergencyId().equals(emergencyId)) { getFireTruckPanel(message.getVehicleId()).decreaseWaterLevel(); } } }); outOfWaterWorker = new MessageConsumerWorker("FTOutOfWaterMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckOutOfWaterMessage>() { @Override public void handleMessage(FireTruckOutOfWaterMessage message) { if (message.getEmergencyId().equals(emergencyId)) { getFireTruckPanel(message.getVehicleId()).fireTruckOutOfWater(); } } }); waterPumpTiltWorker = new MessageConsumerWorker("FTTiltMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckWaterPumpTiltMessage>() { @Override public void handleMessage(FireTruckWaterPumpTiltMessage message) { if (message.getEmergencyId().equals(emergencyId)) { getFireTruckPanel(message.getVehicleId()).waterPumpOverHeat(); } } }); waterRefillWorker = new MessageConsumerWorker("FTWaterRefillMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckWaterRefilledMessage>() { @Override public void handleMessage(FireTruckWaterRefilledMessage message) { if (message.getEmergencyId().equals(emergencyId)) { getFireTruckPanel(message.getVehicleId()).waterRefilled(); } } }); waterRefillWorker.start(); waterPumpTiltWorker.start(); outOfWaterWorker.start(); waterTankDecreaseWorker.start(); vehicleHitsEmergencyWorker.start(); vehicleHitsHospitalWorker.start(); patientMonitorAlertWorker.start(); gpsWorker.start(); heartBeatWorker.start(); } private Map<String, Point> lastVehiclePosition = new HashMap<String, Point>(); private Map<String, Color> vehicleColors = new HashMap<String, Color>(); private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN, Color.ORANGE, Color.PINK}; private void paintVehiclePosition(String vehicleId, int x, int y) { x = x / 2; y = y / 2; if (!lastVehiclePosition.containsKey(vehicleId)) { lastVehiclePosition.put(vehicleId, new Point(x, y)); vehicleColors.put(vehicleId, colors[vehicleColors.size()]); return; } Point lastPoint = lastVehiclePosition.get(vehicleId); Graphics graphics = lblMap.getGraphics(); graphics.setColor(vehicleColors.get(vehicleId)); graphics.drawLine(lastPoint.x, lastPoint.y, x, y); lastVehiclePosition.put(vehicleId, new Point(x, y)); } public void cleanupPanel() { stopPulseEmulator = true; if (waterRefillWorker != null) { waterRefillWorker.stopWorker(); } if (waterPumpTiltWorker != null) { waterPumpTiltWorker.stopWorker(); } if (outOfWaterWorker != null) { outOfWaterWorker.stopWorker(); } if (waterTankDecreaseWorker != null) { waterTankDecreaseWorker.stopWorker(); } if (vehicleHitsEmergencyWorker != null) { vehicleHitsEmergencyWorker.stopWorker(); } if (vehicleHitsHospitalWorker != null) { vehicleHitsHospitalWorker.stopWorker(); } if (patientMonitorAlertWorker != null) { patientMonitorAlertWorker.stopWorker(); } if (heartBeatWorker != null) { heartBeatWorker.stopWorker(); } if (gpsWorker != null) { gpsWorker.stopWorker(); } } private void loadMapImage() { map = new ImageIcon(this.getClass().getClassLoader().getResource("data/png/CityMap.png")); this.lblMap.setIcon(map); } private Map<String, HeartBeatWidget> heartBeatWidgets = new ConcurrentHashMap<String, HeartBeatWidget>(); private void processHeartBeat(String vehicleId, double heartBeatValue, Date time) { //only if the vehicle already hit the emergency, but it doesnt //hit the hospital yet; Boolean hitEmergency = vehicleHitEmergency.get(vehicleId); Boolean hitHospital = vehicleHitHospital.get(vehicleId); if (hitEmergency == null) { hitEmergency = false; } if (hitHospital == null) { hitHospital = false; } if (!hitEmergency) { return; } if (hitHospital) { return; } if (!heartBeatWidgets.containsKey(vehicleId)) { HeartBeatWidget widget = new HeartBeatWidget(); jEmergencyTabbedPane.add("Ambulance " + vehicleId, widget.getChartPanel()); jEmergencyTabbedPane.setSelectedComponent(widget.getChartPanel()); heartBeatWidgets.put(vehicleId, widget); } heartBeatWidgets.get(vehicleId).updateMonitorGraph(heartBeatValue); } public void addAlert(String vehicleId, Date time, String message) { alerts.add(0, vehicleId + " - " + message); DefaultListModel model = new DefaultListModel(); for (String alert : alerts) { model.addElement(alert); } lstAlerts.setModel(model); this.validate(); } private boolean stopPulseEmulator = false; private void startPulseEmulator() { new Thread() { @Override public void run() { while (!stopPulseEmulator) { try { for (String vehicleId : heartBeatWidgets.keySet()) { try { MessageFactory.sendMessage(new HeartBeatMessage(emergencyId, vehicleId, 0, new Date())); } catch (HornetQException ex) { Logger.getLogger(EmergencyMonitorPanel.class.getName()).log(Level.SEVERE, null, ex); } } Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(EmergencyMonitorPanel.class.getName()).log(Level.SEVERE, null, ex); } } } }.start(); } private FireTruckStatusJPanel getFireTruckPanel(String vehicleId){ if(fireTruckPanels.get(vehicleId) == null){ FireTruckStatusJPanel fireTruckStatusJPanel = new FireTruckStatusJPanel(this, vehicleId); fireTruckPanels.put(vehicleId,fireTruckStatusJPanel); jEmergencyTabbedPane.add(fireTruckStatusJPanel); jEmergencyTabbedPane.setSelectedComponent(fireTruckStatusJPanel); } return fireTruckPanels.get(vehicleId); } }