altosui/telegps: Reduce CPU time needed for flight displays
authorKeith Packard <keithp@keithp.com>
Thu, 12 Jun 2014 21:12:08 +0000 (14:12 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 12 Jun 2014 21:12:08 +0000 (14:12 -0700)
Don't update displays which aren't shown; track hierarchy changes to
trigger display from most recent state data.

Don't update values which haven't changed; remember previous values
and compare with new before updating widget contents.

Signed-off-by: Keith Packard <keithp@keithp.com>
altosui/AltosAscent.java
altosui/AltosDescent.java
altosui/AltosFlightStatus.java
altosui/AltosIgnitor.java
altosui/AltosLanded.java
altosui/AltosPad.java
altosuilib/AltosInfoTable.java
altosuilib/AltosUIMapView.java
telegps/TeleGPSInfo.java
telegps/TeleGPSStatus.java

index fb05fe112438d85dc6ff24b2641be71b40dbc4d7..c3225709c21f651fd10423ecfbcef902698c9009 100644 (file)
 package altosui;
 
 import java.awt.*;
 package altosui;
 
 import java.awt.*;
+import java.awt.event.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
-public class AltosAscent extends JComponent implements AltosFlightDisplay {
+public class AltosAscent extends JComponent implements AltosFlightDisplay, HierarchyListener {
        GridBagLayout   layout;
        JLabel                  cur, max;
 
        GridBagLayout   layout;
        JLabel                  cur, max;
 
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
        public class AscentStatus implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
        public class AscentStatus implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
@@ -101,6 +105,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -176,6 +181,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -215,22 +221,21 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                }
 
                public void units_changed(boolean imperial_units) {
                }
 
                public void units_changed(boolean imperial_units) {
-                       show(v);
+                       show(v, max);
                }
 
                }
 
-               void show(double v) {
+               void show(double v, double max) {
                        this.v = v;
                        this.v = v;
+                       this.max = max;
                        if (v == AltosLib.MISSING) {
                                value.setText("Missing");
                        } else {
                                value.setText(units.show(8, v));
                        if (v == AltosLib.MISSING) {
                                value.setText("Missing");
                        } else {
                                value.setText(units.show(8, v));
-                               if (v > max || max == AltosLib.MISSING)
-                                       max = v;
                        }
                        if (max == AltosLib.MISSING)
                                max_value.setText("Missing");
                        else
                        }
                        if (max == AltosLib.MISSING)
                                max_value.setText("Missing");
                        else
-                               max_value.setText(units.show(8, v));
+                               max_value.setText(units.show(8, max));
                }
 
                void hide() {
                }
 
                void hide() {
@@ -256,6 +261,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -266,6 +272,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                        add(value);
 
                        max_value = new JTextField(Altos.text_width);
                        add(value);
 
                        max_value = new JTextField(Altos.text_width);
+                       max_value.setEditable(false);
                        max_value.setFont(Altos.value_font);
                        max_value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 3; c.gridy = y;
                        max_value.setFont(Altos.value_font);
                        max_value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 3; c.gridy = y;
@@ -279,7 +286,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Height extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class Height extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.height());
+                       show(state.height(), state.max_height());
                }
                public Height (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Height");
                }
                public Height (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Height");
@@ -290,7 +297,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Speed extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class Speed extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.speed());
+                       show(state.speed(), state.max_speed());
                }
                public Speed (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Speed");
                }
                public Speed (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Speed");
@@ -301,7 +308,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Accel extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class Accel extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.acceleration());
+                       show(state.acceleration(), state.max_acceleration());
                }
                public Accel (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.accel, "Acceleration");
                }
                public Accel (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.accel, "Acceleration");
@@ -312,7 +319,7 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
 
        class Orient extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class Orient extends AscentValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.orient());
+                       show(state.orient(), state.max_orient());
                }
                public Orient (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.orient, "Tilt Angle");
                }
                public Orient (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.orient, "Tilt Angle");
@@ -420,6 +427,12 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
                if (state.gps != null && state.gps.connected) {
                        lat.show(state, listener_state);
                        lon.show(state, listener_state);
                if (state.gps != null && state.gps.connected) {
                        lat.show(state, listener_state);
                        lon.show(state, listener_state);
@@ -466,6 +479,17 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                return "Ascent";
        }
 
                return "Ascent";
        }
 
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
        public AltosAscent() {
                layout = new GridBagLayout();
 
        public AltosAscent() {
                layout = new GridBagLayout();
 
@@ -487,5 +511,6 @@ public class AltosAscent extends JComponent implements AltosFlightDisplay {
                lon = new Lon(layout, y++);
                apogee = new Apogee(layout, y++);
                main = new Main(layout, y++);
                lon = new Lon(layout, y++);
                apogee = new Apogee(layout, y++);
                main = new Main(layout, y++);
+               addHierarchyListener(this);
        }
 }
        }
 }
