Для этого вам необходимо зарегистрировать прослушиватели перетаскивания с каждой ячейкой, которые заставляют столбцы обновлять свой стиль при перетаскивании ячеек. Я бы сделал это, используя ObjectProperty
, чтобы представить текущий столбец «drop target» (т. Е. Столбец, по которому происходит перетаскивание), и как наблюдать, так и обновлять его из ячеек. Чтобы получить доступ к ячейкам, вам нужна фабрика ячеек.
Следующий способ добавит такую поддержку к столбцу. Он также уважает любую функциональность, определенную в ранее присоединенной клетки завода:
private <S,T> void configureDropTargetColumn(TableColumn<S,T> column, ObjectProperty<TableColumn<?,?>> dropTarget) {
Callback<TableColumn<S,T>, TableCell<S,T>> currentCellFactory = column.getCellFactory() ;
column.setCellFactory(tc -> {
TableCell<S,T> 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<Person> 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<TableColumn<?,?>> 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 <S,T> void configureDropTargetColumn(TableColumn<S,T> column, ObjectProperty<TableColumn<?,?>> dropTarget) {
Callback<TableColumn<S,T>, TableCell<S,T>> currentCellFactory = column.getCellFactory() ;
column.setCellFactory(tc -> {
TableCell<S,T> 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 <S,T> TableColumn<S,T> column(String text, Function<S, ObservableValue<T>> property) {
TableColumn<S,T> col = new TableColumn<>(text);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col ;
}
private List<Person> createData() {
return Arrays.asList(
new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]")
);
}
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 ;
}
Несмотря на то, что вас интересует только столбец, а не фактическая ячейка, вам нужно будет зарегистрировать обработчики перетаскивания с помощью ячеек, используя фабрику ячеек. –
Все ячейки? Разве это не был бы огромный список обработчиков? – User
Если у ваших пользователей нет абсолютно огромного экрана, у вас вряд ли будет более 20 или 30 ячеек на столбе. Я не понимаю, почему вы думаете, что вызовет какие-либо проблемы; обработчики очень легкие. (И если вы действительно кодируете дисплеи на Таймс-сквер или что-то подобное, у вас, вероятно, гораздо более серьезные проблемы с производительностью, чтобы справиться с ...) –