diff options
| author | Keith Packard <keithp@keithp.com> | 2011-08-07 14:52:29 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2011-08-08 12:13:29 -0700 | 
| commit | f03ca0ab8799bfa5100eaa2577cfd7b9c37d05bf (patch) | |
| tree | 29ca769689aa936acdfaabc627993a902db8ee8b | |
| parent | ba5dc35388d28c5769eaabc970c4d4b8c2c2ff9c (diff) | |
altosui: Add dialogs to configure 'common' frequencies
These are stored in preferences, but not yet hooked up to the TM/TD
configure dialogs
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | altosui/AltosConfigFreqUI.java | 418 | ||||
| -rw-r--r-- | altosui/AltosConfigureUI.java | 18 | ||||
| -rw-r--r-- | altosui/AltosFrequency.java | 51 | ||||
| -rw-r--r-- | altosui/AltosPreferences.java | 66 | ||||
| -rw-r--r-- | altosui/Makefile.am | 2 | 
5 files changed, 553 insertions, 2 deletions
| diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java new file mode 100644 index 00000000..d68151ec --- /dev/null +++ b/altosui/AltosConfigFreqUI.java @@ -0,0 +1,418 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import javax.swing.event.*; +import javax.swing.plaf.basic.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +class AltosEditFreqUI extends JDialog implements ActionListener { +	Frame		frame; +	JTextField	frequency; +	JTextField	description; +	JButton		ok_button, cancel_button; +	boolean		got_ok; + +	public void actionPerformed(ActionEvent e) { +		String	cmd = e.getActionCommand(); + +		if ("ok".equals(cmd)) { +			got_ok = true; +			setVisible(false); +		} +		if ("cancel".equals(cmd)) { +			got_ok = false; +			setVisible(false); +		} +	} + +	public AltosFrequency get() { +		if (!got_ok) +			return null; + +		String	f_s = frequency.getText(); +		String	d_s = description.getText(); + +		try { +			double	f_d = Double.parseDouble(f_s); + +			return new AltosFrequency(f_d, d_s); +		} catch (NumberFormatException ne) { +		} +		return null; +	} + +	public AltosEditFreqUI(Frame in_frame, AltosFrequency existing) { +		super(in_frame, true); + +		got_ok = false; +		frame = in_frame; + +		Container pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		GridBagConstraints c = new GridBagConstraints(); +		c.insets = new Insets (4,4,4,4); +		 +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 0; +		c.gridy = 0; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(new JLabel("Frequency"), c); + +		frequency = new JTextField(12); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 1; +		c.gridy = 0; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(frequency, c); + +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 0; +		c.gridy = 1; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(new JLabel("Description"), c); + +		description = new JTextField(12); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 1; +		c.gridy = 1; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(description, c); + +		ok_button = new JButton("OK"); +		ok_button.setActionCommand("ok"); +		ok_button.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 0; +		c.gridy = 2; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(ok_button, c); +		 +		cancel_button = new JButton("Cancel"); +		cancel_button.setActionCommand("cancel"); +		cancel_button.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 1; +		c.gridy = 2; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(cancel_button, c); +		 +		if (existing == null) +			setTitle("Add New Frequency"); +		else { +			setTitle("Edit Existing Frequency"); +			frequency.setText(String.format("%7.3f", existing.frequency)); +			description.setText(existing.description); +		} +		getRootPane().setDefaultButton(ok_button); + +		pack(); +		setLocationRelativeTo(frame); +		 +	} + +	public AltosEditFreqUI(Frame in_frame) { +		this(in_frame, (AltosFrequency) null); +	} +} + +public class AltosConfigFreqUI extends JDialog implements ActionListener { + +	Frame frame; +	LinkedList<ActionListener> listeners; + +	class FrequencyList extends JList { +		DefaultListModel list_model; + +		public void add(AltosFrequency frequency) { +			int i; +			for (i = 0; i < list_model.size(); i++) { +				AltosFrequency	f = (AltosFrequency) list_model.get(i); +				if (f.frequency == frequency.frequency) +					return; +				if (f.frequency > frequency.frequency) +					break; +			} +			list_model.insertElementAt(frequency, i); +		} + +		public void remove(AltosFrequency frequency) { +			list_model.removeElement(frequency); +		} + +		//Subclass JList to workaround bug 4832765, which can cause the +		//scroll pane to not let the user easily scroll up to the beginning +		//of the list.  An alternative would be to set the unitIncrement +		//of the JScrollBar to a fixed value. You wouldn't get the nice +		//aligned scrolling, but it should work. +		public int getScrollableUnitIncrement(Rectangle visibleRect, +						      int orientation, +						      int direction) { +			int row; +			if (orientation == SwingConstants.VERTICAL && +			    direction < 0 && (row = getFirstVisibleIndex()) != -1) { +				Rectangle r = getCellBounds(row, row); +				if ((r.y == visibleRect.y) && (row != 0))  { +					Point loc = r.getLocation(); +					loc.y--; +					int prevIndex = locationToIndex(loc); +					Rectangle prevR = getCellBounds(prevIndex, prevIndex); + +					if (prevR == null || prevR.y >= r.y) { +						return 0; +					} +					return prevR.height; +				} +			} +			return super.getScrollableUnitIncrement( +				visibleRect, orientation, direction); +		} + +		public AltosFrequency selected() { +			AltosFrequency	f = (AltosFrequency) getSelectedValue(); +			return f; +		} + +		public AltosFrequency[] frequencies() { +			AltosFrequency[]	ret; + +			ret = new AltosFrequency[list_model.size()]; +			for (int i = 0; i < list_model.size(); i++) +				ret[i] = (AltosFrequency) list_model.get(i); +			return ret; +		} + +		public FrequencyList(AltosFrequency[] in_frequencies) { +			list_model = new DefaultListModel(); +			setModel(list_model); +			setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); +			setLayoutOrientation(JList.HORIZONTAL_WRAP); +			for (int i = 0; i < in_frequencies.length; i++) { +				add(in_frequencies[i]); +			} +			setVisibleRowCount(in_frequencies.length); +		} +	} + +	FrequencyList	frequencies; + +	void save_frequencies() { +		AltosPreferences.set_common_frequencies(frequencies.frequencies()); +	} + +	JButton	add, edit, remove; + +	JButton cancel, ok; + +	public void actionPerformed(ActionEvent e) { +		String	cmd = e.getActionCommand(); + +		if ("ok".equals(cmd)) { +			save_frequencies(); +			setVisible(false); +		} else if ("cancel".equals(cmd)) { +			setVisible(false); +		} else if ("add".equals(cmd)) { +			AltosEditFreqUI	ui = new AltosEditFreqUI(frame); +			ui.setVisible(true); +			AltosFrequency	f = ui.get(); +			if (f != null) +				frequencies.add(f); +		} else if ("edit".equals(cmd)) { +			AltosFrequency	old_f = frequencies.selected(); +			if (old_f == null) +				return; +			AltosEditFreqUI	ui = new AltosEditFreqUI(frame, old_f); +			ui.setVisible(true); +			AltosFrequency	new_f = ui.get(); +			if (new_f != null) { +				if (old_f != null) +					frequencies.remove(old_f); +				frequencies.add(new_f); +			} +		} else if ("remove".equals(cmd)) { +			AltosFrequency	old_f = frequencies.selected(); +			if (old_f == null) +				return; +			int ret = JOptionPane.showConfirmDialog(this, +								String.format("Remove frequency \"%s\"?", +									      old_f.toShortString()), +								"Remove Frequency", +								JOptionPane.YES_NO_OPTION); +			if (ret == JOptionPane.YES_OPTION) +				frequencies.remove(old_f); +		} +	} + +	public AltosFrequency[] frequencies() { +		return frequencies.frequencies(); +	} +	 +	public AltosConfigFreqUI(Frame in_frame, +				 AltosFrequency[] in_frequencies) { +		super(in_frame, "Manage Frequencies", true); + +		frame = in_frame; + +		listeners = new LinkedList<ActionListener>(); + +		frequencies = new FrequencyList(in_frequencies); + +		Container pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		GridBagConstraints c = new GridBagConstraints(); +		c.insets = new Insets(4,4,4,4); + +		/* +		 * Frequencies label and list +		 */ +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 0; +		c.gridy = 0; +		c.gridwidth = 1; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(new JLabel("Frequencies"), c); + +		JScrollPane list_scroller = new JScrollPane(frequencies); +		list_scroller.setAlignmentX(LEFT_ALIGNMENT); +		c.fill = GridBagConstraints.BOTH; +		c.anchor = GridBagConstraints.WEST; +		c.gridx = 0; +		c.gridy = 1; +		c.gridwidth = 6; +		c.gridheight = 2; +		c.weightx = 1; +		c.weighty = 1; +		pane.add(list_scroller, c); + +		add = new JButton("Add"); +		add.setActionCommand("add"); +		add.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 0; +		c.gridy = 3; +		c.gridwidth = 2; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(add, c); + +		edit = new JButton("Edit"); +		edit.setActionCommand("edit"); +		edit.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 2; +		c.gridy = 3; +		c.gridwidth = 2; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(edit, c); + +		remove = new JButton("Remove"); +		remove.setActionCommand("remove"); +		remove.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 4; +		c.gridy = 3; +		c.gridwidth = 2; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(remove, c); + +		ok = new JButton("OK"); +		ok.setActionCommand("ok"); +		ok.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 0; +		c.gridy = 4; +		c.gridwidth = 3; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(ok, c); + +		cancel = new JButton("Cancel"); +		cancel.setActionCommand("cancel"); +		cancel.addActionListener(this); +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.CENTER; +		c.gridx = 3; +		c.gridy = 4; +		c.gridwidth = 3; +		c.gridheight = 1; +		c.weightx = 0; +		c.weighty = 0; +		pane.add(cancel, c); + +		pack(); +		setLocationRelativeTo(frame); +	} + +	public static void show(Component frameComp) { +		Frame	frame = JOptionPane.getFrameForComponent(frameComp); +		AltosConfigFreqUI	dialog; + +		dialog = new AltosConfigFreqUI(frame, AltosPreferences.common_frequencies()); +		dialog.setVisible(true); +	} + +} diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java index 0f5e4a3b..a8a70ffd 100644 --- a/altosui/AltosConfigureUI.java +++ b/altosui/AltosConfigureUI.java @@ -50,6 +50,7 @@ public class AltosConfigureUI  	JRadioButton	serial_debug;  	JButton		manage_bluetooth; +	JButton		manage_frequencies;  	/* DocumentListener interface methods */  	public void changedUpdate(DocumentEvent e) { @@ -207,13 +208,26 @@ public class AltosConfigureUI  					AltosBTManage.show(owner, Altos.bt_known);  				}  			}); -		c.gridx = 1; +		c.gridx = 0;  		c.gridy = 6; -		c.gridwidth = 3; +		c.gridwidth = 2;  		c.fill = GridBagConstraints.NONE;  		c.anchor = GridBagConstraints.WEST;  		pane.add(manage_bluetooth, c); +		manage_frequencies = new JButton("Manage Frequencies"); +		manage_frequencies.addActionListener(new ActionListener() { +				public void actionPerformed(ActionEvent e) { +					AltosConfigFreqUI.show(owner); +				} +			}); +		c.gridx = 2; +		c.gridy = 6; +		c.gridwidth = 2; +		c.fill = GridBagConstraints.NONE; +		c.anchor = GridBagConstraints.WEST; +		pane.add(manage_frequencies, c); +  		/* And a close button at the bottom */  		close = new JButton("Close");  		close.addActionListener(new ActionListener() { diff --git a/altosui/AltosFrequency.java b/altosui/AltosFrequency.java new file mode 100644 index 00000000..8265eafc --- /dev/null +++ b/altosui/AltosFrequency.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import javax.swing.event.*; +import javax.swing.plaf.basic.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.*; + +public class AltosFrequency { +	double	frequency; +	String	description; + +	public String toString() { +		return String.format("%7.3f MHz %-20.20s", +				     frequency, description); +	} + +	public String toShortString() { +		return String.format("%7.3f MHz %s", +				     frequency, description); +	} + +	public AltosFrequency(double f, String d) { +		frequency = f; +		description = d; +	} +}
\ No newline at end of file diff --git a/altosui/AltosPreferences.java b/altosui/AltosPreferences.java index c8dee743..e92b9532 100644 --- a/altosui/AltosPreferences.java +++ b/altosui/AltosPreferences.java @@ -64,6 +64,9 @@ class AltosPreferences {  	/* Channel (map serial to channel) */  	static Hashtable<Integer, Integer> channels; +	/* Frequency (map serial to frequency) */ +	static Hashtable<Integer, Double> frequencies; +  	/* Telemetry (map serial to telemetry format) */  	static Hashtable<Integer, Integer> telemetries; @@ -79,6 +82,55 @@ class AltosPreferences {  	/* Serial debug */  	static boolean serial_debug; +	/* List of frequencies */ +	final static String common_frequencies_node_name = "COMMON-FREQUENCIES"; +	static AltosFrequency[] common_frequencies; + +	final static String	frequency_count = "COUNT"; +	final static String	frequency_format = "FREQUENCY-%d"; +	final static String	description_format = "DESCRIPTION-%d"; + +	static AltosFrequency[] load_common_frequencies() { +		AltosFrequency[] frequencies = null; +		boolean	existing = false; +		try { +			existing = preferences.nodeExists(common_frequencies_node_name); +		} catch (BackingStoreException be) { +			existing = false; +		} +		if (existing) { +			Preferences	node = preferences.node(common_frequencies_node_name); +			int		count = node.getInt(frequency_count, 0); + +			frequencies = new AltosFrequency[count]; +			for (int i = 0; i < count; i++) { +				double	frequency; +				String	description; + +				frequency = node.getDouble(String.format(frequency_format, i), 0.0); +				description = node.get(String.format(description_format, i), null); +				frequencies[i] = new AltosFrequency(frequency, description); +			} +		} else { +			frequencies = new AltosFrequency[10]; +			for (int i = 0; i < 10; i++) { +				frequencies[i] = new AltosFrequency(434.550 + i * .1, +									   String.format("Channel %d", i)); +			} +		} +		return frequencies; +	} + +	static void save_common_frequencies(AltosFrequency[] frequencies) { +		Preferences	node = preferences.node(common_frequencies_node_name); + +		node.putInt(frequency_count, frequencies.length); +		for (int i = 0; i < frequencies.length; i++) { +			node.putDouble(String.format(frequency_format, i), frequencies[i].frequency); +			node.put(String.format(description_format, i), frequencies[i].description); +		} +	} +  	public static void init() {  		preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); @@ -112,6 +164,8 @@ class AltosPreferences {  		serial_debug = preferences.getBoolean(serialDebugPreference, false);  		AltosSerial.set_debug(serial_debug); + +		common_frequencies = load_common_frequencies();  	}  	static { init(); } @@ -273,4 +327,16 @@ class AltosPreferences {  	public static Preferences bt_devices() {  		return preferences.node("bt_devices");  	} + +	public static AltosFrequency[] common_frequencies() { +		return common_frequencies; +	} + +	public static void set_common_frequencies(AltosFrequency[] frequencies) { +		common_frequencies = frequencies; +		synchronized(preferences) { +			save_common_frequencies(frequencies); +			flush_preferences(); +		} +	}  } diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 008bd097..d6fd0e6d 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -16,6 +16,7 @@ altosui_JAVA = \  	AltosChannelMenu.java \  	AltosConfig.java \  	AltosConfigData.java \ +	AltosConfigFreqUI.java \  	AltosConfigUI.java \  	AltosConfigureUI.java \  	AltosConvert.java \ @@ -50,6 +51,7 @@ altosui_JAVA = \  	AltosFlightReader.java \  	AltosFlightStatus.java \  	AltosFlightUI.java \ +	AltosFrequency.java \  	AltosGPS.java \  	AltosGPSSat.java \  	AltosGreatCircle.java \ | 