index b56a08bc3cfad7f46d0cd32cc9a20c284e0366c9..11bd6dbf2c331c16461f8bad396a2b6b6475902c 100644 (file)
 package altosui;
 
 import java.awt.*;
 package altosui;
 
 import java.awt.*;
+import java.awt.event.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
-public class AltosDescent extends JComponent implements AltosFlightDisplay {
+public class AltosDescent extends JComponent implements AltosFlightDisplay, HierarchyListener {
        GridBagLayout   layout;
 
        GridBagLayout   layout;
 
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
        public abstract class DescentStatus implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
        public abstract class DescentStatus implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
@@ -91,6 +95,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 4; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 4; c.gridy = y;
@@ -109,6 +114,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                JTextField      value;
                AltosUnits      units;
                double          v;
                JTextField      value;
                AltosUnits      units;
                double          v;
+               String          last_value = "";
 
                void reset() {
                        value.setText("");
 
                void reset() {
                        value.setText("");
@@ -128,7 +134,11 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
 
                void show(String v) {
                        show();
 
                void show(String v) {
                        show();
-                       value.setText(v);
+
+                       if (!last_value.equals(v)) {
+                               value.setText(v);
+                               last_value = v;
+                       }
                }
 
                void show(double v) {
                }
 
                void show(double v) {
@@ -172,6 +182,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        add(label, c);
 
                        value = new JTextField(Altos.text_width);
                        add(label, c);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 2; c.gridy = y;
@@ -247,6 +258,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value1 = new JTextField(Altos.text_width);
                        add(label);
 
                        value1 = new JTextField(Altos.text_width);
+                       value1.setEditable(false);
                        value1.setFont(Altos.value_font);
                        value1.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 2; c.gridy = y;
                        value1.setFont(Altos.value_font);
                        value1.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 2; c.gridy = y;
@@ -257,6 +269,7 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                        add(value1);
 
                        value2 = new JTextField(Altos.text_width);
                        add(value1);
 
                        value2 = new JTextField(Altos.text_width);
+                       value2.setEditable(false);
                        value2.setFont(Altos.value_font);
                        value2.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 4; c.gridy = y;
                        value2.setFont(Altos.value_font);
                        value2.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = x + 4; c.gridy = y;
@@ -449,6 +462,12 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
                height.show(state, listener_state);
                speed.show(state, listener_state);
                if (state.gps != null && state.gps.connected) {
                height.show(state, listener_state);
                speed.show(state, listener_state);
                if (state.gps != null && state.gps.connected) {
@@ -480,6 +499,17 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
                return "Descent";
        }
 
                return "Descent";
        }
 
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
        public AltosDescent() {
                layout = new GridBagLayout();
 
        public AltosDescent() {
                layout = new GridBagLayout();
 
@@ -497,5 +527,6 @@ public class AltosDescent extends JComponent implements AltosFlightDisplay {
 
                apogee = new Apogee(layout, 5);
                main = new Main(layout, 6);
 
                apogee = new Apogee(layout, 5);
                main = new Main(layout, 6);
+               addHierarchyListener(this);
        }
 }
        }
 }
index 459b0495939a61bd98bfd58258f2166b5dec7e49..b27deba903a589af3c3b86cb29c23920ed886083 100644 (file)
@@ -61,6 +61,7 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
                        add(label);
 
                        value = new JTextField("");
                        add(label);
 
                        value = new JTextField("");
+                       value.setEditable(false);
                        value.setFont(Altos.status_font);
                        value.setHorizontalAlignment(SwingConstants.CENTER);
                        c.gridx = x; c.gridy = 1;
                        value.setFont(Altos.status_font);
                        value.setHorizontalAlignment(SwingConstants.CENTER);
                        c.gridx = x; c.gridy = 1;
@@ -70,12 +71,25 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        }
 
        class Call extends FlightValue {
        }
 
        class Call extends FlightValue {
-               void show(AltosState state, AltosListenerState listener_state) {
-                       value.setText(state.callsign);
-                       if (state.callsign == null)
-                               setVisible(false);
+
+               String last_call = "";
+
+               boolean same_call(String call) {
+                       if (last_call == null)
+                               return call == null;
                        else
                        else
-                               setVisible(true);
+                               return last_call.equals(call);
+               }
+
+               void show(AltosState state, AltosListenerState listener_state) {
+                       if (!same_call(state.callsign)) {
+                               value.setText(state.callsign);
+                               if (state.callsign == null)
+                                       setVisible(false);
+                               else
+                                       setVisible(true);
+                               last_call = state.callsign;
+                       }
                }
                public Call (GridBagLayout layout, int x) {
                        super (layout, x, "Callsign");
                }
                public Call (GridBagLayout layout, int x) {
                        super (layout, x, "Callsign");
@@ -85,11 +99,16 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        Call call;
 
        class Serial extends FlightValue {
        Call call;
 
        class Serial extends FlightValue {
+
+               int     last_serial = -1;
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       if (state.serial == AltosLib.MISSING)
-                               value.setText("none");
-                       else
-                               value.setText(String.format("%d", state.serial));
+                       if (state.serial != last_serial) {
+                               if (state.serial == AltosLib.MISSING)
+                                       value.setText("none");
+                               else
+                                       value.setText(String.format("%d", state.serial));
+                               last_serial = state.serial;
+                       }
                }
                public Serial (GridBagLayout layout, int x) {
                        super (layout, x, "Serial");
                }
                public Serial (GridBagLayout layout, int x) {
                        super (layout, x, "Serial");
@@ -99,11 +118,17 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        Serial serial;
 
        class Flight extends FlightValue {
        Serial serial;
 
        class Flight extends FlightValue {
+
+               int     last_flight = -1;
+
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       if (state.flight == AltosLib.MISSING)
-                               value.setText("none");
-                       else
-                               value.setText(String.format("%d", state.flight));
+                       if (state.flight != last_flight) {
+                               if (state.flight == AltosLib.MISSING)
+                                       value.setText("none");
+                               else
+                                       value.setText(String.format("%d", state.flight));
+                               last_flight = state.flight;
+                       }
                }
                public Flight (GridBagLayout layout, int x) {
                        super (layout, x, "Flight");
                }
                public Flight (GridBagLayout layout, int x) {
                        super (layout, x, "Flight");
@@ -113,8 +138,14 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        Flight flight;
 
        class FlightState extends FlightValue {
        Flight flight;
 
        class FlightState extends FlightValue {
+
+               int     last_state = -1;
+
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       value.setText(state.state_name());
+                       if (state.state != last_state) {
+                               value.setText(state.state_name());
+                               last_state = state.state;
+                       }
                }
                public FlightState (GridBagLayout layout, int x) {
                        super (layout, x, "State");
                }
                public FlightState (GridBagLayout layout, int x) {
                        super (layout, x, "State");
@@ -124,12 +155,18 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        FlightState flight_state;
 
        class RSSI extends FlightValue {
        FlightState flight_state;
 
        class RSSI extends FlightValue {
+
+               int     last_rssi = 10000;
+
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       value.setText(String.format("%d", state.rssi()));
-                       if (state.rssi == AltosLib.MISSING)
-                               setVisible(false);
-                       else
-                               setVisible(true);
+                       if (state.rssi() != last_rssi) {
+                               value.setText(String.format("%d", state.rssi()));
+                               if (state.rssi == AltosLib.MISSING)
+                                       setVisible(false);
+                               else
+                                       setVisible(true);
+                               last_rssi = state.rssi();
+                       }
                }
                public RSSI (GridBagLayout layout, int x) {
                        super (layout, x, "RSSI");
                }
                public RSSI (GridBagLayout layout, int x) {
                        super (layout, x, "RSSI");
@@ -139,9 +176,15 @@ public class AltosFlightStatus extends JComponent implements AltosFlightDisplay
        RSSI rssi;
 
        class LastPacket extends FlightValue {
        RSSI rssi;
 
        class LastPacket extends FlightValue {
+
+               long    last_secs = -1;
+
                void show(AltosState state, AltosListenerState listener_state) {
                        long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
                void show(AltosState state, AltosListenerState listener_state) {
                        long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
-                       value.setText(String.format("%d", secs));
+                       if (secs != last_secs) {
+                               value.setText(String.format("%d", secs));
+                               last_secs = secs;
+                       }
                }
                public LastPacket(GridBagLayout layout, int x) {
                        super (layout, x, "Age");
                }
                public LastPacket(GridBagLayout layout, int x) {
                        super (layout, x, "Age");
index 7f62938d7e3f721bbe14cfc010c5cae2b6891c54..73318117bc7985152f7c9730c6b081b73661d088 100644 (file)
@@ -102,6 +102,7 @@ public class AltosIgnitor extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
index d2628fb01f1c2b6a468cf4cf01b6f5197529ae23..760b2d64e1456a6ebb4ddccf68414b4621eac4c8 100644 (file)
@@ -24,14 +24,18 @@ import java.io.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
-public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener {
+public class AltosLanded extends JComponent implements AltosFlightDisplay, ActionListener, HierarchyListener {
        GridBagLayout   layout;
 
        GridBagLayout   layout;
 
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
        public abstract class LandedValue implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
                AltosUnits      units;
                double          v;
        public abstract class LandedValue implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
                AltosUnits      units;
                double          v;
+               String          last_value = "";
 
                abstract void show(AltosState state, AltosListenerState listener_state);
 
 
                abstract void show(AltosState state, AltosListenerState listener_state);
 
@@ -46,7 +50,10 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
 
                void show(String s) {
                        show();
 
                void show(String s) {
                        show();
-                       value.setText(s);
+                       if (!last_value.equals(s)) {
+                               value.setText(s);
+                               last_value = s;
+                       }
                }
 
                void show(double v) {
                }
 
                void show(double v) {
@@ -94,6 +101,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 1; c.gridy = y;
@@ -244,6 +252,12 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
                if (state.gps != null && state.gps.connected) {
                        bearing.show(state, listener_state);
                        distance.show(state, listener_state);
                if (state.gps != null && state.gps.connected) {
                        bearing.show(state, listener_state);
                        distance.show(state, listener_state);
@@ -302,6 +316,17 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
                return "Landed";
        }
 
                return "Landed";
        }
 
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
        public AltosLanded(AltosFlightReader in_reader) {
                layout = new GridBagLayout();
 
        public AltosLanded(AltosFlightReader in_reader) {
                layout = new GridBagLayout();
 
@@ -332,5 +357,6 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
                c.weighty = 0;
                c.fill = GridBagConstraints.VERTICAL;
                add(graph, c);
                c.weighty = 0;
                c.fill = GridBagConstraints.VERTICAL;
                add(graph, c);
+               addHierarchyListener(this);
        }
 }
        }
 }
index ce1f2ab74c24f0b3539af1c8e8f8ec3961499399..3294949c395628f9f8e98587bac784da20ea28f8 100644 (file)
@@ -98,6 +98,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -178,6 +179,7 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(Altos.text_width);
                        add(label);
 
                        value = new JTextField(Altos.text_width);
+                       value.setEditable(false);
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(Altos.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -193,50 +195,56 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                }
        }
 
                }
        }
 
-       class Battery extends LaunchStatus {
+       class Voltage extends LaunchStatus {
+
+               double voltage(AltosState state) { return AltosLib.MISSING; };
+               double good() { return 0; };
+
+               double  last_voltage = -1;
+
                void show (AltosState state, AltosListenerState listener_state) {
                void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null || state.battery_voltage == AltosLib.MISSING)
-                               hide();
-                       else {
-                               show("%4.2f V", state.battery_voltage);
-                               lights.set(state.battery_voltage >= AltosLib.ao_battery_good);
+                       double  voltage = AltosLib.MISSING;
+                       if (state != null)
+                               voltage = voltage(state);
+
+                       if (voltage != last_voltage) {
+                               if (voltage == AltosLib.MISSING)
+                                       hide();
+                               else {
+                                       show("%4.2f V", voltage);
+                                       lights.set(voltage >= good());
+                               }
+                               last_voltage = voltage;
                        }
                }
                        }
                }
+               public Voltage (GridBagLayout layout, int y, String name) { super(layout, y, name); }
+       }
+
+
+       class Battery extends Voltage {
+               double voltage(AltosState state) { return state.battery_voltage; }
+               double good() { return AltosLib.ao_battery_good; }
+
                public Battery (GridBagLayout layout, int y) {
                        super(layout, y, "Battery Voltage");
                }
                public Battery (GridBagLayout layout, int y) {
                        super(layout, y, "Battery Voltage");
                }
+
        }
 
        Battery battery;
 
        }
 
        Battery battery;
 
-       class Apogee extends LaunchStatus {
-               void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null || state.apogee_voltage == AltosLib.MISSING)
-                               hide();
-                       else {
-                               show("%4.2f V", state.apogee_voltage);
-                               lights.set(state.apogee_voltage >= AltosLib.ao_igniter_good);
-                       }
-               }
-               public Apogee (GridBagLayout layout, int y) {
-                       super(layout, y, "Apogee Igniter Voltage");
-               }
+       class Apogee extends Voltage {
+               double voltage(AltosState state) { return state.apogee_voltage; }
+               double good() { return AltosLib.ao_igniter_good; }
+               public Apogee (GridBagLayout layout, int y) { super(layout, y, "Apogee Igniter Voltage"); }
        }
 
        Apogee apogee;
 
        }
 
        Apogee apogee;
 
-       class Main extends LaunchStatus {
-               void show (AltosState state, AltosListenerState listener_state) {
-                       if (state == null || state.main_voltage == AltosLib.MISSING)
-                               hide();
-                       else {
-                               show("%4.2f V", state.main_voltage);
-                               lights.set(state.main_voltage >= AltosLib.ao_igniter_good);
-                       }
-               }
-               public Main (GridBagLayout layout, int y) {
-                       super(layout, y, "Main Igniter Voltage");
-               }
+       class Main extends  Voltage {
+               double voltage(AltosState state) { return state.main_voltage; }
+               double good() { return AltosLib.ao_igniter_good; }
+               public Main (GridBagLayout layout, int y) { super(layout, y, "Main Igniter Voltage"); }
        }
 
        Main main;
        }
 
        Main main;
@@ -328,6 +336,9 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
        }
 
        class PadLat extends LaunchValue {
        }
 
        class PadLat extends LaunchValue {
+
+               double  last_lat = 1000;
+
                void show (AltosState state, AltosListenerState listener_state) {
                        double lat = AltosLib.MISSING;
                        String label = null;
                void show (AltosState state, AltosListenerState listener_state) {
                        double lat = AltosLib.MISSING;
                        String label = null;
@@ -341,11 +352,14 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                                        label = "Pad Latitude";
                                }
                        }
                                        label = "Pad Latitude";
                                }
                        }
-                       if (lat != AltosLib.MISSING) {
-                               show(pos(lat,"N", "S"));
-                               set_label(label);
-                       } else
-                               hide();
+                       if (lat != last_lat) {
+                               if (lat != AltosLib.MISSING) {
+                                       show(pos(lat,"N", "S"));
+                                       set_label(label);
+                               } else
+                                       hide();
+                               last_lat = lat;
+                       }
                }
                public PadLat (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Latitude");
                }
                public PadLat (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Latitude");
@@ -355,6 +369,9 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
        PadLat pad_lat;
 
        class PadLon extends LaunchValue {
        PadLat pad_lat;
 
        class PadLon extends LaunchValue {
+
+               double last_lon = 1000;
+
                void show (AltosState state, AltosListenerState listener_state) {
                        double lon = AltosLib.MISSING;
                        String label = null;
                void show (AltosState state, AltosListenerState listener_state) {
                        double lon = AltosLib.MISSING;
                        String label = null;
@@ -368,11 +385,14 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                                        label = "Pad Longitude";
                                }
                        }
                                        label = "Pad Longitude";
                                }
                        }
-                       if (lon != AltosLib.MISSING) {
-                               show(pos(lon,"E", "W"));
-                               set_label(label);
-                       } else
-                               hide();
+                       if (lon != last_lon) {
+                               if (lon != AltosLib.MISSING) {
+                                       show(pos(lon,"E", "W"));
+                                       set_label(label);
+                               } else
+                                       hide();
+                               last_lon = lon;
+                       }
                }
                public PadLon (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Longitude");
                }
                public PadLon (GridBagLayout layout, int y) {
                        super (layout, y, "Pad Longitude");
@@ -382,6 +402,9 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
        PadLon pad_lon;
 
        class PadAlt extends LaunchValue {
        PadLon pad_lon;
 
        class PadAlt extends LaunchValue {
+
+               double  last_alt = -1000000;
+
                void show (AltosState state, AltosListenerState listener_state) {
                        double alt = AltosLib.MISSING;
                        String label = null;
                void show (AltosState state, AltosListenerState listener_state) {
                        double alt = AltosLib.MISSING;
                        String label = null;
@@ -395,11 +418,14 @@ public class AltosPad extends JComponent implements AltosFlightDisplay {
                                        label = "Pad Altitude";
                                }
                        }
                                        label = "Pad Altitude";
                                }
                        }
-                       if (alt != AltosLib.MISSING) {
-                               show(alt);
-                               set_label(label);
-                       } else
-                               hide();
+                       if (alt != last_alt) {
+                               if (alt != AltosLib.MISSING) {
+                                       show(alt);
+                                       set_label(label);
+                               } else
+                                       hide();
+                               last_alt = alt;
+                       }
                }
                public PadAlt (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Pad Altitude");
                }
                public PadAlt (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Pad Altitude");
index 24a895eb22dafb7ac294baecdb54abb25d9c9533..8ded1bea13bd8dca5ab773c6b5733e3ccb45bd13 100644 (file)
 package org.altusmetrum.altosuilib_2;
 
 import java.awt.*;
 package org.altusmetrum.altosuilib_2;
 
 import java.awt.*;
+import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.table.*;
 import org.altusmetrum.altoslib_4.*;
 
 import javax.swing.*;
 import javax.swing.table.*;
 import org.altusmetrum.altoslib_4.*;
 
-public class AltosInfoTable extends JTable implements AltosFlightDisplay {
+public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
        private AltosFlightInfoTableModel model;
 
        static final int info_columns = 3;
        static final int info_rows = 17;
 
        private AltosFlightInfoTableModel model;
 
        static final int info_columns = 3;
        static final int info_rows = 17;
 
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
        int desired_row_height() {
                FontMetrics     infoValueMetrics = getFontMetrics(AltosUILib.table_value_font);
                return (infoValueMetrics.getHeight() + infoValueMetrics.getLeading()) * 18 / 10;
        int desired_row_height() {
                FontMetrics     infoValueMetrics = getFontMetrics(AltosUILib.table_value_font);
                return (infoValueMetrics.getHeight() + infoValueMetrics.getLeading()) * 18 / 10;
@@ -56,6 +60,7 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay {
                super(new AltosFlightInfoTableModel(info_rows, info_columns));
                model = (AltosFlightInfoTableModel) getModel();
                setFont(AltosUILib.table_value_font);
                super(new AltosFlightInfoTableModel(info_rows, info_columns));
                model = (AltosFlightInfoTableModel) getModel();
                setFont(AltosUILib.table_value_font);
+               addHierarchyListener(this);
                setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
                setShowGrid(true);
                set_layout();
                setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
                setShowGrid(true);
                set_layout();
@@ -71,6 +76,17 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay {
        public void units_changed(boolean imperial_units) {
        }
 
        public void units_changed(boolean imperial_units) {
        }
 
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
        public Dimension getPreferredScrollableViewportSize() {
                return getPreferredSize();
        }
        public Dimension getPreferredScrollableViewportSize() {
                return getPreferredSize();
        }
@@ -108,6 +124,13 @@ public class AltosInfoTable extends JTable implements AltosFlightDisplay {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
+
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
                reset();
                if (state != null) {
                        if (state.device_type != AltosLib.MISSING)
                reset();
                if (state != null) {
                        if (state.device_type != AltosLib.MISSING)
index 701986825ea2c3817286a83b411fe1b644c24523..efae376786f5652951fd600623fbdd3510bfe94a 100644 (file)
@@ -28,7 +28,7 @@ import java.util.*;
 import java.util.concurrent.*;
 import org.altusmetrum.altoslib_4.*;
 
 import java.util.concurrent.*;
 import org.altusmetrum.altoslib_4.*;
 
-public class AltosUIMapView extends Canvas implements MouseMotionListener, MouseListener, MouseWheelListener, ComponentListener, AltosUIMapTileListener, AltosUIMapStoreListener {
+public class AltosUIMapView extends Component implements MouseMotionListener, MouseListener, MouseWheelListener, ComponentListener, AltosUIMapTileListener, AltosUIMapStoreListener {
 
        AltosUIMapPath  path = new AltosUIMapPath();
 
 
        AltosUIMapPath  path = new AltosUIMapPath();
 
@@ -422,7 +422,6 @@ public class AltosUIMapView extends Canvas implements MouseMotionListener, Mouse
        }
 
        public void paint(Graphics g) {
        }
 
        public void paint(Graphics g) {
-
                VolatileImage   back_buffer = create_back_buffer();
                do {
                        GraphicsConfiguration gc = getGraphicsConfiguration();
                VolatileImage   back_buffer = create_back_buffer();
                do {
                        GraphicsConfiguration gc = getGraphicsConfiguration();
index 2765f5abd2d0ea83b0466d35eb5e76db19048e4f..15eb9b75e4fb71628c577d4fa035d03809bdf457 100644 (file)
 package org.altusmetrum.telegps;
 
 import java.awt.*;
 package org.altusmetrum.telegps;
 
 import java.awt.*;
+import java.awt.event.*;
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
 import javax.swing.*;
 import org.altusmetrum.altoslib_4.*;
 import org.altusmetrum.altosuilib_2.*;
 
-public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
+public class TeleGPSInfo extends JComponent implements AltosFlightDisplay, HierarchyListener {
        GridBagLayout   layout;
        JLabel                  cur, max;
 
        GridBagLayout   layout;
        JLabel                  cur, max;
 
+       private AltosState              last_state;
+       private AltosListenerState      last_listener_state;
+
        public abstract class Info implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
        public abstract class Info implements AltosFontListener, AltosUnitsListener {
                JLabel          label;
                JTextField      value;
@@ -280,6 +284,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                        value1 = new JTextField(AltosUILib.text_width);
                        value1.setFont(AltosUILib.value_font);
                        value1.setHorizontalAlignment(SwingConstants.RIGHT);
                        value1 = new JTextField(AltosUILib.text_width);
                        value1.setFont(AltosUILib.value_font);
                        value1.setHorizontalAlignment(SwingConstants.RIGHT);
+                       value1.setEditable(false);
                        c.gridx = 2; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
                        c.fill = GridBagConstraints.BOTH;
                        c.gridx = 2; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
                        c.fill = GridBagConstraints.BOTH;
@@ -290,6 +295,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                        value2 = new JTextField(AltosUILib.text_width);
                        value2.setFont(AltosUILib.value_font);
                        value2.setHorizontalAlignment(SwingConstants.RIGHT);
                        value2 = new JTextField(AltosUILib.text_width);
                        value2.setFont(AltosUILib.value_font);
                        value2.setHorizontalAlignment(SwingConstants.RIGHT);
+                       value1.setEditable(false);
                        c.gridx = 3; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
                        c.fill = GridBagConstraints.BOTH;
                        c.gridx = 3; c.gridy = y;
                        c.anchor = GridBagConstraints.WEST;
                        c.fill = GridBagConstraints.BOTH;
@@ -323,18 +329,16 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                }
 
                public void units_changed(boolean imperial_units) {
                }
 
                public void units_changed(boolean imperial_units) {
-                       show(v);
+                       show(v, max);
                }
 
                }
 
-               void show(double v) {
+               void show(double v, double max) {
                        this.v = v;
                        this.v = v;
-                       if (v == AltosLib.MISSING) {
+                       this.max = max;
+                       if (v == AltosLib.MISSING)
                                value.setText("Missing");
                                value.setText("Missing");
-                       } else {
+                       else
                                value.setText(units.show(8, v));
                                value.setText(units.show(8, v));
-                               if (v > max || max == AltosLib.MISSING)
-                                       max = v;
-                       }
                        if (max == AltosLib.MISSING)
                                max_value.setText("Missing");
                        else
                        if (max == AltosLib.MISSING)
                                max_value.setText("Missing");
                        else
@@ -364,6 +368,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField(AltosUILib.text_width);
                        add(label);
 
                        value = new JTextField(AltosUILib.text_width);
+                       value.setEditable(false);
                        value.setFont(AltosUILib.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
                        value.setFont(AltosUILib.value_font);
                        value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 2; c.gridy = y;
@@ -374,6 +379,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                        add(value);
 
                        max_value = new JTextField(AltosUILib.text_width);
                        add(value);
 
                        max_value = new JTextField(AltosUILib.text_width);
+                       max_value.setEditable(false);
                        max_value.setFont(AltosUILib.value_font);
                        max_value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 3; c.gridy = y;
                        max_value.setFont(AltosUILib.value_font);
                        max_value.setHorizontalAlignment(SwingConstants.RIGHT);
                        c.gridx = 3; c.gridy = y;
@@ -388,7 +394,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
 
        class Altitude extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class Altitude extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.altitude());
+                       show(state.altitude(), state.max_altitude());
                }
                public Altitude (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Altitude");
                }
                public Altitude (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.height, "Altitude");
@@ -399,7 +405,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
 
        class AscentRate extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class AscentRate extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.gps_ascent_rate());
+                       show(state.gps_ascent_rate(), state.max_gps_ascent_rate());
                }
                public AscentRate (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Ascent Rate");
                }
                public AscentRate (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Ascent Rate");
@@ -410,7 +416,7 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
 
        class GroundSpeed extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
 
        class GroundSpeed extends ValueHold {
                void show (AltosState state, AltosListenerState listener_state) {
-                       show(state.gps_ground_speed());
+                       show(state.gps_ground_speed(), state.max_gps_ground_speed());
                }
                public GroundSpeed (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Ground Speed");
                }
                public GroundSpeed (GridBagLayout layout, int y) {
                        super (layout, y, AltosConvert.speed, "Ground Speed");
@@ -526,6 +532,12 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
+               if (!isShowing()) {
+                       last_state = state;
+                       last_listener_state = listener_state;
+                       return;
+               }
+
                if (state.gps != null && state.gps.connected) {
                        lat.show(state, listener_state);
                        lon.show(state, listener_state);
                if (state.gps != null && state.gps.connected) {
                        lat.show(state, listener_state);
                        lon.show(state, listener_state);
@@ -562,6 +574,17 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                return "Info";
        }
 
                return "Info";
        }
 
+       public void hierarchyChanged(HierarchyEvent e) {
+               if (last_state != null && isShowing()) {
+                       AltosState              state = last_state;
+                       AltosListenerState      listener_state = last_listener_state;
+
+                       last_state = null;
+                       last_listener_state = null;
+                       show(state, listener_state);
+               }
+       }
+
        public TeleGPSInfo() {
                layout = new GridBagLayout();
 
        public TeleGPSInfo() {
                layout = new GridBagLayout();
 
@@ -582,5 +605,6 @@ public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
                lat = new Lat(layout, y++);
                lon = new Lon(layout, y++);
                gps_locked = new GPSLocked(layout, y++);
                lat = new Lat(layout, y++);
                lon = new Lon(layout, y++);
                gps_locked = new GPSLocked(layout, y++);
+               addHierarchyListener(this);
        }
 }
        }
 }
index 37cfae37ec1f0d3b27c423b33b6f5d6afaf35b65..e6bb1ea58a7bb047836aa99857f41fca895aa738 100644 (file)
@@ -61,6 +61,7 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
                        add(label);
 
                        value = new JTextField("");
                        add(label);
 
                        value = new JTextField("");
+                       value.setEditable(false);
                        value.setFont(AltosUILib.status_font);
                        value.setHorizontalAlignment(SwingConstants.CENTER);
                        c.gridx = x; c.gridy = 1;
                        value.setFont(AltosUILib.status_font);
                        value.setHorizontalAlignment(SwingConstants.CENTER);
                        c.gridx = x; c.gridy = 1;
@@ -70,8 +71,13 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        }
 
        class Call extends Value {
        }
 
        class Call extends Value {
+               String  call;
+
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       value.setText(state.callsign);
+                       if (state.callsign != call) {
+                               value.setText(state.callsign);
+                               call = state.callsign;
+                       }
                        if (state.callsign == null)
                                setVisible(false);
                        else
                        if (state.callsign == null)
                                setVisible(false);
                        else
@@ -85,11 +91,15 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        Call call;
 
        class Serial extends Value {
        Call call;
 
        class Serial extends Value {
+               int     serial = -1;
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       if (state.serial == AltosLib.MISSING)
-                               value.setText("none");
-                       else
-                               value.setText(String.format("%d", state.serial));
+                       if (state.serial != serial) {
+                               if (state.serial == AltosLib.MISSING)
+                                       value.setText("none");
+                               else
+                                       value.setText(String.format("%d", state.serial));
+                               serial = state.serial;
+                       }
                }
                public Serial (GridBagLayout layout, int x) {
                        super (layout, x, "Serial");
                }
                public Serial (GridBagLayout layout, int x) {
                        super (layout, x, "Serial");
@@ -99,12 +109,19 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        Serial serial;
 
        class RSSI extends Value {
        Serial serial;
 
        class RSSI extends Value {
+               int     rssi = 10000;
+
                void show(AltosState state, AltosListenerState listener_state) {
                void show(AltosState state, AltosListenerState listener_state) {
-                       value.setText(String.format("%d", state.rssi()));
-                       if (state.rssi == AltosLib.MISSING)
-                               setVisible(false);
-                       else
-                               setVisible(true);
+                       int     new_rssi = state.rssi();
+
+                       if (new_rssi != rssi) {
+                               value.setText(String.format("%d", new_rssi));
+                               if (state.rssi == AltosLib.MISSING)
+                                       setVisible(false);
+                               else
+                                       setVisible(true);
+                               rssi = new_rssi;
+                       }
                }
                public RSSI (GridBagLayout layout, int x) {
                        super (layout, x, "RSSI");
                }
                public RSSI (GridBagLayout layout, int x) {
                        super (layout, x, "RSSI");
@@ -114,9 +131,16 @@ public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
        RSSI rssi;
 
        class LastPacket extends Value {
        RSSI rssi;
 
        class LastPacket extends Value {
+
+               long    last_secs = -1;
+
                void show(AltosState state, AltosListenerState listener_state) {
                        long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
                void show(AltosState state, AltosListenerState listener_state) {
                        long secs = (System.currentTimeMillis() - state.received_time + 500) / 1000;
-                       value.setText(String.format("%d", secs));
+
+                       if (secs != last_secs) {
+                               value.setText(String.format("%d", secs));
+                               last_secs = secs;
+                       }
                }
                public LastPacket(GridBagLayout layout, int x) {
                        super (layout, x, "Age");
                }
                public LastPacket(GridBagLayout layout, int x) {
                        super (layout, x, "Age");