2017-06-01 2 views
0

Ich machte ein kleines funktionierendes Beispielprogramm für das Problem, das ich habe. Bitte daran denkt, dass mein wirkliches Programm komplexer ist und alle diese Klassen benötigt werden, auch wenn es in dieser kleinen StichprobeTableView aktualisiert nicht auf neuen Informationen von Threads

Hauptklasse überdimensionierte sieht:

public class PingTest extends Application { 

private static final ArrayList<PingThread> THREADS = new ArrayList(); 

@Override 
public void start(Stage primaryStage) { 

    AnchorPane root = new AnchorPane(); 
    TableView<Map.Entry<String, Ping>> tblPing = new TableView(); 
    TableColumn<Map.Entry<String, Ping>, String> colName = new TableColumn("Name"); 
    TableColumn<Map.Entry<String, Ping>, String> colTime = new TableColumn("Time"); 
    TableColumn<Map.Entry<String, Ping>, String> colDifference = new TableColumn("Difference"); 

    colName.setCellValueFactory((TableColumn.CellDataFeatures<Map.Entry<String, Ping>, String> p) -> new SimpleStringProperty(p.getValue().getKey())); 
    colTime.setCellValueFactory((TableColumn.CellDataFeatures<Map.Entry<String, Ping>, String> p) -> new SimpleStringProperty(Integer.toString(p.getValue().getValue().getTime()))); 
    colDifference.setCellValueFactory((TableColumn.CellDataFeatures<Map.Entry<String, Ping>, String> p) -> new SimpleStringProperty(Integer.toString(p.getValue().getValue().getDifference()))); 

    ObservableList<Map.Entry<String, Ping>> items = FXCollections.observableArrayList(Pings.getPings().entrySet()); 
    tblPing.setItems(items); 

    Scene scene = new Scene(root, 300, 750); 

    // Align to pane 
    AnchorPane.setTopAnchor(tblPing, 0.0); 
    AnchorPane.setLeftAnchor(tblPing, 0.0); 
    AnchorPane.setRightAnchor(tblPing, 0.0); 
    AnchorPane.setBottomAnchor(tblPing, 0.0); 

    tblPing.getColumns().addAll(colName, colTime, colDifference); 
    root.getChildren().add(tblPing); 

    // Setting primary Stage 
    primaryStage.setOnCloseRequest(e -> { 
     THREADS.forEach(t -> t.interrupt()); 
    }); 
    primaryStage.setTitle("Ping List"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

} 

public static void main(String[] args) { 
    // Some examples 
    String[] servers = {"www.google.com", "www.bing.com", "www.yahoo.com", "www.stackoverflow.com"}; 

    // Start Threads 
    for (String server : servers) { 
     PingThread pingThread = new PingThread(server); 
     pingThread.start(); 
     THREADS.add(pingThread); 
    } 
    launch(args); 
} 

}

Helper Class

public class Ping { 

private int difference; 
private int time; 
private final String url; 

public Ping(String url,int time) { 
    this.url = url; 
    this.time = time; 
    difference = 0; 
} 

public int getDifference() { 
    return difference; 
} 

public int getTime() { 
    return time; 
} 

public void setTime(int time) { 
    difference = time - this.time; 
    this.time = time; 
} 

public String getUrl() { 
    return url; 
} 

} 

Themen

public class PingThread extends Thread { 

private final String SERVER; 
private int ping = 0; 

public PingThread(String server) { 
    SERVER = server; 
} 

@Override 
public void run() { 
    try { 
     while (true) { 
      // Ping, update then sleep 
      ping(); 
      Pings.update(SERVER, ping); 
      Thread.sleep(1000); 
     } 
    } catch (InterruptedException ex) { 
     // Used to end thread 
    } 
} 

public void ping() { 
    try { 
     // Sendinging request 
     InetAddress host = InetAddress.getByName(SERVER); 
     long tm = System.nanoTime(); 
     Socket so = new Socket(host, 80); 
     so.close(); 
     ping =(int)((System.nanoTime() - tm)/1000000L); 
    } catch (IOException ex) { 
    } 

} 

}

Data Container

public class Pings { 

private static final ConcurrentHashMap<String,Ping> PINGS= new ConcurrentHashMap(); 

public static synchronized void update(String server, int time) { 
    if (PINGS.containsKey(server)) { 
     PINGS.get(server).setTime(time); 
    } else { 
     PINGS.put(server, new Ping(server,time)); 
    } 
} 
public static synchronized ConcurrentHashMap<String,Ping> getPings(){ 
    return PINGS; 
} 
} 

Die GUI-Tabelle ist nicht auf neue Werte zu aktualisieren, in meiner größeren Implementierung wie in diesem kleinen Beispiel. Was mache ich falsch, wenn ich die Werte an TableView anbinde?

Antwort

0

Es gibt eine Reihe von Problemen mit diesem Code.

Die unmittelbarste ist, dass

erstellt eine neue beobachtbaren Liste und fügt alles in Pings.getPings().entrySet() es

FXCollections.observableArrayList(Pings.getPings().entrySet()); 
aufrufen. Wenn Sie jedoch anschließend die Menge ändern, mit der sie erstellt wurde, wird die beobachtbare Liste nicht geändert, sodass sich die Tabelle nicht ändert. Sie müssen die beobachtbare Liste im Modell speichern ( Pings) und direkt aktualisieren.

Sie müssen auch das Update für den FX-Anwendungs-Thread durchführen, und Sie müssen JavaFX-Eigenschaften in Ihrer Ping-Klasse verwenden, damit die Tabelle Änderungen an diesen Werten beobachten kann.

So:

public class Ping { 

