package com.aerodynelabs.habtk.tracking; import java.awt.Container; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.SpringLayout; import com.aerodynelabs.habtk.connectors.APRSIS; import com.aerodynelabs.habtk.connectors.APRSSource; import com.aerodynelabs.habtk.connectors.parsers.APRSPacket; import com.aerodynelabs.map.MapPoint; public class APRSTracker extends Tracker { private static APRSIS aprsis = null; // private static AGWPE agwpe = null; private String callsign; private APRSSource source; @SuppressWarnings("serial") class SetupDialog extends JDialog { private final String options[] = { "APRS-IS" }; boolean accepted = false; JTextField fCallsign; JComboBox<String> fConnector; JTextField fName; public SetupDialog() { setTitle("Setup APRS Tracker"); setModal(true); SpringLayout layout = new SpringLayout(); setLayout(layout); Container pane = getContentPane(); JLabel lCallsign = new JLabel("Callsign:"); fCallsign = new JTextField(10); layout.putConstraint(SpringLayout.NORTH, fCallsign, 6, SpringLayout.NORTH, pane); layout.putConstraint(SpringLayout.BASELINE, lCallsign, 0, SpringLayout.BASELINE, fCallsign); layout.putConstraint(SpringLayout.WEST, lCallsign, 6, SpringLayout.WEST, pane); layout.putConstraint(SpringLayout.WEST, fCallsign, 6, SpringLayout.EAST, lCallsign); layout.putConstraint(SpringLayout.EAST, fCallsign, -6, SpringLayout.EAST, pane); add(lCallsign); add(fCallsign); JLabel lConnector = new JLabel("Connector:"); fConnector = new JComboBox<>(options); fName = new JTextField(30); fName.setEditable(false); JButton bConnector = new JButton("Configure"); bConnector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { callsign = fCallsign.getText(); if(fConnector.getSelectedItem().equals("APRS-IS")) { boolean reconfig = false; if(aprsis != null) { // Connection already exists int n = JOptionPane.showConfirmDialog(null, "APRS-IS is already configured.\n" + "Would you like to reconfigure?", "APRS-IS Configuration", JOptionPane.YES_NO_OPTION); if(n == JOptionPane.YES_OPTION) { reconfig = true; } else { source = aprsis; aprsis.addFilter("f/" + callsign + "/100"); aprsis.addFilter("b/" + callsign); } } if(aprsis == null || reconfig == true) { // Connection has not been created String serverCall = (String)JOptionPane.showInputDialog("APRS-IS Callsign:"); String serverPass = null; if(serverCall != null) serverPass = (String)JOptionPane.showInputDialog("APRS-IS Passcode:"); if(serverPass == null) { accepted = false; return; } else { APRSIS server = new APRSIS("midwest.aprs2.net", 14580, serverCall, serverPass); if(server.isValid()) { server.addFilter("f/" + callsign + "/100"); server.addFilter("b/" + callsign); aprsis = server; source = aprsis; // fName.setText(callsign + ": " + server.toString()); } else { accepted = false; return; } } } } // Add more connector types here fName.setText(callsign + ": " + source.toString()); } }); layout.putConstraint(SpringLayout.NORTH, fConnector, 6, SpringLayout.SOUTH, fCallsign); layout.putConstraint(SpringLayout.BASELINE, lConnector, 0, SpringLayout.BASELINE, fConnector); layout.putConstraint(SpringLayout.WEST, lConnector, 6, SpringLayout.WEST, pane); layout.putConstraint(SpringLayout.WEST, fConnector, 6, SpringLayout.EAST, lConnector); layout.putConstraint(SpringLayout.EAST, fConnector, -6, SpringLayout.EAST, pane); layout.putConstraint(SpringLayout.NORTH, fName, 6, SpringLayout.SOUTH, fConnector); layout.putConstraint(SpringLayout.NORTH, bConnector, 0, SpringLayout.NORTH, fName); layout.putConstraint(SpringLayout.SOUTH, bConnector, 0, SpringLayout.SOUTH, fName); layout.putConstraint(SpringLayout.WEST, fName, 6, SpringLayout.WEST, pane); layout.putConstraint(SpringLayout.WEST, bConnector, 6, SpringLayout.EAST, fName); layout.putConstraint(SpringLayout.EAST, pane, 6, SpringLayout.EAST, bConnector); add(lConnector); add(fConnector); add(fName); add(bConnector); JButton cancel = new JButton("Cancel"); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { accepted = false; dispose(); } }); JButton ok = new JButton("Accept"); ok.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { // XXX validate callsign boolean validCall = true; accepted = (validCall || source.isValid()); } catch(Exception e1) { e1.printStackTrace(); accepted = false; } dispose(); } }); layout.putConstraint(SpringLayout.NORTH, ok, 6, SpringLayout.SOUTH, bConnector); layout.putConstraint(SpringLayout.SOUTH, pane, 6, SpringLayout.SOUTH, ok); layout.putConstraint(SpringLayout.BASELINE, cancel, 0, SpringLayout.BASELINE, ok); layout.putConstraint(SpringLayout.EAST, ok, -6, SpringLayout.EAST, pane); layout.putConstraint(SpringLayout.EAST, cancel, -6, SpringLayout.WEST, ok); add(cancel); add(ok); pack(); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((screen.width - getWidth()) / 2, (screen.height - getHeight()) / 2); setVisible(true); } public boolean wasAccepted() { return accepted; } } public String getCallsign() { return callsign; } public APRSSource getSource() { return source; } public APRSTracker() { } @Override public boolean setup() { SetupDialog dialog = new SetupDialog(); return dialog.wasAccepted(); } @Override public String toString() { return callsign + ": " + source.toString(); } @Override public boolean isReady() { return source.isReady(); } @Override public MapPoint getPacket() { MapPoint position = null; if(source.isReady() == true) { String line = source.readLine(); APRSPacket pkt = new APRSPacket(line); if(pkt.isPosition() == true) { if(pkt.getFrom().equalsIgnoreCase(callsign)) position = new MapPoint(pkt.getLatitude(), pkt.getLongitude(), pkt.getAltitude(), pkt.getTimestamp() / 1000, pkt.getFrom()); } } return position; } }