title: Updating tableview javafx without block UI thread
body: <p>I am constantly pulling data (about 10-15 items) from my database (every 2 seconds) 
  everytime it updates the ui just freezes.</p>
  
  <p>I've tried using scheduledservice, thread and tasks in order to update the UI but it always freezes. </p>
  
  <p>I've also tried using observable list for the tableview and just removeAll() and addAll() (according to <a href="https://stackoverflow.com/questions/11065140/javafx-2-1-tableview-refresh-items">JavaFX 2.1 TableView refresh items</a>)</p>
  
  <p>Is there a way to avoid blocking the ui thread?</p>
  
  <p>EDITED:</p>
  
  <p>It doesn't lag if I remove the tableViewConcern.getItems().setAll(service.getValue()); part but as soon as I start adding stuff into the database it becomes slower and slower (until it stops).</p>
  
  <p>Inside my <strong>ActiveConcernService</strong> (ScheduledService) it just gets data from the database.</p>
  
  <pre><code>public class ActiveConcernService extends ScheduledService&lt;ObservableList&lt;Concern&gt;&gt; {
      private UserAccount currentUser;
      public ActiveConcernService(UserAccount currentUser) {
          this.currentUser = currentUser;
      }
  
  public final ObservableList&lt;Concern&gt; getConcerns() {
      ObservableList&lt;Concern&gt; concerns;
      if(RoleService.getInstance().getById(currentUser.getRoleId()).getTitle().equals(Role.DefaultRole.ADMIN.getRole())){
          concerns = FXCollections.observableList(ConcernService.getInstance().allNotDone());         
      } else {
          concerns = FXCollections.observableList(ConcernService.getInstance().allByUser(currentUser));           
      }
      return concerns; //gets the data from database base on the user role
  }
  
  @Override
  protected Task&lt;ObservableList&lt;Concern&gt;&gt; createTask() {
      return new Task&lt;ObservableList&lt;Concern&gt;&gt;() {
          @Override
          protected ObservableList&lt;Concern&gt; call() {
              return getConcerns();
          }
      };
  }
  </code></pre>
  
  <p>And in my Controller this is how I initialize my table column header and the scheduledservice does are the only two part where the table is being used. </p>
  
  <pre><code>@Override
  public void initialize(URL arg0, ResourceBundle arg1) {
      // Initializes other ui elements (textfield, button, choicebox, etc)
      initializeConcernTable();
      ActiveConcernService service = new ActiveConcernService(currentUser);
      service.setPeriod(Duration.millis(2000));
      service.setOnSucceeded((t) -&gt; {
          tableViewConcern.getItems().setAll(service.getValue()); //Everytime this executes it lags
      });
      service.start();
  }
  
  private void initializeConcernTable() {
  
      TableColumn&lt;Concern, String&gt; clientColumn = new TableColumn&lt;&gt;(Concern.NAME_HEADER);
      clientColumn.setCellValueFactory(param -&gt; param.getValue().getClientNameProperty());
      clientColumn.setMinWidth(125);
      clientColumn.setSortable(false);
  
      TableColumn&lt;Concern, String&gt; remarkColumn = new TableColumn&lt;&gt;(Concern.REMARK_HEADER);
      remarkColumn.setCellValueFactory(param -&gt; param.getValue().getRemarkProperty());
      remarkColumn.setMinWidth(175);
      remarkColumn.setSortable(false);
  
      TableColumn&lt;Concern, String&gt; categoryColumn = new TableColumn&lt;&gt;(Concern.CATEGORY_HEADER);
      categoryColumn.setCellValueFactory(param -&gt; new SimpleStringProperty(
              CategoryService.getInstance().getById(param.getValue().getCatergoryId()).getTitle()));
      categoryColumn.setMinWidth(150);
      categoryColumn.setSortable(false);
  
      TableColumn&lt;Concern, String&gt; assignToColumn = new TableColumn&lt;&gt;(Concern.EMPLOYEE_HEADER);
      assignToColumn.setCellValueFactory(param -&gt; new SimpleStringProperty(
              UserAccountService.getInstance().getById(param.getValue().getUserAccountId()).getName()));
      assignToColumn.setMinWidth(125);
      assignToColumn.setSortable(false);
  
      TableColumn&lt;Concern, String&gt; numberColumn = new TableColumn&lt;&gt;(Concern.NUMBER_HEADER);
      numberColumn.setCellValueFactory(param -&gt; new ReadOnlyObjectWrapper&lt;String&gt;(param.getValue().getNumber() + ""));
      numberColumn.setSortable(false);
  
      TableColumn&lt;Concern, String&gt; dateColumn = new TableColumn&lt;&gt;(Concern.DATE_HEADER);
      dateColumn.setCellValueFactory(param -&gt; new SimpleStringProperty(
              param.getValue().getIssuedOn().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))));
      dateColumn.setPrefWidth(150);
      dateColumn.setSortable(false);
  
      tableViewConcern.getColumns().addAll(numberColumn, assignToColumn, clientColumn, categoryColumn, remarkColumn,
              dateColumn);
  }
  </code></pre>