当前位置: 首页 > 面试题库 >

JavaFX-检测并突出显示被拖动到的TableColumn

上官华池
2023-03-14
问题内容

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

我希望能够突出显示(例如,将背景颜色更改为黄色,或在列周围显示黄色边框)TableColumn,因为拖动的项目“悬停”在其上方,以便于用户清楚他们正在放的专栏。拖动完成后,我当然必须确保TableView的样式已恢复。

需要明确的是,确切的单元格没有关系-只是列。


问题答案:

为此,您需要在每个单元格中注册拖动侦听器,这会导致在单元格被拖动时该列更新其样式。我将使用ObjectProperty来代表当前的“放置目标列”(即在其上发生拖动的列)来进行此操作,并观察它并从单元格中对其进行更新。要访问单元,您需要一个单元工厂。

下面的方法会将这种支持添加到列中。它还尊重先前连接的单元工厂中定义的任何功能:

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", "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 ;
}


 类似资料:
  • 我目前正在为一个学校项目制作一个小游戏,冲突检测有问题。 这是我的时间线和跳转按钮代码: 这是我对碰撞检测的尝试: 我只能假设这不起作用,因为它不会不断地寻找X和Y位置,但我不确定如何做到这一点。

  • 我试图在JavaFX中执行以下操作。我正在用画布在屏幕上画东西,我希望发生以下事情: 当我点击画布表面时(比如快速按下并释放):有些事情发生了 当我在画布表面拖动时(如按住并移动,然后释放):会发生其他事情 但是如果我拖动,我希望它排除单击操作,所以如果我拖动,如果我单击,会发生什么事情,而不应该发生。不幸的是,当我释放鼠标时,释放和单击事件都会启动,即使我拖动鼠标。

  • 我正在寻找一个用JavaScript编写的好的全方位语法荧光笔,它将自动检测所使用的语言并应用正确的语法高亮显示。 我从一个简单的谷歌搜索中找到了无数个,但它们都必须在

  • 问题内容: 我们正在TextArea应用程序中使用JavaFX的控件,并尝试将其与 集成在一起-例如,当用户输入词典中没有的错误单词时,该单词将突出显示。 有什么办法可以突出显示控件中的单词吗?我在中没有看到任何选择,因此,如果有人可以建议一种方法? 我想,可能有可能使用组件并用分别为单词加上颜色。但是,这会带来很多不同的拼写检查问题,例如html标签和字数统计。 问题答案: JavaFX Tex

  • 本文向大家介绍HTML 突出显示,包括了HTML 突出显示的使用技巧和注意事项,需要的朋友参考一下 示例 该<mark>元素是HTML5中的新元素,用于“由于其在另一个上下文中的相关性”而标记或突出显示文档中的文本。1 最常见的示例是用户输入搜索查询并显示结果以突出显示所需查询的搜索结果。 输出: 常见的标准格式是黄色背景上的黑色文本,但是可以使用CSS进行更改。