2016-07-05 44 views
1

我正在设计一个应用程序,允许在TableView单元上拖放。如何在拖放事件完成后在javafx tablecell中设置单元值?

但是,一旦拖放完成并且单元格的值切换成功,双击已拖动和拖放的单元格可使单元格在更改后拖回原来的文本。

帮我解决这个问题。以下代码用于为所有单元设置cellFactoryValue。我是javafx的新手。

private void setCellFactoryForColumns(TableColumn<TimeTable, String> col) 
{ 
    col.setCellFactory((TableColumn<TimeTable, String> e) -> { 
     TableCell<TimeTable, String> cell = new TableCell<TimeTable, String>() { 
      @Override 
      public void updateItem(String item, boolean empty) { 

       super.updateItem(item, empty); 
       if (item == null || empty) { 
        setText(null); 
        setGraphic(null); 
       } else { 
        setText(item); 
        setGraphic(null); 
       } 
      } 
     }; 

     col.setOnEditCommit((CellEditEvent<TimeTable, String> t) -> { 
      ((TimeTable)t.getTableView().getItems().get(
        t.getTablePosition().getRow()) 
        ).setDay(t.getNewValue()); 
     }); 

     cell.setOnDragDetected((MouseEvent event) -> { 
      Dragboard db = cell.startDragAndDrop(TransferMode.ANY); 

      ClipboardContent content = new ClipboardContent(); 
      content.putString(cell.getText()); 
      db.setContent(content); 
      cell.setStyle("-fx-background-color: red;" 
         + "-fx-text-fill: white;"); 
      cell.startEdit(); 
      cell.setText("Dragged"); 

      event.consume(); 
     }); 

     cell.setOnDragOver((DragEvent event) ->{ 
      if(event.getGestureSource() != cell && 
        event.getDragboard().hasString()) 
      { 
       event.acceptTransferModes(TransferMode.MOVE); 
       cell.setStyle("-fx-background-color: green;" 
         + "-fx-text-fill: white;"); 
      } 
      event.consume(); 
     }); 

     cell.setOnDragEntered((DragEvent event) ->{ 
      if(event.getGestureSource() != cell && 
        event.getDragboard().hasString()){ 
       cell.setStyle("-fx-background-color: yellow;"); 
      } 
      event.consume(); 
     }); 

     cell.setOnDragExited((DragEvent event) -> { 
      cell.setStyle("-fx-background-color: grey;"); 
      event.consume(); 
     }); 

     cell.setOnDragDropped((DragEvent event) -> { 
      Dragboard db = event.getDragboard(); 
      boolean success = false; 
      if(db.hasString()) 
      { 
       holdData = cell.getText(); 
       cell.setText(db.getString()); 
       success = true; 
      } 

      event.setDropCompleted(success); 
      event.consume(); 
     }); 

     cell.setOnDragDone((DragEvent event) ->{ 
      if(event.getTransferMode() == TransferMode.MOVE) 
      { 
       cell.setText(holdData); 
      } 
      event.consume(); 
     }); 
     return cell; 
    }); 
} 

回答

1

您只需更改单元格中的文本,而不是项目的属性。因此,每次将新项目分配给TableCell时,旧值都将用作文本。

如果您将包含项目的单元格滚动到视图外,也会发生这种情况。

要解决这个问题替换onDragDone/onDragDropped处理程序

cell.setText(db.getString()); 

cell.setText(holdData); 

陈述与

update(cell, db.getString()); 

update(cell, holdData); 

分别实现update方法是这样的:

static void update(TableCell<TimeTable, String> cell, String newValue) { 
    ((TableRow<TimeTable>)cell.getTableRow()).getItem().setDay(newValue); 
    // the below line would be needed, if the setter does not trigger 
    // a update of the ObservableValue returned by the cellValueFactory 
    // cell.getTableView().refresh(); 
} 

如果您cellValueFactory回报WritableProperty,允许写入项目,该方法可以写成更一般为

static <I,P>void update(TableCell<I, P> cell, P newValue) { 
    WritableValue<P> property = (WritableValue<P>) cell.getTableColumn().getCellObservableValue(((TableRow<I>)cell.getTableRow()).getItem()); 
    property.setValue(newValue); 
} 
+0

怎么办我实现更新方法?我是新来的javafx,不知道我到底能完成什么.. – Githiora

+0

我已经发布了一个,但更新'方法的2个版本...没有关于'TimeTable'类的更多信息和列的“cellValueFactory”我不能告诉你哪一个可以使用。 – fabian

+0

非常感谢你......解决方案的工作...... @fabian – Githiora