package developer.swingtool;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import oculusPrime.State;
import oculusPrime.State.values;
public class StateMonitor extends JFrame {
private static final long serialVersionUID = 1L;
final values[] stateValues = State.values.values();
TableModel model = new StateTableModel();
BufferedReader reader = null;
PrintWriter printer = null;
Socket socket = null;
long rx = 0;
String ip;
int port;
public StateMonitor(String ip, int port) {
this.ip = ip;
this.port = port;
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(new Dimension(500, 800));
table.getColumnModel().getColumn(0).setPreferredWidth(150);
table.getColumnModel().getColumn(0).setMinWidth(100);
table.getColumnModel().getColumn(0).setMaxWidth(250);
table.getColumnModel().getColumn(2).setMaxWidth(60);
// table.repaint();
// table.setEnabled(false);
table.addMouseListener(new MouseListener() {
@Override public void mouseReleased(MouseEvent arg) {}
@Override public void mousePressed(MouseEvent arg) {}
@Override public void mouseExited(MouseEvent arg) {}
@Override public void mouseEntered(MouseEvent arg) {}
@Override // double clicked, force update
public void mouseClicked(MouseEvent arg) {
if(arg.getClickCount() == 2){
int row = table.rowAtPoint(arg.getPoint());
// int col = table.columnAtPoint(arg.getPoint());
// System.out.println("["+row+", "+col+"] "+ table.getValueAt(row, 0));
printer.println("state "+ table.getValueAt(row, 0));
}
}
});
table.addKeyListener(new KeyListener() {
@Override public void keyTyped(KeyEvent e) {}
@Override public void keyPressed(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 10){
String update = "";
if(table.getValueAt(table.getSelectedRow(), 1) != null) update = (String) table.getValueAt(table.getSelectedRow(), 1);
// System.out.println(" ... typed: " + table.getValueAt(table.getSelectedRow(), 0) + " [" + update + "]");
if(update.length() == 0) printer.println("state delete " + table.getValueAt(table.getSelectedRow(), 0));
else printer.println("state " + table.getValueAt(table.getSelectedRow(), 0) + " " + update);
}
}
});
setDefaultCloseOperation(EXIT_ON_CLOSE);
setDefaultLookAndFeelDecorated(true);
setLayout(new GridLayout(1,0));
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
pack();
setVisible(true);
new Timer().scheduleAtFixedRate(new Task(), 2000, 10000);
// new Timer().scheduleAtFixedRate(new nullTask(), Util.TWO_MINUTES, Util.TWO_MINUTES);
}
class StateTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
String[] columnNames = {"state", "value", "count"};
Object[][] data = new Object[State.values.values().length][3];
StateTableModel(){
for(int i = 0; i < stateValues.length; i++){
data[i][0] = stateValues[i].name();
// data[i][1] = "null";
data[i][2] = 0;
}
}
public int getColumnCount() { return columnNames.length; }
public int getRowCount() { return data.length; }
public String getColumnName(int col) { return columnNames[col]; }
public Object getValueAt(int row, int col) { return data[row][col]; }
@SuppressWarnings("unchecked")
public Class getColumnClass(int c) {
if(c == 0 || c == 1) return String.class;
return Integer.class;
}
public boolean isCellEditable(int row, int col) {
if(col == 0 || col == 2) return false;
return true;
}
public void setValueAt(Object value, int row, int col) {
// System.out.println("[" + row + "," + col + "] value = " + value + " " + data[row][0]);
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
private class Task extends TimerTask {
public void run(){
if(printer == null || socket.isClosed()){
openSocket();
try { Thread.sleep(5000); } catch (InterruptedException e) {}
if(socket != null) if(socket.isConnected()) readSocket();
} else {
try {
printer.checkError();
printer.flush();
printer.println("state");
} catch (Exception e) {
System.out.println("TimerTask(): "+e.getMessage());
closeSocket();
}
}
}
}
private class nullTask extends TimerTask {
public void run(){
if(printer == null || socket.isClosed()){
openSocket();
try { Thread.sleep(5000); } catch (InterruptedException e) {}
if(socket != null) if(socket.isConnected()) readSocket();
} else {
try {
printer.checkError();
printer.flush();
for(int i = 0; i < stateValues.length; i++){
if(model.getValueAt(i, 1) == null){
printer.println("state " + stateValues[i].name());
try { Thread.sleep(100); } catch (InterruptedException e) {}
} else {
if(model.getValueAt(i, 1).equals("null")){
printer.println("state " + stateValues[i].name());
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
}
} catch (Exception e) {
System.out.println("TimerTask(): "+e.getMessage());
closeSocket();
}
}
}
}
void openSocket(){
try {
setTitle("trying to connect");
socket = new Socket(ip, port);
printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("openSocket(): connected to: " + socket.getInetAddress().toString());
setTitle(socket.getInetAddress().toString());
rx = 0;
printer.println("state");
} catch (Exception e) {
setTitle("disconnected");
System.out.println("openSocket(): " + e.getMessage());
closeSocket();
}
}
void closeSocket(){
if(printer != null){
printer.close();
printer = null;
}
if(reader != null){
try {
reader.close();
reader = null;
} catch (IOException e) {
System.out.println("closeSocket(): " + e.getLocalizedMessage());
}
}
try {
if(socket != null) socket.close();
} catch (IOException ex) {
System.out.println("closeSocket(): " + ex.getLocalizedMessage());
}
}
void readSocket(){
new Thread(new Runnable() { public void run() {
String input = null;
while(printer != null) {
try {
input = reader.readLine();
if(input == null) {
System.out.println("readSocket(): closing..");
try { Thread.sleep(5000); } catch (InterruptedException e) {}
closeSocket();
break;
}
// ignore dummy messages
input = input.trim();
if(input.length() > 0) {
setTitle(socket.getInetAddress().toString() + " rx: " + rx++);
input = input.replace("<telnet>", "");
input = input.replace("=", "");
input = input.replace(" ", " ");
input = input.trim();
String[] tokens = input.split(" ");
//, System.out.println("[" + input + "] tokens:" + tokens.length);
if(input.contains("deleted")){
for( int i = 0 ; i < model.getRowCount() ; i++ )
if(model.getValueAt(i, 0).equals(tokens[tokens.length-1]))
model.setValueAt(/*table.getValueAt(i, 1) + " (deleted)"*/ null, i, 1);
}
if(input.contains("<state>")){
System.out.println(input);
for( int i = 0 ; i < model.getRowCount() ; i++ ){
if(model.getValueAt(i, 0).equals(tokens[1])){
String value = input.substring(input.indexOf(tokens[2]), input.length());
if( ! value.equals("null")){
model.setValueAt(value, i, 1);
model.setValueAt((int)model.getValueAt(i, 2)+1, i, 2);
}
}
}
}
if(tokens.length == 2){
System.out.println("[" + input + "] tokens:" + tokens.length);
for( int i = 0 ; i < model.getRowCount() ; i++ ){
if(model.getValueAt(i, 0).equals(tokens[0])){
model.setValueAt(tokens[1], i, 1);
model.setValueAt((int)model.getValueAt(i, 2)+1, i, 2);
}
}
}
}
} catch (Exception e) {
System.out.println("readSocket(): "+e.getMessage());
closeSocket();
}
}
}}).start();
}
public static void main(String[] args) {
String ip = args[0];
int port = Integer.parseInt(args[1]);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new StateMonitor(ip, port);
}
});
}
}