出于教育目的,我尝试将TreeTableColumn
拖到TreeTableView
之外的节点上并接受drop
。可能的用例是分组或多级排序。
我在onDragDetected
上搜索TreeTableColumn
,但是此方法不存在。 (TreeTableColumn
的图形默认为null
)
TreeTableView
确实提供了这种方法,但是当我开始拖动列时我没有任何事件。
所以我的尝试是将Label
作为图形放到TreeTableColumn
上。
这使我可以将Column
拖到Table
之外。但这以掉落后的图形故障结束。
关于如何解决此故障或完全摆脱“ TreeTableColumn”中的“ Graphics”包装的任何想法?
这是一个显示我的问题的示例应用程序
public class TreeTableViewSample extends Application {
List<Employee> employees = Arrays.<Employee>asList(new Employee("Ethan Williams", "ethan.williams@example.com"),
new Employee("Emma Jones", "emma.jones@example.com"),
new Employee("Michael Brown", "michael.brown@example.com"),
new Employee("Anna Black", "anna.black@example.com"), new Employee("Rodger York", "roger.york@example.com"),
new Employee("Susan Collins", "susan.collins@example.com"));
final TreeItem<Employee> root = new TreeItem<>(new Employee("Sales Department", ""));
public static void main(String[] args) {
Application.launch(TreeTableViewSample.class, args);
}
@Override
public void start(Stage stage) {
root.setExpanded(true);
employees.stream().forEach((employee) -> {
root.getChildren().add(new TreeItem<>(employee));
});
stage.setTitle("Tree Table View Sample with DND");
final Scene scene = new Scene(new BorderPane(), 400, 400);
scene.setFill(Color.LIGHTGRAY);
BorderPane sceneRoot = (BorderPane) scene.getRoot();
TreeTableColumn<Employee, String> empColumn = new TreeTableColumn<>("Employee");
empColumn.setPrefWidth(150);
empColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param) -> new ReadOnlyStringWrapper(
param.getValue().getValue().getName()));
TreeTableColumn<Employee, String> emailColumn = new TreeTableColumn<>("Email");
emailColumn.setPrefWidth(190);
emailColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param) -> new ReadOnlyStringWrapper(
param.getValue().getValue().getEmail()));
TreeTableView<Employee> treeTableView = new TreeTableView<>(root);
treeTableView.getColumns().setAll(empColumn, emailColumn);
treeTableView.getColumns().stream().forEach((column) -> {
createDragableColumnHeader(column);
});
HBox dndPane = new HBox();
Label dragSource = new Label("<- drag me or a column there");
dragSource.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
Dragboard db = dragSource.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString("dragged the Label");
db.setContent(content);
event.consume();
}
});
/*
* this does not work if an column is dragged... only events outside of
* columns are used - which does not make sense as usually the columns
* cover the whole area
*/
treeTableView.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
Dragboard db = dragSource.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString("dragged the Table ");
db.setContent(content);
event.consume();
}
});
Label dropTarget = new Label("[drop on me!]");
dropTarget.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
if (event.getGestureSource() != dropTarget && event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
});
dropTarget.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
if (event.getGestureSource() != dropTarget && event.getDragboard().hasString()) {
dropTarget.setStyle("-fx-background-color: green;");
}
event.consume();
}
});
dropTarget.setOnDragExited(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
dropTarget.setStyle("");
event.consume();
}
});
dropTarget.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
dropTarget.setText(db.getString());
success = true;
}
event.setDropCompleted(success);
event.consume();
}
});
dndPane.getChildren().addAll(dropTarget, dragSource);
sceneRoot.setTop(dndPane);
sceneRoot.setCenter(treeTableView);
stage.setScene(scene);
stage.show();
}
private void createDragableColumnHeader(TreeTableColumn column) {
Label dragableHeader = new Label("[" + column.getText() + "]");
dragableHeader.setStyle("-fx-background-color: red;");
column.setText(null);
column.setGraphic(dragableHeader);
dragableHeader.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
Dragboard db = dragableHeader.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString("dragged the Column " + dragableHeader.getText());
db.setContent(content);
event.consume();
}
});
dragableHeader.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
System.out.println("dropped. done! - how to fix nasty drag gfx?");
event.consume();
}
});
}
public class Employee {
private SimpleStringProperty name;
private SimpleStringProperty email;
public SimpleStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(this, "name");
}
return name;
}
public SimpleStringProperty emailProperty() {
if (email == null) {
email = new SimpleStringProperty(this, "email");
}
return email;
}
private Employee(String name, String email) {
this.name = new SimpleStringProperty(name);
this.email = new SimpleStringProperty(email);
}
public String getName() {
return name.get();
}
public void setName(String fName) {
name.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}