summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben.burwell@trifecta.com>2016-11-15 23:43:08 -0500
committerBen Burwell <ben.burwell@trifecta.com>2016-11-15 23:43:08 -0500
commit54b0fab72106672ea1d9ca4d81d782b6bf1c6820 (patch)
tree3928fbfc9e0021d15326caa4500b98db13b0a75b
parente2ae5749a522b0d4d2657a2cac571b1524d33cfa (diff)
Implement data table
-rw-r--r--src/com/benburwell/planes/data/Aircraft.java66
-rw-r--r--src/com/benburwell/planes/data/Position.java46
-rw-r--r--src/com/benburwell/planes/gui/AircraftTableModel.java65
-rw-r--r--src/com/benburwell/planes/gui/Main1090.java61
-rw-r--r--src/com/benburwell/planes/sbs/AggregateDataSource.java31
-rw-r--r--src/com/benburwell/planes/sbs/DataSource.java2
-rw-r--r--src/com/benburwell/planes/sbs/SBSPacket.java122
-rw-r--r--src/com/benburwell/planes/sbs/TCPDataSource.java63
8 files changed, 413 insertions, 43 deletions
diff --git a/src/com/benburwell/planes/data/Aircraft.java b/src/com/benburwell/planes/data/Aircraft.java
new file mode 100644
index 0000000..71ee5b5
--- /dev/null
+++ b/src/com/benburwell/planes/data/Aircraft.java
@@ -0,0 +1,66 @@
+package com.benburwell.planes.data;
+
+import com.benburwell.planes.sbs.SBSPacket;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Created by ben on 11/15/16.
+ */
+public class Aircraft implements Comparable<Aircraft> {
+ private final String hexIdent;
+ private Position currentPosition = new Position();
+ private List<Position> positionHistory = new ArrayList<>();
+ private String callsign = "";
+ private String squawk = "";
+ private long packetCount = 0;
+
+ public Aircraft(String hexIdent) {
+ this.hexIdent = hexIdent;
+ }
+
+ public void handleUpdate(SBSPacket packet) {
+ this.packetCount++;
+ if (packet.getAltitude() != null) {
+ this.currentPosition.setAltitude(packet.getAltitude());
+ }
+ if (packet.getLatitude() != null) {
+ this.currentPosition.setLatitude(packet.getLatitude());
+ }
+ if (packet.getLongitude() != null) {
+ this.currentPosition.setLongitude(packet.getLongitude());
+ }
+ if (packet.getCallsign() != null && !packet.getCallsign().isEmpty()) {
+ this.callsign = packet.getCallsign();
+ }
+ if (packet.getSquawk() != null && !packet.getSquawk().isEmpty()) {
+ this.callsign = packet.getSquawk();
+ }
+ }
+
+ public Position getCurrentPosition() {
+ return currentPosition;
+ }
+
+ public String getCallsign() {
+ return callsign;
+ }
+
+ public String getSquawk() {
+ return squawk;
+ }
+
+ public Long getPacketCount() {
+ return packetCount;
+ }
+
+ public String getHexIdent() {
+ return this.hexIdent;
+ }
+
+ @Override
+ public int compareTo(Aircraft that) {
+ return this.getHexIdent().compareTo(that.getHexIdent());
+ }
+}
diff --git a/src/com/benburwell/planes/data/Position.java b/src/com/benburwell/planes/data/Position.java
new file mode 100644
index 0000000..4b37235
--- /dev/null
+++ b/src/com/benburwell/planes/data/Position.java
@@ -0,0 +1,46 @@
+package com.benburwell.planes.data;
+
+import java.util.Date;
+
+/**
+ * Created by ben on 11/15/16.
+ */
+public class Position {
+ private Date timestamp = new Date(System.currentTimeMillis());
+ private Double latitude = 0.0;
+ private Double longitude = 0.0;
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ public double getAltitude() {
+ return altitude;
+ }
+
+ public void setAltitude(double altitude) {
+ this.altitude = altitude;
+ }
+
+ private double altitude = 0;
+}
diff --git a/src/com/benburwell/planes/gui/AircraftTableModel.java b/src/com/benburwell/planes/gui/AircraftTableModel.java
new file mode 100644
index 0000000..72be372
--- /dev/null
+++ b/src/com/benburwell/planes/gui/AircraftTableModel.java
@@ -0,0 +1,65 @@
+package com.benburwell.planes.gui;
+
+import com.benburwell.planes.data.Aircraft;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Created by ben on 11/15/16.
+ */
+public class AircraftTableModel extends AbstractTableModel {
+ private Map<String,Aircraft> aircraftMap;
+ private String[] columnNames = { "Hex", "Callsign", "Squawk", "Latitude", "Longitude", "Altitude", "Packets" };
+
+ public AircraftTableModel(Map<String,Aircraft> aircraftMap) {
+ this.aircraftMap = aircraftMap;
+ }
+
+ @Override
+ public int getRowCount() {
+ return this.aircraftMap.keySet().size();
+ }
+
+ @Override
+ public int getColumnCount() {
+ return this.columnNames.length;
+ }
+
+ @Override
+ public String getColumnName(int col) {
+ return this.columnNames[col];
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ List<Aircraft> aircraftList = this.getAircraftList();
+ Aircraft aircraft = aircraftList.get(rowIndex);
+ switch (columnIndex) {
+ case 0:
+ return aircraft.getHexIdent();
+ case 1:
+ return aircraft.getCallsign();
+ case 2:
+ return aircraft.getSquawk();
+ case 3:
+ return aircraft.getCurrentPosition().getLatitude();
+ case 4:
+ return aircraft.getCurrentPosition().getLongitude();
+ case 5:
+ return aircraft.getCurrentPosition().getAltitude();
+ case 6:
+ return aircraft.getPacketCount();
+ }
+ return "";
+ }
+
+ private List<Aircraft> getAircraftList() {
+ List<Aircraft> aircraftList = new ArrayList<>(this.aircraftMap.values());
+ Collections.sort(aircraftList);
+ return aircraftList;
+ }
+}
diff --git a/src/com/benburwell/planes/gui/Main1090.java b/src/com/benburwell/planes/gui/Main1090.java
index 5393dc0..02ef2bf 100644
--- a/src/com/benburwell/planes/gui/Main1090.java
+++ b/src/com/benburwell/planes/gui/Main1090.java
@@ -5,14 +5,19 @@
package com.benburwell.planes.gui;
import com.benburwell.planes.sbs.*;
+import com.benburwell.planes.data.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
+import java.util.Map;
+import java.util.HashMap;
public class Main1090 extends JFrame {
private AggregateDataSource sbsDataSource = new AggregateDataSource();
+ private Map<String,Aircraft> aircraftMap = new HashMap<>();
+ private int currentTcpConnection = 0;
+ private AircraftTableModel aircraftTableModel = new AircraftTableModel(this.aircraftMap);
public Main1090() {
this.initUI();
@@ -21,6 +26,8 @@ public class Main1090 extends JFrame {
private void initUI() {
this.createMenuBar();
+ this.createTable();
+
this.setTitle("1090");
this.setSize(100, 100);
this.setLocationRelativeTo(null);
@@ -29,27 +36,67 @@ public class Main1090 extends JFrame {
this.openDataSource();
}
+ private void createTable() {
+ JTable table = new JTable(this.aircraftTableModel);
+ table.setFillsViewportHeight(true);
+ JScrollPane scrollPane = new JScrollPane(table);
+ this.add(scrollPane);
+ }
+
private void createMenuBar() {
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("1090");
- file.setMnemonic(KeyEvent.VK_F);
JMenuItem eMenuItem = new JMenuItem("Quit");
- eMenuItem.setMnemonic(KeyEvent.VK_E);
- eMenuItem.setToolTipText("Exit 1090");
+ JMenu data = new JMenu("Data");
+ JMenuItem dataConnectItem = new JMenuItem("Connect...");
+ JMenuItem dataDisconnectItem = new JMenuItem("Disconnect");
+
eMenuItem.addActionListener((ActionEvent event) -> {
System.exit(0);
});
file.add(eMenuItem);
menubar.add(file);
+
+ dataConnectItem.addActionListener((ActionEvent event) -> {
+ if (this.currentTcpConnection == 0) {
+ this.currentTcpConnection = this.addTcpSource("10.0.0.111", 30003);
+ dataConnectItem.setEnabled(false);
+ dataDisconnectItem.setEnabled(true);
+ }
+ });
+ dataDisconnectItem.addActionListener((ActionEvent event) -> {
+ if (this.currentTcpConnection != 0) {
+ this.sbsDataSource.closeSource(this.currentTcpConnection);
+ dataConnectItem.setEnabled(true);
+ dataDisconnectItem.setEnabled(false);
+ this.currentTcpConnection = 0;
+ }
+ });
+ dataDisconnectItem.setEnabled(false);
+ data.add(dataConnectItem);
+ data.add(dataDisconnectItem);
+ menubar.add(data);
+
this.setJMenuBar(menubar);
}
private void openDataSource() {
- System.out.println("asdfasdfasdfasdfasdf");
- this.sbsDataSource.addSource(new TCPDataSource("10.0.0.111", 30003));
this.sbsDataSource.subscribe((SBSPacket packet) -> {
- System.out.println("Got message: " + packet.toString());
+ if (packet.getHexIdent() != null) {
+ if (!this.aircraftMap.containsKey(packet.getHexIdent())) {
+ this.aircraftMap.put(packet.getHexIdent(), new Aircraft(packet.getHexIdent()));
+ }
+ this.aircraftMap.get(packet.getHexIdent()).handleUpdate(packet);
+ this.aircraftTableModel.fireTableDataChanged();
+ }
});
+ this.sbsDataSource.open();
+ }
+
+ private int addTcpSource(String host, int port) {
+ TCPDataSource source = new TCPDataSource(host, port);
+ source.open();
+ return this.sbsDataSource.addSource(source);
}
public static void main(String[] args) {
diff --git a/src/com/benburwell/planes/sbs/AggregateDataSource.java b/src/com/benburwell/planes/sbs/AggregateDataSource.java
index 08b89ea..2850404 100644
--- a/src/com/benburwell/planes/sbs/AggregateDataSource.java
+++ b/src/com/benburwell/planes/sbs/AggregateDataSource.java
@@ -2,22 +2,47 @@ package com.benburwell.planes.sbs;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
/**
* Created by ben on 11/15/16.
*/
public class AggregateDataSource implements DataSource {
private List<DataListener> subscribers = new ArrayList<>();
+ private boolean isOpen = false;
+ private int nextSourceNumber = 1;
+ private Map<Integer,DataSource> sources = new HashMap<>();
- public void addSource(DataSource source) {
+ public int addSource(DataSource source) {
+ int thisSourceNumber = this.nextSourceNumber++;
+ this.sources.put(thisSourceNumber, source);
source.subscribe((SBSPacket packet) -> {
- for (DataListener listener : subscribers) {
- listener.handleMessage(packet);
+ if (isOpen) {
+ for (DataListener listener : subscribers) {
+ listener.handleMessage(packet);
+ }
}
});
+ return thisSourceNumber;
}
public void subscribe(DataListener listener) {
this.subscribers.add(listener);
}
+
+ public void open() {
+ this.isOpen = true;
+ }
+
+ public void close() {
+ this.isOpen = false;
+ }
+
+ public void closeSource(int sourceNumber) {
+ if (this.sources.containsKey(sourceNumber)) {
+ this.sources.get(sourceNumber).close();
+ this.sources.remove(sourceNumber);
+ }
+ }
}
diff --git a/src/com/benburwell/planes/sbs/DataSource.java b/src/com/benburwell/planes/sbs/DataSource.java
index 959e273..961c6e2 100644
--- a/src/com/benburwell/planes/sbs/DataSource.java
+++ b/src/com/benburwell/planes/sbs/DataSource.java
@@ -5,4 +5,6 @@ package com.benburwell.planes.sbs;
*/
public interface DataSource {
void subscribe(DataListener listener);
+ void open();
+ void close();
}
diff --git a/src/com/benburwell/planes/sbs/SBSPacket.java b/src/com/benburwell/planes/sbs/SBSPacket.java
index 0988f3a..5684803 100644
--- a/src/com/benburwell/planes/sbs/SBSPacket.java
+++ b/src/com/benburwell/planes/sbs/SBSPacket.java
@@ -4,35 +4,31 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
-import java.util.DoubleSummaryStatistics;
/**
* Created by ben on 11/15/16.
*/
public class SBSPacket {
private MessageType messageType;
- private TransmissionType transmissionType;
- private String sessionId;
- private String aircraftId;
- private String hexIdent;
- private String flightId;
- private Date dateGenerated;
- private Date dateLogged;
- private String callsign;
- private double altitude;
- private double groundSpeed;
- private double track;
- private double latitude;
- private double longitude;
- private double verticalRate;
- private String squawk;
- private boolean alert;
- private boolean emergency;
- private boolean spi;
- private boolean isOnGround;
-
- public SBSPacket() {
- }
+ private TransmissionType transmissionType = null;
+ private String sessionId = null;
+ private String aircraftId = null;
+ private String hexIdent = null;
+ private String flightId = null;
+ private Date dateGenerated = null;
+ private Date dateLogged = null;
+ private String callsign = null;
+ private Double altitude = null;
+ private Double groundSpeed = null;
+ private Double track = null;
+ private Double latitude = null;
+ private Double longitude = null;
+ private Double verticalRate = null;
+ private String squawk = null;
+ private Boolean alert = null;
+ private Boolean emergency = null;
+ private Boolean spi = null;
+ private Boolean isOnGround = null;
public SBSPacket(String packet) throws MalformedPacketException {
this.parse(packet);
@@ -137,4 +133,84 @@ public class SBSPacket {
public String toString() {
return this.messageType.name();
}
+
+ public MessageType getMessageType() {
+ return messageType;
+ }
+
+ public TransmissionType getTransmissionType() {
+ return transmissionType;
+ }
+
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ public String getAircraftId() {
+ return aircraftId;
+ }
+
+ public String getHexIdent() {
+ return hexIdent;
+ }
+
+ public String getFlightId() {
+ return flightId;
+ }
+
+ public Date getDateGenerated() {
+ return dateGenerated;
+ }
+
+ public Date getDateLogged() {
+ return dateLogged;
+ }
+
+ public String getCallsign() {
+ return callsign;
+ }
+
+ public Double getAltitude() {
+ return altitude;
+ }
+
+ public Double getGroundSpeed() {
+ return groundSpeed;
+ }
+
+ public Double getTrack() {
+ return track;
+ }
+
+ public Double getLatitude() {
+ return latitude;
+ }
+
+ public Double getLongitude() {
+ return longitude;
+ }
+
+ public Double getVerticalRate() {
+ return verticalRate;
+ }
+
+ public String getSquawk() {
+ return squawk;
+ }
+
+ public Boolean isAlert() {
+ return alert;
+ }
+
+ public Boolean isEmergency() {
+ return emergency;
+ }
+
+ public Boolean isSpi() {
+ return spi;
+ }
+
+ public Boolean isOnGround() {
+ return isOnGround;
+ }
}
diff --git a/src/com/benburwell/planes/sbs/TCPDataSource.java b/src/com/benburwell/planes/sbs/TCPDataSource.java
index 6c0e51d..2224d36 100644
--- a/src/com/benburwell/planes/sbs/TCPDataSource.java
+++ b/src/com/benburwell/planes/sbs/TCPDataSource.java
@@ -10,20 +10,67 @@ import java.net.*;
*/
public class TCPDataSource implements DataSource {
private List<DataListener> subscribers = new ArrayList<>();
+ private String host;
+ private int port;
+ private Thread clientThread = null;
+ private SocketClient client = null;
public TCPDataSource(String host, int port) {
- new Thread(() -> {
+ this.host = host;
+ this.port = port;
+ }
+
+ public void subscribe(DataListener listener) {
+ this.subscribers.add(listener);
+ }
+
+ public void open() {
+ this.client = new SocketClient(this.host, this.port);
+ this.clientThread = new Thread(this.client);
+ this.clientThread.start();
+ }
+
+ public void close() {
+ if (this.client != null) {
+ this.client.terminate();
+ try {
+ this.clientThread.join();
+ } catch (InterruptedException ignored) {}
+ }
+ }
+
+ private class SocketClient implements Runnable {
+ private String host;
+ private int port;
+ private Socket clientSocket = null;
+
+ public SocketClient(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+
+ public void terminate() {
+ if (this.clientSocket != null) {
+ try {
+ this.clientSocket.close();
+ } catch (IOException e) {
+ System.out.println("Got exception closing socket: " + e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void run() {
System.out.println("Starting socket client");
- Socket clientSocket;
BufferedReader socketReader;
try {
- clientSocket = new Socket(host, port);
+ this.clientSocket = new Socket(this.host, this.port);
} catch (IOException e) {
- System.out.println("Could not connect to " + host + " on port " + port + ": " + e.getMessage());
+ System.out.println("Could not connect to " + this.host + " on port " + this.port + ": " + e.getMessage());
return;
}
try {
- socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ socketReader = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
System.out.println("Could not create socket reader: " + e.getMessage());
return;
@@ -47,10 +94,6 @@ public class TCPDataSource implements DataSource {
System.out.println(e.getMessage());
}
}
- }).start();
- }
-
- public void subscribe(DataListener listener) {
- this.subscribers.add(listener);
+ }
}
}