JavaFX – 检测并突出显示要拖动的TableColumn

发现DragEvent发生在哪个TableColumn(在TableView中)的最佳方法是什么?

我希望能够突出显示(例如,将背景颜色更改为黄色,或在列周围显示黄色边框)作为拖动项目的TableColumn将“hover”在其上方,以使用户明白列他们正在下降。 拖动完成后,我必须确保恢复TableView的样式。

要清楚,正确的细胞被丢弃并不重要 – 只有柱子。

要执行此操作,您需要向每个单元格注册拖动侦听器,以便在拖动单元格时使列更新其样式。 我会使用ObjectProperty来表示当前的“放置目标列”(即正在进行拖动的列),并观察它并从单元格中更新它。 要访问单元格,您需要一个单元工厂。

以下方法将向列添加此类支持。 它还尊重先前附加的单元工厂中定义的任何function:

 private  void configureDropTargetColumn(TableColumn column, ObjectProperty> dropTarget) { Callback, TableCell> currentCellFactory = column.getCellFactory() ; column.setCellFactory(tc -> { TableCell cell = currentCellFactory.call(tc); dropTarget.addListener((obs, oldColumn, newColumn) -> cell.pseudoClassStateChanged(PseudoClass.getPseudoClass("drop-target"), newColumn==column)); cell.setOnDragEntered(e -> dropTarget.set(column)); cell.setOnDragExited(e -> dropTarget.set(null)); return cell ; }); } 

这是使用通常的“联系表”示例的SSCCE:

 import java.util.Arrays; import java.util.List; import java.util.function.Function; import javafx.application.Application; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; import javafx.css.PseudoClass; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.input.ClipboardContent; import javafx.scene.input.Dragboard; import javafx.scene.input.TransferMode; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import javafx.util.Callback; public class TableColumnDropTargetExample extends Application { @Override public void start(Stage primaryStage) { TableView table = new TableView<>(); table.getColumns().add(column("First Name", Person::firstNameProperty)); table.getColumns().add(column("Last Name", Person::lastNameProperty)); table.getColumns().add(column("Email", Person::emailProperty)); ObjectProperty> dropTargetColumn = new SimpleObjectProperty<>(); table.getColumns().forEach(col -> configureDropTargetColumn(col, dropTargetColumn)); table.getItems().addAll(createData()); Label label = new Label("Drag me"); label.getStyleClass().add("drag-source"); label.setOnDragDetected(e -> { Dragboard db = label.startDragAndDrop(TransferMode.COPY_OR_MOVE); ClipboardContent cc = new ClipboardContent(); cc.putString(label.getText()); db.setContent(cc); }); label.setOnDragDone(e -> dropTargetColumn.set(null)); BorderPane root = new BorderPane(table); root.setTop(label); BorderPane.setAlignment(label, Pos.CENTER); Scene scene = new Scene(root, 800, 600); scene.getStylesheets().add("style.css"); primaryStage.setScene(scene); primaryStage.show(); } private  void configureDropTargetColumn(TableColumn column, ObjectProperty> dropTarget) { Callback, TableCell> currentCellFactory = column.getCellFactory() ; column.setCellFactory(tc -> { TableCell cell = currentCellFactory.call(tc); dropTarget.addListener((obs, oldColumn, newColumn) -> cell.pseudoClassStateChanged(PseudoClass.getPseudoClass("drop-target"), newColumn==column)); cell.setOnDragEntered(e -> dropTarget.set(column)); cell.setOnDragExited(e -> dropTarget.set(null)); return cell ; }); } private static  TableColumn column(String text, Function> property) { TableColumn col = new TableColumn<>(text); col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); return col ; } private List createData() { return Arrays.asList( new Person("Jacob", "Smith", "jacob.smith@example.com"), new Person("Isabella", "Johnson", "isabella.johnson@example.com"), new Person("Ethan", "Williams", "ethan.williams@example.com"), new Person("Emma", "Jones", "emma.jones@example.com"), new Person("Michael", "Brown", "michael.brown@example.com") ); } public static class Person { private final StringProperty firstName = new SimpleStringProperty(); private final StringProperty lastName = new SimpleStringProperty(); private final StringProperty email = new SimpleStringProperty(); public Person(String firstName, String lastName, String email) { setFirstName(firstName); setLastName(lastName); setEmail(email); } public final StringProperty firstNameProperty() { return this.firstName; } public final String getFirstName() { return this.firstNameProperty().get(); } public final void setFirstName(final String firstName) { this.firstNameProperty().set(firstName); } public final StringProperty lastNameProperty() { return this.lastName; } public final String getLastName() { return this.lastNameProperty().get(); } public final void setLastName(final String lastName) { this.lastNameProperty().set(lastName); } public final StringProperty emailProperty() { return this.email; } public final String getEmail() { return this.emailProperty().get(); } public final void setEmail(final String email) { this.emailProperty().set(email); } } public static void main(String[] args) { launch(args); } } 

和样式表:

 .table-cell:drop-target { -fx-background-color: -fx-background ; -fx-background: yellow ; -fx-border-color: -fx-table-cell-border-color -fx-table-cell-border-color transparent transparent ; } .drag-source { -fx-font-size: 18 ; -fx-padding: 10 ; }