2016-04-22 36 views
0

表包含以下行(只是举例一列):拖放项目到TableView中,已有行之间

A 
B 
C 

我试图找出如何拖动一个项目到它,并有它放置在现有的行B和C之间。

我能够拖放并导致在表格末尾添加项目,但我无法弄清楚如何将它放在行之间,基于在我释放鼠标按钮的位置。

回答

2

创建一个接受的姿态,通过鼠标的位置决定,是否要行之前或之后添加的项目rowFactory生产TableRow S:

@Override 
public void start(Stage primaryStage) { 
    TableView<Item> table = new TableView<>(); 

    Button button = new Button("A"); 

    // d&d source providing next char 
    button.setOnDragDetected(evt -> { 
     Dragboard db = button.startDragAndDrop(TransferMode.MOVE); 
     ClipboardContent content = new ClipboardContent(); 
     content.putString(button.getText()); 
     db.setContent(content); 
    }); 
    button.setOnDragDone(evt -> { 
     if (evt.isAccepted()) { 
      // next char 
      button.setText(Character.toString((char) (button.getText().charAt(0) + 1))); 
     } 
    }); 

    // accept for empty table too 
    table.setOnDragOver(evt -> { 
     if (evt.getDragboard().hasString()) { 
      evt.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
     } 
     evt.consume(); 
    }); 
    table.setOnDragDropped(evt -> { 
     Dragboard db = evt.getDragboard(); 
     if (db.hasString()) { 
      table.getItems().add(new Item(db.getString())); 
      evt.setDropCompleted(true); 
     } 
     evt.consume(); 
    }); 

    TableColumn<Item, String> col = new TableColumn<>("value"); 
    col.setCellValueFactory(new PropertyValueFactory<>("value")); 
    table.getColumns().add(col); 

    // let rows accept drop too 
    table.setRowFactory(tv -> { 
     TableRow<Item> row = new TableRow(); 
     row.setOnDragOver(evt -> { 
      if (evt.getDragboard().hasString()) { 
       evt.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
      } 
      evt.consume(); 
     }); 
     row.setOnDragDropped(evt -> { 
      Dragboard db = evt.getDragboard(); 
      if (db.hasString()) { 
       Item item = new Item(db.getString()); 
       if (row.isEmpty()) { 
        // row is empty (at the end -> append item) 
        table.getItems().add(item); 
       } else { 
        // decide based on drop position whether to add the element before or after 
        int offset = evt.getY() > row.getHeight()/2 ? 1 : 0; 
        table.getItems().add(row.getIndex() + offset, item); 
        evt.setDropCompleted(true); 
       } 
      } 
      evt.consume(); 
     }); 
     return row; 
    }); 

    Scene scene = new Scene(new VBox(button, table)); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
public class Item { 

    public Item() { 
    } 

    public Item(String value) { 
     this.value.set(value); 
    } 

    private final StringProperty value = new SimpleStringProperty(); 

    public String getValue() { 
     return value.get(); 
    } 

    public void setValue(String val) { 
     value.set(val); 
    } 

    public StringProperty valueProperty() { 
     return value; 
    } 

}