    private final ReadOnlyIntegerWrapper difference = new ReadOnlyIntegerWrapper(); 
    private final ReadOnlyIntegerWrapper time = new ReadOnlyIntegerWrapper(); 
    private final String url; 

    public Ping(String url,int time) { 
     this.url = url; 
     setTime(time); 
     difference.set(0); 
    } 

    public ReadOnlyIntegerProperty differenceProperty() { 
     return difference.getReadOnlyProperty() ; 
    } 

    public final int getDifference() { 
     return differenceProperty().get(); 
    } 

    public ReadOnlyIntegerProperty timeProperty() { 
     return time ; 
    } 

    public final int getTime() { 
     return timeProperty().get(); 
    } 

    public void setTime(int time) { 
     difference.set(time - getTime()); 
     this.time.set(time); 
    } 

    public String getUrl() { 
     return url; 
    } 

} 

Die Daten auf dem FX Anwendung Faden muss verändert werden, so dass Ihre Datencontainer als auch können Single-Threaded:

public class Pings { 

    private static final Map<String,Ping> PINGS= new HashMap<>(); 
    private static final ObservableList<Ping> pingList = FXCollections.observableArrayList(); 

    public static void update(String server, int time) { 
     if (PINGS.containsKey(server)) { 
      PINGS.get(server).setTime(time); 
     } else { 
      Ping ping = new Ping(server, time); 
      pingList.add(ping); 
      PINGS.put(server, ping); 
     } 
    } 
    public static ObservableList<Ping> getPings(){ 
     return pingList; 
    } 

} 

nun die Fäden tun:

public class PingThread extends Thread { 

    private final String SERVER; 

    public PingThread(String server) { 
     SERVER = server; 
    } 

    @Override 
    public void run() { 
     try { 
      while (true) { 
       // Ping, update then sleep 
       final int ping = ping(); 
       // again, not exactly sure how you want to handle exceptions... 
       if (ping >= 0) { 
        Platform.runLater(() -> Pings.update(SERVER, ping)); 
       } 
       Thread.sleep(1000); 
      } 
     } catch (InterruptedException ex) { 
      // Used to end thread 
     } 
    } 

    public int ping() { 
     try { 
      // Sendinging request 
      InetAddress host = InetAddress.getByName(SERVER); 
      long tm = System.nanoTime(); 
      Socket so = new Socket(host, 80); 
      so.close(); 
      return (int)((System.nanoTime() - tm)/1000000L); 
     } catch (IOException ex) { 
      return -1 ; // or handle exception? 
     } 

    } 

} 

und legen Sie endlich den Tisch wie:

TableView<Ping> tblPing = new TableView<>(); 
TableColumn<Ping, String> colName = new TableColumn<>("Name"); 
TableColumn<Ping, Number> colTime = new TableColumn<>("Time"); 
TableColumn<Ping, Number> colDifference = new TableColumn<>("Difference"); 

colName.setCellValueFactory(p -> new SimpleStringProperty(p.getValue())); 
colTime.setCellValueFactory(p -> p.getValue().timeProperty()); 
colDifference.setCellValueFactory(p -> p.getValue().differenceProperty()); 

tblPing.getColumns().addAll(colName, colTime, colDifference); 

tblPing.setItems(Pings.getPings()); 
+0

Vielen Dank für Ihre umfassende Erklärung – chenino

Verwandte Themen