JavaFX Перетаскивание TreeTableColumn на другой узел - PullRequest
0 голосов
/ 21 декабря 2018

В образовательных целях я пытаюсь перетащить TreeTableColumn на узел за пределами TreeTableView и принимаю drop.Возможные варианты использования: группировка или многоуровневая сортировка.

Я искал onDragDetected на TreeTableColumn, но этот метод не существует.(TreeTableColumn Графика null по умолчанию) TreeTableView предлагает этот метод, но я не получаю никаких событий, когда я начинаю перетаскивать столбец.

Поэтому я попытался поставить Label как Графика на TreeTableColumn.это позволяет мне перетащить Column за пределы Table.но это заканчивается графическим сбоем после выпадения.

любые идеи, как обойти этот глюк или полностью избавиться от этой обертки «Графика» в «TreeTableColumn»?

, вот примерприложение, чтобы показать мою проблему

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);
        }
    }
}
...