package nbtool.gui.utilitypanes; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.List; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.net.InetAddress; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.Vector; import javax.swing.DefaultListModel; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.SwingUtilities; import nbtool.util.Debug; import nbtool.util.Robots; import nbtool.util.Robots.Robot; public class ReachableRobots extends UtilityParent { private static Display display = null; @Override public JFrame supplyDisplay() { if (display != null) { return display; } else { start(); return (display = new Display()); } } @Override public String purpose() { return "look for reachable robots"; } @Override public char preferredMemnonic() { return 'r'; } private static class Display extends JFrame { final Set<String> reachable = new HashSet<>(); final JList<String> list; Display() { super("reachable robots"); list = new JList<String>(); this.getContentPane().add(list, BorderLayout.CENTER); this.setMinimumSize(new Dimension(300,600)); pack(); this.addComponentListener(new ComponentAdapter(){ @Override public void componentHidden(ComponentEvent e) { Debug.print("reachable robots hidden."); running = false; } @Override public void componentShown(ComponentEvent e) { Debug.print("reachable robots shown."); running = true; } }); } void doUpdate(String name, boolean up) { if (up) { reachable.add(name); } else { reachable.remove(name); } DefaultListModel<String> model = new DefaultListModel<String>(); for (String n : reachable) model.addElement(n); list.setModel(model); } } protected static void update(final String name, final boolean up) { SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { if (display != null) { display.doUpdate(name, up); } } }); } public static boolean running = false; private static String[] addresses = new String[Robots.ROBOT_HOSTNAMES.size()]; private static Reach[] reachers = new Reach[addresses.length]; private static Thread[] threads = new Thread[reachers.length]; public static void start() { assert(!running); addresses = Robots.ROBOT_HOSTNAMES.toArray(new String[0]); synchronized(reachers) { for (int i = 0; i < threads.length; ++i) { String addr = addresses[i]; reachers[i] = new Reach(i, addr); threads[i] = new Thread(reachers[i]); threads[i].setDaemon(true); threads[i].setName("reach-" + addresses[i]); } for (Thread t : threads) { t.start(); } } running = true; } private static class Reach implements Runnable { private final int loopTime = 1000; int index; String addr; protected Reach(int i, String a) { this.index = i; this.addr = a; } @Override public void run() { boolean last = false; long lastTime = System.currentTimeMillis(); for(;;) { try { if (running) { boolean reached = false; try { reached = InetAddress.getByName(addr).isReachable(loopTime); // Debug.print("returned %B", reached); } catch (Exception e) { /* Debug.error("%s", e.getMessage()); */} if (reached != last) { Debug.print("reach (%B -> %B) now %B for %s", last, reached, reached, addr); update(addr, reached); } last = reached; long elapsed = System.currentTimeMillis() - lastTime; // Debug.print("%d elapsed", elapsed); if (elapsed < loopTime) Thread.sleep(loopTime - elapsed); lastTime = System.currentTimeMillis(); } else { Thread.sleep(loopTime * 5); } } catch (Exception e) { } } } } public static void main(String[] args) throws InterruptedException { // running = true; // new Reach(0, "10.211.55.2").run(); // new Reach(0, "127.0.0.1").run(); start(); for(;;) Thread.sleep(1000); } }