package com.dreikraft.axbo.gui; import com.dreikraft.axbo.Axbo; import com.dreikraft.events.ApplicationEventDispatcher; import com.dreikraft.events.ApplicationMessageEvent; import com.dreikraft.axbo.timeseries.KeyTimeSeries; import com.dreikraft.axbo.data.SleepData; import com.dreikraft.axbo.events.DiagramCopy; import com.dreikraft.axbo.events.DiagramPrint; import com.dreikraft.axbo.events.DiagramSaveAsPNG; import com.dreikraft.axbo.events.DiagramClose; import com.dreikraft.axbo.model.ChartType; import com.dreikraft.axbo.timeseries.TimeSeriesUtil; import com.dreikraft.axbo.util.BundleUtil; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.geom.Rectangle2D; import java.awt.print.Book; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.io.IOException; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import javax.swing.JPanel; import javax.swing.RepaintManager; import javax.swing.border.TitledBorder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.StandardChartTheme; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.labels.StandardXYToolTipGenerator; import org.jfree.chart.labels.XYToolTipGenerator; import org.jfree.chart.plot.CombinedDomainXYPlot; import org.jfree.chart.plot.IntervalMarker; import org.jfree.chart.plot.Marker; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.SeriesRenderingOrder; import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.LookupPaintScale; import org.jfree.chart.renderer.xy.StandardXYBarPainter; import org.jfree.chart.renderer.xy.XYBarRenderer; import org.jfree.chart.renderer.xy.XYBlockRenderer; import org.jfree.data.Range; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.time.TimeSeriesDataItem; import org.jfree.data.xy.IntervalXYDataset; import org.jfree.ui.Align; import org.jfree.ui.Layer; import org.jfree.ui.RectangleAnchor; import org.jfree.ui.RectangleInsets; /** * DataFrame * * @author jan.illetschko@3kraft.com */ public class DataFrame extends JPanel implements Printable { public static final Log log = LogFactory.getLog(DataFrame.class); public static final Color CHART_BG_COLOR = new Color(0, 0, 0, 0); public static final Color AXIS_COLOR = new Color(0x7D, 0x7D, 0x7D, 0xFF); public static final Color GRID_COLOR = new Color(0x7D, 0x7D, 0x7D, 0xFF); public static final Color BAR_COLOR = new Color(255, 212, 107, 255); public static final Color BAR_COLOR2 = new Color(155, 112, 7, 255); public static final GradientPaint BAR_PAINT = new GradientPaint(0f, 0f, BAR_COLOR, 0f, 0f, BAR_COLOR2); public static final Color SLEEP_MARKER_PAINT = new Color(0xF0, 0x00, 0XFF, 0xFF); public static final Color WAKE_PAINT = new Color(0x10, 0xCE, 0x15, 0xFF); public static final Color SNOOZE_PAINT = new Color(0x00, 0xFF, 0xFF, 0xFF); public static final Color WAKE_INTERVALL_PAINT = new Color(0x9D, 0x84, 0x47, 0x40); public static final Color WAKE_INTERVALL_END_PAINT = new Color(0x9D, 0x84, 0x47, 0xFF); public static final Color SLEEP_DURATION_PAINT = new Color(0x9E, 0x9E, 0x9E, 0xFF); public static final Color KEY_PAINT = new Color(0x7D, 0x9B, 0xFF, 0xFF); public static final Stroke MARKER_STROKE = new BasicStroke(1.5f); public static final Color MOVEMENTS__HIGH_PAINT = Color.RED; public static final Color MOVEMENTS_MEDIUM_PAINT = Color.ORANGE; public static final Color MOVEMENTS_LOW_PAINT = Color.YELLOW; public static final Color MOVEMENTS_NONE_PAINT = Color.GREEN; public static final int INSET = 20; public static final int PRINT_FONT_SIZE = 8; private ChartPanel chartPanel; private SleepData sleepData; public void init() { initComponents(); } /** * Creates a new data chart from the sleep data. The chart is a combination of * a bar chart and a moving average distribution plot. * * @param sleepData the movement data of one sleep */ public void createChartPanel(final SleepData sleepData) { this.sleepData = sleepData; // set border title ((TitledBorder) getBorder()).setTitle(getTitle()); // create the chart final JFreeChart chart = createChart(ChartType.valueOf(Axbo .getApplicationPreferences().get(Axbo.CHART_TYPE_PREF, ChartType.BAR .name()))); // create a new chart panel if (chartPanel != null) { pnlChart.removeAll(); } chartPanel = new ChartPanel(chart, true); chartPanel.setBorder(null); chartPanel.setRangeZoomable(false); chartPanel.setPopupMenu(chartPanelPopupMenu); chartPanel.setMaximumDrawHeight(2000); chartPanel.setMaximumDrawWidth(2000); chartPanel.setMinimumDrawWidth(10); chartPanel.setMinimumDrawHeight(10); pnlChart.add(chartPanel); } /** * Creates a new chart from sleep data. * * @param chartType the requested chart type * @return a new chart instance */ private JFreeChart createChart(final ChartType chartType) { // set domain axis final DateAxis dateAxis = new DateAxis(); dateAxis.setTickLabelPaint(AXIS_COLOR); final Date startTime = sleepData.calculateSleepStart(); final Date wakeIntervalStart = sleepData.getWakeIntervalStart(); final Date wakeIntervalEnd = sleepData.calculateWakeIntervalEnd(); final Date wakeupTime = sleepData.getWakeupTime(); final KeyTimeSeries keyTimeSeries = TimeSeriesUtil.createKeyDataset(sleepData, BundleUtil.getMessage("chart.keyseries.label")); final KeyTimeSeries snoozeTimeSeries = TimeSeriesUtil.createSnoozeDataset(sleepData, BundleUtil.getMessage("chart.snoozeseries.label")); final IntervalXYDataset dataset = TimeSeriesUtil.createDataset(sleepData, BundleUtil.getMessage("chart.timeseries.label")); // create a data plot XYPlot plot = null; if (chartType.equals(ChartType.BAR)) { // create movement plot plot = createMovementsPlot(dataset, dateAxis); // add event markers addMarkers(plot, startTime, wakeIntervalStart, wakeIntervalEnd, keyTimeSeries, snoozeTimeSeries, wakeupTime); } else if (chartType.equals(ChartType.MOVING_AVG)) { // create moving average plot plot = createMovementDistributionPlot( TimeSeriesUtil.createMovingAverage( ((TimeSeriesCollection) dataset).getSeries(0), 1, 1), dateAxis, 4); // add event markers addMarkers(plot, startTime, wakeIntervalStart, wakeIntervalEnd, keyTimeSeries, snoozeTimeSeries, wakeupTime); } else { // create movement plot XYPlot barPlot = createMovementsPlot(dataset, dateAxis); addMarkers(barPlot, startTime, wakeIntervalStart, wakeIntervalEnd, keyTimeSeries, snoozeTimeSeries, wakeupTime); // create moving average plot XYPlot mvgAvgPlot = createMovementDistributionPlot( TimeSeriesUtil.createMovingAverage( ((TimeSeriesCollection) dataset).getSeries(0), 1, 1), dateAxis, 4); addMarkers(mvgAvgPlot, startTime, wakeIntervalStart, wakeIntervalEnd, keyTimeSeries, snoozeTimeSeries, wakeupTime); // create combined plot plot = createCombinedPlot(barPlot, mvgAvgPlot, dateAxis); } // create the chart final JFreeChart chart = new JFreeChart(plot); StandardChartTheme.createLegacyTheme().apply(chart); // customize the chart chart.setBackgroundPaint(CHART_BG_COLOR); chart.setBorderVisible(false); chart.setAntiAlias(false); chart.setTextAntiAlias(true); chart.removeLegend(); return chart; } /** * Creates a plot with both chart types combined into one chart. * * @param movementPlot a movement plot * @param movingAvgPlot a moving average plot of the same sleep date * @param dateAxis the date axis for both diagrams * @return a combined plot */ public CombinedDomainXYPlot createCombinedPlot(XYPlot movementPlot, XYPlot movingAvgPlot, final DateAxis dateAxis) { final CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(dateAxis); combinedPlot.setGap(1); combinedPlot.add(movementPlot, 12); combinedPlot.add(movingAvgPlot, 1); return combinedPlot; } /** * Creates the moving average plot from the movement data. * * @param timeSeries a moving average timeseries * @param dateAxis the date axis (x) * @param steps the number of shades of the chart * @return a moving average plot */ private XYPlot createMovementDistributionPlot(final TimeSeries timeSeries, final DateAxis dateAxis, int steps) { final NumberAxis numAxis = new NumberAxis(); numAxis.setVisible(false); numAxis.setFixedAutoRange(1); final XYBlockRenderer renderer = new XYBlockRenderer(); renderer.setBlockWidth(1000 * 60); renderer.setBlockAnchor(RectangleAnchor.BOTTOM_LEFT); renderer.setSeriesOutlinePaint(0, null); final double max = timeSeries.getMaxY() / 3; final LookupPaintScale paintScale = new LookupPaintScale(0, timeSeries.getMaxY(), BAR_COLOR2); int diffR = BAR_COLOR2.getRed() - BAR_COLOR.getRed(); int diffG = BAR_COLOR2.getGreen() - BAR_COLOR.getGreen(); int diffB = BAR_COLOR2.getBlue() - BAR_COLOR.getBlue(); for (int i = 1; i <= steps; i++) { paintScale.add(max / steps * i, new Color( BAR_COLOR2.getRed() - (diffR * i / steps), BAR_COLOR2.getGreen() - (diffG * i / steps), BAR_COLOR2.getBlue() - (diffB * i / steps))); } renderer.setPaintScale(paintScale); final XYPlot plot = new XYPlot( TimeSeriesUtil.createXYZTimeSeries(timeSeries), dateAxis, numAxis, renderer); plot.setBackgroundPaint(CHART_BG_COLOR); plot.setRangeGridlinesVisible(false); plot.setDomainGridlinesVisible(false); plot.setOutlineVisible(false); return plot; } /** * Creates a bar chart from the movement data. * * @param dataset the movement data set * @param dateAxis the date axis * @return a bar chart */ private XYPlot createMovementsPlot(final IntervalXYDataset dataset, final DateAxis dateAxis) { // connfigure value axis final NumberAxis valueAxis = new NumberAxis(); valueAxis.setStandardTickUnits(NumberAxis. createIntegerTickUnits()); valueAxis.setAxisLineVisible(false); valueAxis.setTickLabelsVisible(true); valueAxis.setTickMarksVisible(false); valueAxis.setTickLabelPaint(AXIS_COLOR); // movements renderer final XYBarRenderer renderer = new XYBarRenderer(); renderer.setBarPainter(new StandardXYBarPainter()); renderer.setShadowVisible(false); renderer.setDrawBarOutline(false); renderer.setSeriesPaint(0, BAR_PAINT); // tool tips final XYToolTipGenerator tooltipGenerator = StandardXYToolTipGenerator. getTimeSeriesInstance(); renderer.setBaseToolTipGenerator(tooltipGenerator); // customize the plot final XYPlot plot = new XYPlot(dataset, dateAxis, valueAxis, renderer); plot.setOrientation(PlotOrientation.VERTICAL); plot.setInsets(new RectangleInsets(5, 5, 5, 5)); plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0)); plot.setBackgroundPaint(CHART_BG_COLOR); plot.setBackgroundImageAlpha(0.05f); plot.setBackgroundImageAlignment(Align.CENTER); plot.setRangeGridlinesVisible(true); plot.setRangeGridlineStroke(new BasicStroke()); plot.setRangeGridlinePaint(GRID_COLOR); plot.setDomainGridlinesVisible(false); plot.setOutlineVisible(false); plot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD); return plot; } /** * Creates markers for various sleep events in xy plot. * * @param plot a XYPlot * @param sleepStart the calculated start time of the sleep displayed in the * chart or null * @param wakeIntervalStart the received start time of the wake interval or * null * @param wakeIntervalEnd the calculated wake interval or null * @param keys any key presses during the sleep interval as time series * @param snoozes snooze key presses during the wakeup interval * @param wakeupTime the calculated wakeup time or null */ private void addMarkers(final XYPlot plot, final Date sleepStart, final Date wakeIntervalStart, final Date wakeIntervalEnd, final KeyTimeSeries keys, final KeyTimeSeries snoozes, final Date wakeupTime) { // draw sleep start final Marker sleepStartMarker = new ValueMarker(sleepStart.getTime()); sleepStartMarker.setPaint(SLEEP_MARKER_PAINT); sleepStartMarker.setStroke(MARKER_STROKE); sleepStartMarker.setOutlinePaint(null); plot.addDomainMarker(sleepStartMarker, Layer.FOREGROUND); // wake intervall marker if (wakeIntervalStart != null) { final Marker wakeInterval = new IntervalMarker( wakeIntervalStart.getTime(), wakeIntervalEnd.getTime()); wakeInterval.setPaint(WAKE_INTERVALL_PAINT); wakeInterval.setOutlinePaint(null); plot.addDomainMarker(wakeInterval, Layer.BACKGROUND); } // sensor keys for (final Object series : keys.getItems()) { final TimeSeriesDataItem timeSeriesItem = (TimeSeriesDataItem) series; final Marker keyMarker = new ValueMarker(timeSeriesItem.getPeriod() .getMiddleMillisecond()); keyMarker.setPaint(KEY_PAINT); keyMarker.setOutlinePaint(null); keyMarker.setStroke(MARKER_STROKE); plot.addDomainMarker(keyMarker, Layer.FOREGROUND); } // snooze keys for (final Object series : snoozes.getItems()) { final TimeSeriesDataItem timeSeriesItem = (TimeSeriesDataItem) series; final Marker snoozeMarker = new ValueMarker(timeSeriesItem.getPeriod() .getMiddleMillisecond()); snoozeMarker.setPaint(SNOOZE_PAINT); snoozeMarker.setOutlinePaint(null); snoozeMarker.setStroke(MARKER_STROKE); plot.addDomainMarker(snoozeMarker, Layer.FOREGROUND); } // wakeup time if (wakeupTime != null) { final Marker wakeupMarker = new ValueMarker((double) wakeupTime.getTime()); wakeupMarker.setPaint(WAKE_PAINT); wakeupMarker.setOutlinePaint(null); wakeupMarker.setStroke(MARKER_STROKE); plot.addDomainMarker(wakeupMarker, Layer.FOREGROUND); } } private String getTitle() { // initialize view final StringBuffer titleBuf = new StringBuffer(); if (sleepData.getName() != null) { titleBuf.append(sleepData.getName()).append(" - "); } titleBuf.append(DateFormat.getDateInstance(DateFormat.MEDIUM). format(sleepData.calculateStartTime())); return titleBuf.toString(); } /** * Removes the PropertyChangeListeners from the TimeSeries objects. Otherwise * the Panels will not be removed from memory, because they are linked to the * SleepData objects in the SleepDataTableModel, which results in a nice * memory leak. */ public void close() { final Container parent = getParent(); parent.remove(this); } public void doCopy() { chartPanel.doCopy(); } public void doSaveAsPNG() { try { chartPanel.doSaveAs(); } catch (IOException ex) { log.error("failed to save chart as png", ex); } } public void zoom(final SleepData sleepData, final String fromText, final Integer duration, final Range range) { try { long sleepDataStart = sleepData.calculateStartTime().getTime(); long sleepDataEnd = sleepData.calculateEndTime().getTime(); int startHours = Integer.parseInt(fromText.split(":")[0]); int minutes = Integer.parseInt(fromText.split(":")[1]); if (startHours < 0 || startHours > 23 || minutes < 0 || minutes > 59) { throw new NumberFormatException(); } int startMinutes = startHours * 60 + minutes; long start = getZoomTimeMillis(sleepDataStart, startMinutes); long end = (1000L * duration * 60) + start; if (end < sleepDataStart) { start += 24 * 60 * 60 * 1000; end = start + (duration * 60 * 1000); } if (start > sleepDataEnd) { start -= 24 * 60 * 60 * 1000; end = start + (duration * 60 * 1000); } // perform the the zooming XYPlot plot = chartPanel.getChart().getXYPlot(); if (plot instanceof CombinedDomainXYPlot) { plot = (XYPlot) ((CombinedDomainXYPlot) plot).getSubplots().get(0); } if (plot.getRenderer() instanceof XYBarRenderer) { plot.getRangeAxis().setAutoRange(false); plot.getRangeAxis().setRange(range); } plot.getDomainAxis().setRange(start - 1000, end + 1000); } catch (NumberFormatException | NullPointerException ex) { log.warn("invalid zoom input", ex); chartPanel.restoreAutoBounds(); } } private long getZoomTimeMillis(final long sleepDataStart, final int timeOfDayInMinutes) { Calendar calRecorded = Calendar.getInstance(); calRecorded.setTime(new Date(sleepDataStart)); calRecorded.set(Calendar.HOUR_OF_DAY, 0); calRecorded.set(Calendar.MINUTE, 0); calRecorded.set(Calendar.SECOND, 0); calRecorded.set(Calendar.MILLISECOND, 0); long zoomTime = (1000L * timeOfDayInMinutes * 60) + calRecorded .getTimeInMillis(); return zoomTime; } @Override public int print(final Graphics graphics, final PageFormat pageFormat, final int pageIndex) throws PrinterException { if (graphics instanceof Graphics2D) { final Graphics2D printer = (Graphics2D) graphics; printer.setFont(new Font("SansSerif", Font.PLAIN, PRINT_FONT_SIZE)); int lineHeight = printer.getFontMetrics().getHeight() + 4; double x = pageFormat.getImageableX() + INSET; double y = pageFormat.getImageableY() + INSET; double w = pageFormat.getImageableWidth() - 2 * INSET; double h = pageFormat.getImageableHeight() - 2 * INSET; disableDoubleBuffering(chartPanel); createChart(ChartType.COMBINED).draw(printer, new Rectangle2D.Double(x, y + lineHeight * 3, w, h - lineHeight * 6)); enableDoubleBuffering(chartPanel); x = x + INSET; w = w - 2 * INSET; printer.setColor(GRID_COLOR); printer.drawString(getTitle(), (int) (x), (int) y + lineHeight * 2); printer.setColor(SLEEP_MARKER_PAINT); printer.drawString(lblSleepStart.getText() + " " + lblSleepStartValue. getText(), (int) (x), (int) (y + h - lineHeight * 2)); printer.setColor(GRID_COLOR); printer.drawString(lblLatency.getText() + " " + lblLatencyValue.getText(), (int) (x + w / 4 * 1), (int) (y + h - lineHeight * 2)); printer.setColor(GRID_COLOR); printer.drawString(lblDuration.getText() + " " + lblDurationValue .getText(), (int) (x + w / 4 * 2), (int) (y + h - lineHeight * 2)); printer.setColor(WAKE_PAINT); printer.drawString(lblWakeupTime.getText() + " " + lblWakeupTimeValue. getText(), (int) (x + w / 4 * 3), (int) (y + h - lineHeight * 2)); printer.setColor(WAKE_INTERVALL_END_PAINT); printer.drawString(lblLatest.getText() + " " + lblLatestValue.getText(), (int) (x), (int) (y + h - lineHeight * 1)); printer.setColor(GRID_COLOR); printer.drawString(lblTimeSaving.getText() + " " + lblTimeSavingValue. getText(), (int) (x + w / 4 * 1), (int) (y + h - lineHeight * 1)); printer.setColor(BAR_COLOR); printer.drawString(lblMovementsCount.getText() + " " + lblMovementsCountValue. getText(), (int) (x + w / 4 * 2), (int) (y + h - lineHeight * 1)); printer.setColor(GRID_COLOR); printer.drawString(lblMovementsAverage.getText() + " " + lblMovementsAverageValue. getText(), (int) (x + w / 4 * 3), (int) (y + h - lineHeight * 1)); if (lblCommentValue.getText() != null && lblCommentValue.getText().trim() .length() > 0) { printer.setColor(GRID_COLOR); printer.drawString(BundleUtil.getMessage("dataframe.label.comment") + " " + lblCommentValue.getText(), (int) (x + w / 4 * 0), (int) (y + h - lineHeight * 0)); } } return PAGE_EXISTS; } private static void disableDoubleBuffering(Component c) { RepaintManager currentManager = RepaintManager.currentManager(c); currentManager.setDoubleBufferingEnabled(false); } private static void enableDoubleBuffering(Component c) { RepaintManager currentManager = RepaintManager.currentManager(c); currentManager.setDoubleBufferingEnabled(true); } public void updateChart() { chartPanel.restoreAutoRangeBounds(); } public void updateStats(final SleepData sleepData) { // set title ((TitledBorder) getBorder()).setTitle(getTitle()); lblIdValue.setText(sleepData.getId()); lblNameValue.setText(sleepData.getName()); if (sleepData.getWakeIntervalStart() != null || sleepData.getWakeupTime() != null) { final Date sleepStart = sleepData.calculateSleepStart(); lblSleepStartValue.setText(String.format("%tR", sleepStart)); lblSleepStart.setVisible(true); lblSleepStartValue.setVisible(true); lblSpacerSleepStart.setVisible(true); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.setTime(new Date(sleepData.calculateLatency())); lblLatencyValue.setText(String.format("%tT", cal)); lblLatency.setVisible(true); lblLatencyValue.setVisible(true); lblSpacerLatency.setVisible(true); cal.setTime(new Date(sleepData.calculateDuration())); lblDurationValue.setText(String.format("%tT", cal)); lblDuration.setVisible(true); lblDurationValue.setVisible(true); lblSpacerDuration.setVisible(true); if (sleepData.getWakeupTime() != null) { lblWakeupTime.setVisible(true); lblWakeupTimeValue.setVisible(true); lblWakeupTimeValue.setText(String.format("%tR", sleepData.getWakeupTime())); lblSpacerWakeupTime.setVisible(true); } else { lblWakeupTime.setVisible(false); lblWakeupTimeValue.setVisible(false); lblSpacerWakeupTime.setVisible(false); } if (sleepData.calculateTimeSaving() != 0) { cal.setTime(new Date(sleepData.calculateTimeSaving())); lblTimeSavingValue.setText(String.format("%tR", cal)); lblTimeSaving.setVisible(true); lblTimeSavingValue.setVisible(true); lblSpacerTimeSaving.setVisible(true); } else { lblTimeSaving.setVisible(false); lblTimeSavingValue.setVisible(false); lblSpacerTimeSaving.setVisible(false); } if (sleepData.getWakeIntervalStart() != null) { long end = sleepData.calculateWakeIntervalEnd().getTime(); lblLatestValue.setText(String.format("%tR", end)); lblLatest.setVisible(true); lblLatestValue.setVisible(true); lblSpacerLatest.setVisible(true); } else { lblLatest.setVisible(false); lblLatestValue.setVisible(false); lblSpacerLatest.setVisible(false); } } else { lblSleepStart.setVisible(false); lblSleepStartValue.setVisible(false); lblSpacerSleepStart.setVisible(false); lblLatency.setVisible(false); lblLatencyValue.setVisible(false); lblSpacerLatency.setVisible(false); lblDuration.setVisible(false); lblDurationValue.setVisible(false); lblSpacerDuration.setVisible(false); lblLatest.setVisible(false); lblLatestValue.setVisible(false); lblSpacerLatest.setVisible(false); lblTimeSaving.setVisible(false); lblTimeSavingValue.setVisible(false); lblSpacerTimeSaving.setVisible(false); lblWakeupTime.setVisible(false); lblWakeupTimeValue.setVisible(false); lblSpacerWakeupTime.setVisible(false); } if (sleepData.isPowerNap()) { lblSleepStart.setText(BundleUtil.getMessage("label.powerNapStart")); lblTimeSaving.setVisible(false); lblTimeSavingValue.setVisible(false); lblSpacerTimeSaving.setVisible(false); lblMovementsAverage.setVisible(false); lblMovementsAverageValue.setVisible(false); lblLatency.setVisible(false); lblLatencyValue.setVisible(false); lblSpacerLatency.setVisible(false); lblSpacerMovementsCount.setVisible(false); } lblMovementsCountValue.setText(String.format("%d", sleepData.calculateMovementCount())); lblMovementsAverageValue.setText(String.format("%.1f", sleepData.calculateMovementsPerHour())); if (sleepData.getComment() == null || sleepData.getComment().trim().length() == 0) { lblComment.setVisible(false); lblCommentValue.setVisible(false); } else { lblComment.setVisible(true); lblCommentValue.setVisible(true); lblCommentValue.setText(sleepData.getComment()); } repaint(); } public SleepData getSleepData() { return sleepData; } /** * 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. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { chartPanelPopupMenu = new javax.swing.JPopupMenu(); pmniCopy = new javax.swing.JMenuItem(); pmniPrint = new javax.swing.JMenuItem(); pmniSaveAsPNG = new javax.swing.JMenuItem(); pnlChart = new javax.swing.JPanel(); pnlInfo = new javax.swing.JPanel(); pnlStats = new javax.swing.JPanel(); lblDuration = new javax.swing.JLabel(); lblDurationValue = new javax.swing.JLabel(); lblSpacerDuration = new javax.swing.JLabel(); lblSleepStart = new javax.swing.JLabel(); lblSleepStartValue = new javax.swing.JLabel(); lblSpacerSleepStart = new javax.swing.JLabel(); lblLatency = new javax.swing.JLabel(); lblLatencyValue = new javax.swing.JLabel(); lblSpacerLatency = new javax.swing.JLabel(); lblWakeupTime = new javax.swing.JLabel(); lblWakeupTimeValue = new javax.swing.JLabel(); lblSpacerWakeupTime = new javax.swing.JLabel(); lblLatest = new javax.swing.JLabel(); lblLatestValue = new javax.swing.JLabel(); lblSpacerLatest = new javax.swing.JLabel(); lblTimeSaving = new javax.swing.JLabel(); lblTimeSavingValue = new javax.swing.JLabel(); lblSpacerTimeSaving = new javax.swing.JLabel(); lblMovementsCount = new javax.swing.JLabel(); lblMovementsCountValue = new javax.swing.JLabel(); lblSpacerMovementsCount = new javax.swing.JLabel(); lblMovementsAverage = new javax.swing.JLabel(); lblMovementsAverageValue = new javax.swing.JLabel(); pnlComment = new javax.swing.JPanel(); lblComment = new javax.swing.JLabel(); lblCommentValue = new javax.swing.JLabel(); lblIdValue = new javax.swing.JLabel(); lblNameValue = new javax.swing.JLabel(); pnlClose = new javax.swing.JPanel(); btnClose = new javax.swing.JButton(); pmniCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/clipboard-16.png"))); // NOI18N java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("resources/default"); // NOI18N pmniCopy.setText(bundle.getString("chart.popup.copy")); // NOI18N pmniCopy.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pmniCopyActionPerformed(evt); } }); chartPanelPopupMenu.add(pmniCopy); pmniPrint.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/printer-16.png"))); // NOI18N pmniPrint.setText(bundle.getString("chart.popup.print")); // NOI18N pmniPrint.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pmniPrintActionPerformed(evt); } }); chartPanelPopupMenu.add(pmniPrint); pmniSaveAsPNG.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/desktop-16.png"))); // NOI18N pmniSaveAsPNG.setText(bundle.getString("chart.popup.save")); // NOI18N pmniSaveAsPNG.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pmniSaveAsPNGActionPerformed(evt); } }); chartPanelPopupMenu.add(pmniSaveAsPNG); setBorder(javax.swing.BorderFactory.createTitledBorder("")); setLayout(new java.awt.BorderLayout()); pnlChart.setMaximumSize(new java.awt.Dimension(10, 10)); pnlChart.setLayout(new java.awt.BorderLayout()); add(pnlChart, java.awt.BorderLayout.CENTER); pnlInfo.setLayout(new java.awt.BorderLayout()); pnlStats.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 2, 0)); lblDuration.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblDuration.setForeground(SLEEP_DURATION_PAINT); lblDuration.setText(bundle.getString("label.sleepDuration")); // NOI18N pnlStats.add(lblDuration); lblDurationValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblDurationValue.setForeground(SLEEP_DURATION_PAINT); lblDurationValue.setText("--:--:--"); pnlStats.add(lblDurationValue); lblSpacerDuration.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerDuration.setForeground(AXIS_COLOR); lblSpacerDuration.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerDuration.setText("|"); lblSpacerDuration.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerDuration.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerDuration.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerDuration); lblSleepStart.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSleepStart.setForeground(SLEEP_MARKER_PAINT); lblSleepStart.setText(bundle.getString("label.sleepStart")); // NOI18N pnlStats.add(lblSleepStart); lblSleepStartValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSleepStartValue.setForeground(SLEEP_MARKER_PAINT); lblSleepStartValue.setText("--:--"); pnlStats.add(lblSleepStartValue); lblSpacerSleepStart.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerSleepStart.setForeground(new java.awt.Color(174, 173, 173)); lblSpacerSleepStart.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerSleepStart.setText("|"); lblSpacerSleepStart.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerSleepStart.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerSleepStart.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerSleepStart); lblLatency.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblLatency.setForeground(AXIS_COLOR); lblLatency.setText(bundle.getString("dataFrame.label.latency")); // NOI18N lblLatency.setToolTipText(""); pnlStats.add(lblLatency); lblLatencyValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblLatencyValue.setForeground(AXIS_COLOR); lblLatencyValue.setText("--:--"); pnlStats.add(lblLatencyValue); lblSpacerLatency.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerLatency.setForeground(AXIS_COLOR); lblSpacerLatency.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerLatency.setText("|"); lblSpacerLatency.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerLatency.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerLatency.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerLatency); lblWakeupTime.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblWakeupTime.setForeground(WAKE_PAINT); lblWakeupTime.setText(bundle.getString("label.wakeupTime")); // NOI18N pnlStats.add(lblWakeupTime); lblWakeupTimeValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblWakeupTimeValue.setForeground(WAKE_PAINT); lblWakeupTimeValue.setText("--:--"); pnlStats.add(lblWakeupTimeValue); lblSpacerWakeupTime.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerWakeupTime.setForeground(AXIS_COLOR); lblSpacerWakeupTime.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerWakeupTime.setText("|"); lblSpacerWakeupTime.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerWakeupTime.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerWakeupTime.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerWakeupTime); lblLatest.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblLatest.setForeground(WAKE_INTERVALL_END_PAINT); lblLatest.setText(bundle.getString("label.latest")); // NOI18N pnlStats.add(lblLatest); lblLatestValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblLatestValue.setForeground(WAKE_INTERVALL_END_PAINT); lblLatestValue.setText("--:--"); pnlStats.add(lblLatestValue); lblSpacerLatest.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerLatest.setForeground(AXIS_COLOR); lblSpacerLatest.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerLatest.setText("|"); lblSpacerLatest.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerLatest.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerLatest.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerLatest); lblTimeSaving.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblTimeSaving.setForeground(WAKE_PAINT); lblTimeSaving.setText(bundle.getString("label.timeSaving")); // NOI18N pnlStats.add(lblTimeSaving); lblTimeSavingValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblTimeSavingValue.setForeground(WAKE_PAINT); lblTimeSavingValue.setText("--:--"); pnlStats.add(lblTimeSavingValue); lblSpacerTimeSaving.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerTimeSaving.setForeground(AXIS_COLOR); lblSpacerTimeSaving.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerTimeSaving.setText("|"); lblSpacerTimeSaving.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerTimeSaving.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerTimeSaving.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerTimeSaving); lblMovementsCount.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblMovementsCount.setForeground(BAR_COLOR); lblMovementsCount.setText(bundle.getString("dataFrame.label.movementsCount")); // NOI18N pnlStats.add(lblMovementsCount); lblMovementsCountValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblMovementsCountValue.setForeground(BAR_COLOR); lblMovementsCountValue.setText("-"); pnlStats.add(lblMovementsCountValue); lblSpacerMovementsCount.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblSpacerMovementsCount.setForeground(AXIS_COLOR); lblSpacerMovementsCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lblSpacerMovementsCount.setText("|"); lblSpacerMovementsCount.setMaximumSize(new java.awt.Dimension(14, 14)); lblSpacerMovementsCount.setMinimumSize(new java.awt.Dimension(14, 14)); lblSpacerMovementsCount.setPreferredSize(new java.awt.Dimension(14, 14)); pnlStats.add(lblSpacerMovementsCount); lblMovementsAverage.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblMovementsAverage.setForeground(new java.awt.Color(174, 173, 173)); lblMovementsAverage.setText(bundle.getString("dataFrame.label.movementsAverage")); // NOI18N pnlStats.add(lblMovementsAverage); lblMovementsAverageValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblMovementsAverageValue.setForeground(new java.awt.Color(174, 173, 173)); lblMovementsAverageValue.setText("-"); pnlStats.add(lblMovementsAverageValue); pnlInfo.add(pnlStats, java.awt.BorderLayout.CENTER); pnlComment.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 2, 0)); lblComment.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblComment.setForeground(AXIS_COLOR); lblComment.setText(bundle.getString("dataframe.label.comment")); // NOI18N pnlComment.add(lblComment); lblCommentValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblCommentValue.setForeground(new java.awt.Color(174, 173, 173)); pnlComment.add(lblCommentValue); lblIdValue.setVisible(false); lblIdValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblIdValue.setForeground(AXIS_COLOR); lblIdValue.setText(bundle.getString("label.id")); // NOI18N pnlComment.add(lblIdValue); lblNameValue.setVisible(false); lblNameValue.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lblNameValue.setForeground(AXIS_COLOR); lblNameValue.setText(bundle.getString("label.name")); // NOI18N pnlComment.add(lblNameValue); pnlInfo.add(pnlComment, java.awt.BorderLayout.SOUTH); add(pnlInfo, java.awt.BorderLayout.SOUTH); pnlClose.setPreferredSize(new java.awt.Dimension(16, 16)); pnlClose.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); btnClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/button-cross-16.png"))); // NOI18N btnClose.setBorderPainted(false); btnClose.setContentAreaFilled(false); btnClose.setFocusable(false); btnClose.setIconTextGap(2); btnClose.setMultiClickThreshhold(1000L); btnClose.setPreferredSize(new java.awt.Dimension(16, 16)); btnClose.setRequestFocusEnabled(false); btnClose.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnCloseActionPerformed(evt); } }); pnlClose.add(btnClose); add(pnlClose, java.awt.BorderLayout.EAST); }// </editor-fold>//GEN-END:initComponents private void pmniCopyActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_pmniCopyActionPerformed {//GEN-HEADEREND:event_pmniCopyActionPerformed ApplicationEventDispatcher.getInstance().dispatchGUIEvent(new DiagramCopy( this)); }//GEN-LAST:event_pmniCopyActionPerformed private void pmniPrintActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_pmniPrintActionPerformed {//GEN-HEADEREND:event_pmniPrintActionPerformed final PrinterJob job = PrinterJob.getPrinterJob(); if (job.printDialog()) { final Book book = new Book(); job.setPageable(book); job.setJobName(getSleepData().getSleepDataFilename()); ApplicationEventDispatcher.getInstance().dispatchEvent(new DiagramPrint( this, job, book)); try { job.print(); } catch (PrinterException ex) { final String msg = BundleUtil.getErrorMessage( "globalError.printingFailed"); log.error(msg, ex); ApplicationEventDispatcher.getInstance().dispatchGUIEvent( new ApplicationMessageEvent( this, msg, true)); } } }//GEN-LAST:event_pmniPrintActionPerformed private void pmniSaveAsPNGActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_pmniSaveAsPNGActionPerformed {//GEN-HEADEREND:event_pmniSaveAsPNGActionPerformed ApplicationEventDispatcher.getInstance().dispatchGUIEvent( new DiagramSaveAsPNG( this)); }//GEN-LAST:event_pmniSaveAsPNGActionPerformed private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed {//GEN-HEADEREND:event_btnCloseActionPerformed ApplicationEventDispatcher.getInstance().dispatchGUIEvent(new DiagramClose( this, this)); }//GEN-LAST:event_btnCloseActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnClose; private javax.swing.JPopupMenu chartPanelPopupMenu; private javax.swing.JLabel lblComment; private javax.swing.JLabel lblCommentValue; private javax.swing.JLabel lblDuration; private javax.swing.JLabel lblDurationValue; private javax.swing.JLabel lblIdValue; private javax.swing.JLabel lblLatency; private javax.swing.JLabel lblLatencyValue; private javax.swing.JLabel lblLatest; private javax.swing.JLabel lblLatestValue; private javax.swing.JLabel lblMovementsAverage; private javax.swing.JLabel lblMovementsAverageValue; private javax.swing.JLabel lblMovementsCount; private javax.swing.JLabel lblMovementsCountValue; private javax.swing.JLabel lblNameValue; private javax.swing.JLabel lblSleepStart; private javax.swing.JLabel lblSleepStartValue; private javax.swing.JLabel lblSpacerDuration; private javax.swing.JLabel lblSpacerLatency; private javax.swing.JLabel lblSpacerLatest; private javax.swing.JLabel lblSpacerMovementsCount; private javax.swing.JLabel lblSpacerSleepStart; private javax.swing.JLabel lblSpacerTimeSaving; private javax.swing.JLabel lblSpacerWakeupTime; private javax.swing.JLabel lblTimeSaving; private javax.swing.JLabel lblTimeSavingValue; private javax.swing.JLabel lblWakeupTime; private javax.swing.JLabel lblWakeupTimeValue; private javax.swing.JMenuItem pmniCopy; private javax.swing.JMenuItem pmniPrint; private javax.swing.JMenuItem pmniSaveAsPNG; private javax.swing.JPanel pnlChart; private javax.swing.JPanel pnlClose; private javax.swing.JPanel pnlComment; private javax.swing.JPanel pnlInfo; private javax.swing.JPanel pnlStats; // End of variables declaration//GEN-END:variables }