2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 import java.awt.event.*;
25 import java.util.concurrent.*;
26 import org.altusmetrum.altoslib_12.*;
27 import org.altusmetrum.altosuilib_12.*;
29 public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
31 AltosFlightReader reader;
32 AltosDisplayThread thread;
34 LinkedList<AltosFlightDisplay> displays;
44 private AltosFlightStatus flightStatus;
45 private AltosInfoTable flightInfo;
47 boolean exit_on_close = false;
49 JComponent cur_tab = null;
50 JComponent which_tab(AltosState state) {
51 if (state.state() < Altos.ao_flight_boost)
57 if (thread != null && thread.isAlive()) {
61 } catch (InterruptedException ie) {}
71 for (AltosFlightDisplay d : displays)
75 public void font_size_changed(int font_size) {
76 for (AltosFlightDisplay d : displays)
77 d.font_size_changed(font_size);
80 public void units_changed(boolean imperial_units) {
81 for (AltosFlightDisplay d : displays)
82 d.units_changed(imperial_units);
85 AltosFlightStatusUpdate status_update;
87 public void show(AltosState state, AltosListenerState listener_state) {
88 status_update.saved_state = state;
89 status_update.saved_listener_state = listener_state;
92 state = new AltosState(new AltosCalData());
94 if (state.state() != Altos.ao_flight_startup) {
96 pane.setTitleAt(0, "Launch Pad");
102 JComponent tab = which_tab(state);
103 if (tab != cur_tab) {
104 if (cur_tab == pane.getSelectedComponent())
105 pane.setSelectedComponent(tab);
109 if (igniter.should_show(state)) {
111 pane.add("Ignitor", igniter);
116 pane.remove(igniter);
121 for (AltosFlightDisplay d : displays) {
123 d.show(state, listener_state);
124 } catch (Exception e) {
125 System.out.printf("Exception showing %s\n", d.getName());
131 public void set_exit_on_close() {
132 exit_on_close = true;
136 AltosUIFreqList frequencies;
137 AltosUIRateList rates;
138 AltosUITelemetryList telemetries;
141 ActionListener show_timer;
143 public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) {
144 AltosUIPreferences.set_component(this);
146 displays = new LinkedList<AltosFlightDisplay>();
151 bag = getContentPane();
152 bag.setLayout(new GridBagLayout());
154 setTitle(String.format("AltOS %s", reader.name));
156 /* Stick channel selector at top of table for telemetry monitoring */
161 frequencies = new AltosUIFreqList(AltosUIPreferences.frequency(serial));
162 frequencies.set_product("Monitor");
163 frequencies.set_serial(serial);
164 frequencies.addActionListener(new ActionListener() {
165 public void actionPerformed(ActionEvent e) {
166 double frequency = frequencies.frequency();
168 reader.set_frequency(frequency);
169 } catch (TimeoutException te) {
170 } catch (InterruptedException ie) {
172 reader.save_frequency();
175 bag.add (frequencies, constraints(0, 1));
177 // Telemetry rate list
178 rates = new AltosUIRateList(AltosUIPreferences.telemetry_rate(serial));
179 rates.addActionListener(new ActionListener() {
180 public void actionPerformed(ActionEvent e) {
181 int rate = rates.rate();
183 reader.set_telemetry_rate(rate);
184 } catch (TimeoutException te) {
185 } catch (InterruptedException ie) {
187 reader.save_telemetry_rate();
190 rates.setEnabled(reader.supports_telemetry_rate(AltosLib.ao_telemetry_rate_2400));
191 bag.add (rates, constraints(1, 1));
193 // Telemetry format list
194 if (reader.supports_telemetry(Altos.ao_telemetry_standard)) {
195 telemetries = new AltosUITelemetryList(serial);
196 telemetries.addActionListener(new ActionListener() {
197 public void actionPerformed(ActionEvent e) {
198 int telemetry = telemetries.get_selected();
199 reader.set_telemetry(telemetry);
200 reader.save_telemetry();
203 bag.add (telemetries, constraints(2, 1));
207 if (reader.supports_telemetry(Altos.ao_telemetry_0_9))
208 version = "Telemetry: 0.9";
209 else if (reader.supports_telemetry(Altos.ao_telemetry_0_8))
210 version = "Telemetry: 0.8";
212 version = "Telemetry: None";
214 telemetry = new JLabel(version);
215 bag.add (telemetry, constraints(2, 1));
221 /* Flight status is always visible */
222 flightStatus = new AltosFlightStatus();
223 displays.add(flightStatus);
224 bag.add(flightStatus, constraints(0, 4, GridBagConstraints.HORIZONTAL));
227 /* The rest of the window uses a tabbed pane to
228 * show one of the alternate data views
230 pane = new JTabbedPane();
232 pad = new AltosPad();
234 pane.add("Status", pad);
236 igniter = new AltosIgnitor();
237 displays.add(igniter);
238 landed = new AltosLanded(reader);
239 displays.add(landed);
241 flightInfo = new AltosInfoTable();
242 displays.add(flightInfo);
243 pane.add("Table", new JScrollPane(flightInfo));
247 /* Make the tabbed pane use the rest of the window space */
248 bag.add(pane, constraints(0, 4, GridBagConstraints.BOTH));
250 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
252 AltosUIPreferences.register_font_listener(this);
253 AltosPreferences.register_units_listener(this);
255 status_update = new AltosFlightStatusUpdate(flightStatus);
257 flightStatus.start(status_update);
259 addWindowListener(new WindowAdapter() {
261 public void windowClosing(WindowEvent e) {
266 AltosUIPreferences.unregister_font_listener(AltosFlightUI.this);
267 AltosPreferences.unregister_units_listener(AltosFlightUI.this);
276 thread = new AltosDisplayThread(this, voice, this, reader);
281 public AltosFlightUI (AltosVoice in_voice, AltosFlightReader in_reader) {
282 this(in_voice, in_reader, -1);