2015-12-08 45 views
0

在我的项目中,当客户端断开连接时,服务器将从可观察列表中删除名称,并且tableview应该停止显示名称。但是tableview并没有更新。 Controller类在JAVA中自动更新Tableview Fx

public class Controller { 

@FXML 
public TableView tableView; 

@FXML 
private TableColumn<clientLoginData,String> client; 
@FXML 
private TableColumn<clientLoginData,String> activeTime; 
void initialize(ObservableList<clientLoginData> data) 
{ 
    client.setCellValueFactory(new PropertyValueFactory<>("clientName")); 
    client.setCellFactory(TextFieldTableCell.<clientLoginData>forTableColumn()); 
    activeTime.setCellValueFactory(new PropertyValueFactory<>("time")); 
    activeTime.setCellFactory(TextFieldTableCell.<clientLoginData>forTableColumn()); 
    tableView.setItems(data); 
    tableView.setEditable(true); 

} 

} 

主类

public class Main extends Application{ 
volatile public ObservableList<clientLoginData> data= FXCollections.observableArrayList(); 
public Controller controller; 

@Override 
public void start(Stage primaryStage) throws Exception { 
    FXMLLoader loader = new FXMLLoader(); 
    loader.setLocation(getClass().getResource("server.fxml")); 
    Parent root = loader.load(); 
    data.addAll(new clientLoginData((new SimpleStringProperty("john")),new SimpleStringProperty(ZonedDateTime.now().getHour()+":"+ZonedDateTime.now().getMinute()))); 
    controller=loader.getController(); 
    controller.initialize(data); 
    primaryStage.setTitle("Server"); 
    primaryStage.setScene(new Scene(root, 600, 400)); 
    primaryStage.show(); 
    Thread t=new Thread(new messengerServer(this)); 
    t.start(); 



} 

public static void main(String[] args) { 
    launch(args); 
} 
} 

更新类

public class messengerReadThread implements Runnable { 
private Thread thr; 
private NetworkUtil nc; 
public Hashtable<SimpleStringProperty, NetworkUtil> table; 
SimpleStringProperty oldName; 
Main main; 


public messengerReadThread(NetworkUtil nc, Hashtable<SimpleStringProperty, NetworkUtil> table, SimpleStringProperty s, Main main) { 
    this.nc = nc; 
    this.thr = new Thread(this); 
    thr.start(); 
    this.table=table; 
    oldName=s; 
    this.main=main; 
} 

public void run() { 

    try { 
     while(true) { 
      String s1=(String)nc.read(); 
      StringTokenizer st=new StringTokenizer(s1); 
      if(st.nextToken().equals("Name")) 
      { 
       String sn=s1.substring(5,s1.length()); 
       NetworkUtil n1=table.get(oldName); 
       table.remove(oldName); 
       oldName=new SimpleStringProperty(sn); 
       table.put(oldName, n1); 
       main.data.add(new clientLoginData(oldName,new SimpleStringProperty(ZonedDateTime.now().getHour()+":"+ZonedDateTime.now().getMinute()))); 
      } 
      else 
      { 
       System.out.println("here it is"+s1); 
      } 
     } 
    } catch(Exception e) { 
     System.out.println("disconnected "+oldName.toString()); 
     main.data.remove(oldName); 
     //System.out.println(main.data.contains(oldName)); 

     main.controller.tableView.refresh();//the tableview should update 

    } 
    nc.closeConnection(); 
} 
} 
+0

您的main.data.remove调用将永远不会有任何效果,因为你试图从'List '中移除一个StringProperty。此外,可观察对象的所有修改都需要在应用程序线程上完成。这意味着'main.data.add'和'main.data.remove'必须在[Platform.runLater]中调用(http://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform .html#runLater-java.lang.Runnable-)调用。 – VGR

回答

0

有一些修改我应该到该代码,例如使用那些 “静态引用” 避免,通过定义ObservableList并移动控制器内的更新代码,这样你就可以拥有2个类的代码,主类和你的控制器......但我会尽量保持它的模拟PLE。

首先,您需要在您的控制器中定义ObservableList。

然后将您的“更新”代码放在控制器中的方法中。我建议你使用任务<>来保持你的控制器在JavaFX线程中更新。

尝试这样:

private void updateTable(){ 

    Task<Void> myUpdatingTask=new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
     //Your Updating Code Here 
     } 
    } 

    //and then you run it like this: 
    Thread hilo=new Thread(myUpdatingTask); 
    hilo.setDaemon(true); 
    hilo.start(); 
} 

然后,从初始化方法除去该参数,定义它的私人与@FXML注释是这样的:

@FXML 
private void initialize(){ 
    //Your Stuff to initialize 
    //here is were you fill your table like you did in the Main 
    //and don't forget to call you updateTable Method 
    this.updateTable(); 
} 
-1

因为这是一个肮脏的黑客为由@kleopatra指出,我打算把它装饰成一个肮脏的黑客。 ****************************肮脏的文丐******************* ********************** 尝试隐藏一列并再次显示,并且您的桌面应该刷新

+0

不需要肮脏的黑客:如果所有的协作者都连线正确,更新将自动发生 – kleopatra

+0

@kleopatra我一直在谈论有关这一点,表视图也导致内存泄漏。他们还没有解决这个问题。除非有事件发生,否则我无法在没有肮脏的黑客的情况下更新表格。 。event.getTableView()getItems()获取(event.getTablePosition()的getRow()。)setSomething(event.getNewValue()修剪()。)。 – user1363516

+0

想想你可能会生成自己的事件来更新表格。 – user1363516