]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/function/FullRangeDetails.java
Version 9, February 2010
[GpsPrune.git] / tim / prune / function / FullRangeDetails.java
diff --git a/tim/prune/function/FullRangeDetails.java b/tim/prune/function/FullRangeDetails.java
new file mode 100644 (file)
index 0000000..ed86ef9
--- /dev/null
@@ -0,0 +1,219 @@
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.NumberFormat;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.data.Altitude;
+import tim.prune.data.Distance;
+import tim.prune.data.Selection;
+import tim.prune.gui.DisplayUtils;
+
+/**
+ * Class to show the full range details in a separate popup
+ */
+public class FullRangeDetails extends GenericFunction
+{
+       /** Dialog */
+       private JDialog _dialog = null;
+       /** Label for number of segments */
+       private JLabel _numSegsLabel = null;
+       /** Label for pace */
+       private JLabel _paceLabel = null;
+       /** Label for gradient */
+       private JLabel _gradientLabel = null;
+       /** Moving distance, speed */
+       private JLabel _movingDistanceLabel = null, _aveMovingSpeedLabel = null;
+       /** Number formatter for one decimal place */
+       private static final NumberFormat FORMAT_ONE_DP = NumberFormat.getNumberInstance();
+       /** Flexible number formatter for different decimal places */
+       private NumberFormat _distanceFormatter = NumberFormat.getInstance();
+
+       /**
+        * Constructor
+        * @param inApp App object
+        */
+       public FullRangeDetails(App inApp)
+       {
+               super(inApp);
+               FORMAT_ONE_DP.setMaximumFractionDigits(1);
+               FORMAT_ONE_DP.setMinimumFractionDigits(1);
+       }
+
+       /** Get the name key */
+       public String getNameKey() {
+               return "function.fullrangedetails";
+       }
+
+       /**
+        * Begin the function
+        */
+       public void begin()
+       {
+               if (_dialog == null)
+               {
+                       _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
+                       _dialog.setLocationRelativeTo(_parentFrame);
+                       _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+                       _dialog.getContentPane().add(makeDialogComponents());
+                       _dialog.pack();
+               }
+               updateDetails();
+               _dialog.setVisible(true);
+       }
+
+       /**
+        * Create dialog components
+        * @return Panel containing all gui elements in dialog
+        */
+       private Component makeDialogComponents()
+       {
+               JPanel dialogPanel = new JPanel();
+               dialogPanel.setLayout(new BorderLayout(5, 5));
+               // Label at top
+               JLabel topLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.intro"));
+               topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+               dialogPanel.add(topLabel, BorderLayout.NORTH);
+
+               // Details panel in middle
+               JPanel midPanel = new JPanel();
+               midPanel.setLayout(new GridLayout(0, 2, 6, 2));
+               midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
+               // Number of segments
+               JLabel segLabel = new JLabel(I18nManager.getText("details.range.numsegments") + ": ");
+               segLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(segLabel);
+               _numSegsLabel = new JLabel("100");
+               midPanel.add(_numSegsLabel);
+               // Pace
+               JLabel paceLabel = new JLabel(I18nManager.getText("details.range.pace") + ": ");
+               paceLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(paceLabel);
+               _paceLabel = new JLabel("8 min/km");
+               midPanel.add(_paceLabel);
+               // Gradient
+               JLabel gradientLabel = new JLabel(I18nManager.getText("details.range.gradient") + ": ");
+               gradientLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(gradientLabel);
+               _gradientLabel = new JLabel("10 %");
+               midPanel.add(_gradientLabel);
+               // Moving distance
+               JLabel movingDistLabel = new JLabel(I18nManager.getText("fieldname.movingdistance") + ": ");
+               movingDistLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(movingDistLabel);
+               _movingDistanceLabel = new JLabel("5 km");
+               midPanel.add(_movingDistanceLabel);
+               // Moving speed
+               JLabel movingSpeedLabel = new JLabel(I18nManager.getText("details.range.avemovingspeed") + ": ");
+               movingSpeedLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(movingSpeedLabel);
+               _aveMovingSpeedLabel = new JLabel("5 km/h");
+               midPanel.add(_aveMovingSpeedLabel);
+
+               dialogPanel.add(midPanel, BorderLayout.CENTER);
+               // button panel at bottom
+               JPanel buttonPanel = new JPanel();
+               buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+               JButton closeButton = new JButton(I18nManager.getText("button.close"));
+               closeButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e)
+                       {
+                               _dialog.dispose();
+                       }
+               });
+               buttonPanel.add(closeButton);
+               dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
+               return dialogPanel;
+       }
+
+
+       /**
+        * Update the labels with the current details
+        */
+       private void updateDetails()
+       {
+               Selection selection = _app.getTrackInfo().getSelection();
+               // Number of segments
+               _numSegsLabel.setText("" + selection.getNumSegments());
+               // Pace value
+               if (selection.getNumSeconds() > 0)
+               {
+                       boolean useMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS);
+                       Distance.Units distUnits = useMetric?Distance.Units.KILOMETRES:Distance.Units.MILES;
+                       String distUnitsStr = I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short");
+                       _paceLabel.setText(DisplayUtils.buildDurationString(
+                                       (long) (selection.getNumSeconds()/selection.getDistance(distUnits)))
+                               + " / " + distUnitsStr);
+               }
+               else {
+                       _paceLabel.setText("");
+               }
+               // Gradient
+               Altitude firstAlt = _app.getTrackInfo().getTrack().getPoint(selection.getStart()).getAltitude();
+               Altitude lastAlt = _app.getTrackInfo().getTrack().getPoint(selection.getEnd()).getAltitude();
+               double metreDist = selection.getDistance(Distance.Units.METRES);
+               if (firstAlt.isValid() && lastAlt.isValid() && metreDist > 0.0)
+               {
+                       // got an altitude and range
+                       int altDiffInMetres = lastAlt.getValue(Altitude.Format.METRES) - firstAlt.getValue(Altitude.Format.METRES);
+                       double gradient = altDiffInMetres * 100.0 / metreDist;
+                       _gradientLabel.setText(FORMAT_ONE_DP.format(gradient) + " %");
+               }
+               else {
+                       // no altitude given
+                       _gradientLabel.setText("");
+               }
+
+               // Show moving distance and average even when number of segments is 1
+               final boolean isMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS);
+               final Distance.Units distUnits = isMetric?Distance.Units.KILOMETRES:Distance.Units.MILES;
+               final String distUnitsStr = I18nManager.getText(isMetric?"units.kilometres.short":"units.miles.short");
+               final String speedUnitsStr = I18nManager.getText(isMetric?"units.kmh":"units.mph");
+               // Moving distance
+               _movingDistanceLabel.setText(roundedNumber(selection.getMovingDistance(distUnits)) + " " + distUnitsStr);
+               // Moving average speed
+               long numSecs = selection.getMovingSeconds();
+               if (numSecs > 0) {
+                       _aveMovingSpeedLabel.setText(roundedNumber(selection.getMovingDistance(distUnits)/numSecs*3600.0)
+                               + " " + speedUnitsStr);
+               }
+               else {
+                       _aveMovingSpeedLabel.setText("");
+               }
+       }
+
+       /**
+        * Format a number to a sensible precision
+        * @param inDist distance
+        * @return formatted String
+        */
+       private String roundedNumber(double inDist)
+       {
+               // Set precision of formatter
+               int numDigits = 0;
+               if (inDist < 1.0)
+                       numDigits = 3;
+               else if (inDist < 10.0)
+                       numDigits = 2;
+               else if (inDist < 100.0)
+                       numDigits = 1;
+               // set formatter
+               _distanceFormatter.setMaximumFractionDigits(numDigits);
+               _distanceFormatter.setMinimumFractionDigits(numDigits);
+               return _distanceFormatter.format(inDist);
+       }
+}