/* * Copyright to the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.examples.hospital.ui; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.data.time.FixedMillisecond; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.ui.RectangleInsets; import org.rioproject.examples.hospital.CalculablePatient; import org.rioproject.examples.hospital.Patient; import org.rioproject.servicecore.Service; import org.rioproject.watch.Calculable; import org.rioproject.watch.WatchDataSource; import javax.swing.*; import java.awt.*; import java.io.IOException; import java.rmi.RemoteException; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Displays patient stats. */ public class PatientStatsPanel extends JPanel { private TimeSeries pulseTimeSeries = new TimeSeries("Pulse", FixedMillisecond.class); private TimeSeries temperatureTimeSeries = new TimeSeries("Temperature", FixedMillisecond.class); private ScheduledExecutorService scheduler; private Service service; private CalculablePatient lastPulse; private Calculable lastTemperature; private static final long MINUTE=60*1000; private JLabel patientLabel; public PatientStatsPanel() { super(new BorderLayout(8, 8)); setBorder(BorderFactory.createEmptyBorder(2, 8, 8, 8)); patientLabel = new JLabel(getLabelText(null)); add(patientLabel, BorderLayout.NORTH); pulseTimeSeries.setMaximumItemAge(5*MINUTE); temperatureTimeSeries.setMaximumItemAge(5*MINUTE); TimeSeriesCollection pulseDataSet = new TimeSeriesCollection(pulseTimeSeries); TimeSeriesCollection temperatureDataSet = new TimeSeriesCollection(temperatureTimeSeries); JFreeChart pulseChart = createTimeSeriesChart(pulseDataSet, Color.RED); JFreeChart temperatureChart = createTimeSeriesChart(temperatureDataSet, Color.BLUE); JPanel chartPanel = new JPanel(new GridLayout(1, 2)); chartPanel.add(makeChartPanel(pulseChart)); chartPanel.add(makeChartPanel(temperatureChart)); add(chartPanel, BorderLayout.CENTER); scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(new FeederTask(), 0, 2, TimeUnit.SECONDS); } private String getLabelText(Patient p) { if(p==null) return "<html><body><h3>Patient Stats</h3></body></html>"; else return "<html><body><h3>Patient Stats for "+p.getPatientInfo().getName()+"</h3></body></html>"; } void setPatient(Patient p) { if(p==null) { pulseTimeSeries.clear(); temperatureTimeSeries.clear(); patientLabel.setText(getLabelText(p)); return; } patientLabel.setText(getLabelText(p)); service = (Service)p.getBed(); try { pulseTimeSeries.clear(); WatchDataSource pulse = service.fetch("pulse"); for(Calculable c : pulse.getCalculable()) { lastPulse = (CalculablePatient)c; pulseTimeSeries.addOrUpdate(new FixedMillisecond(c.getWhen()), c.getValue()); } } catch (RemoteException e) { e.printStackTrace(); } try { temperatureTimeSeries.clear(); WatchDataSource temperature = service.fetch("temperature"); for(Calculable c : temperature.getCalculable()) { lastTemperature = c; temperatureTimeSeries.add(new FixedMillisecond(c.getWhen()), c.getValue()); } } catch (RemoteException e) { e.printStackTrace(); } } void shutdown() { if(scheduler!=null) scheduler.shutdownNow(); scheduler = null; } private Service getService() { return service; } class FeederTask implements Runnable { public void run() { Service s = getService(); if(s!=null) { try { CalculablePatient c = checkAdd(s, "pulse", lastPulse); if(c!=null) { lastPulse = c; pulseTimeSeries.addOrUpdate(new FixedMillisecond(c.getWhen()), c.getValue()); } } catch (IOException e) { e.printStackTrace(); } try { Calculable c = checkAdd(s, "temperature", lastTemperature); if(c!=null) { lastTemperature = c; temperatureTimeSeries.addOrUpdate(new FixedMillisecond(c.getWhen()), c.getValue()); } } catch (RemoteException e) { e.printStackTrace(); } } } private CalculablePatient checkAdd(Service s, String watch, Calculable lastOne) throws RemoteException { WatchDataSource wds = s.fetch(watch); CalculablePatient c = (CalculablePatient)wds.getLastCalculable(); Date lastMeasurement = new Date(lastOne.getWhen()); Date currentMeasurement = new Date(c.getWhen()); return currentMeasurement.after(lastMeasurement)?c:null; } } private ChartPanel makeChartPanel(JFreeChart chart) { ChartPanel chartPanel = new ChartPanel(chart, true); chartPanel.setPreferredSize(new Dimension(300, 200)); return chartPanel; } private JFreeChart createTimeSeriesChart(TimeSeriesCollection dataSet, Color color) { JFreeChart chart = ChartFactory.createTimeSeriesChart( "", "", "", dataSet, true, true, false ); XYPlot plot = (XYPlot) chart.getPlot(); plot.getRenderer().setSeriesPaint(0, color); plot.setBackgroundPaint(Color.lightGray); plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinePaint(Color.white); plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0)); plot.setDomainCrosshairVisible(true); plot.setRangeCrosshairVisible(true); ValueAxis yAxis = plot.getRangeAxis(); yAxis.setRange(0, 150); ValueAxis xAxis = plot.getDomainAxis(); xAxis.setAutoRange(true); xAxis.setFixedAutoRange(5*MINUTE); return chart; } }