发现DragEvent发生在哪个TableColumn(在TableView中)的最佳方法是什么?
我希望能够突出显示(例如,将背景颜色更改为黄色,或在列周围显示黄色边框)作为拖动项目的TableColumn将“悬停”在其上方,以使其清晰显示用户要删除哪一列。当拖动完成后,我必须确保恢复TableView的样式。
要明确的是,确切的细胞被丢弃并不重要 - 只有柱子。
答案 0 :(得分:3)
要执行此操作,您需要向每个单元格注册拖动侦听器,以便在拖动单元格时使列更新其样式。我会使用class TermsAndConditionsViewController: UIViewController {
//...
@IBAction func acceptButtonTapped(_ sender: Any) {
UserDefaults.standard.set(true, forKey: "termsAccepted")
performSegue(withIdentifier: "toPeekView", sender: sender)
}
//...
}
来表示当前" drop target列" (即,正在进行拖动的列),并且都观察它并从单元格中更新它。要访问单元格,您需要一个单元工厂。
以下方法将为列添加此类支持。它还尊重先前附加的单元工厂中定义的任何功能:
ObjectProperty
这是一个使用常规"联系表的SSCCE"例如:
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 ;
});
}
和样式表:
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", "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);
}
}