【问题标题】:JavaFX - Drag and Drop TableCellJavaFX - 拖放 TableCell
【发布时间】:2016-06-10 06:05:36
【问题描述】:

我有一个包含单元格的 TableView。我的表格像坐标系一样工作,而不像通常的表格。 Click here for more about this.

现在,我需要将一个单元格拖放到另一个单元格(移动)。

这是我的拖放代码:

tableView.setOnDragDetected(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            Dragboard db = tableView.startDragAndDrop(TransferMode.MOVE);
            ClipboardContent content = new ClipboardContent();

            int x = tableView.getSelectionModel().getSelectedCells().get(0).getColumn();
            int y = tableView.getSelectionModel().getSelectedCells().get(0).getRow();

            for(Event e:eventList) {
                if(e.getAblaufX() == x && e.getAblaufY() == y) {
                    //System.out.println("Event Abteilung: " + e.getAbteilung());
                    content.put(Config.SERIALIZED_MIME_TYPE, e.getId());
                }
            }

            db.setContent(content);
            event.consume();
        }
    });

    tableView.setOnDragDropped(new EventHandler<DragEvent>() {
        @Override
        public void handle(DragEvent event) {
            System.out.println("Drag Dropped!");

            Dragboard db = event.getDragboard();
             if (db.hasContent(Config.SERIALIZED_MIME_TYPE)) {
                 int draggedEventId = (Integer) db.getContent(Config.SERIALIZED_MIME_TYPE);
                 Event draggedEvent = null;
                 //System.out.println("Dragged Event ID: " + draggedEventId);
                 for(Event e:eventList) {
                     if(e.getId() == draggedEventId) {
                         draggedEvent = e;
                         eventMap.get(e).setAblaufX(ablaufX); // <-- HERE I NEED CELL INDEX
                         eventMap.get(e).setAblaufY(ablaufY); // <-- HERE I NEED ROW INDEX
                         //eventMap.put(new TablePos(draggedEvent.getAblaufX(), draggedEvent.getAblaufY()), draggedEvent);
                     }
                 }
                 if(draggedEvent != null) {
                     event.setDropCompleted(true);
                     event.consume();
                     System.out.println(draggedEvent.getText());
                 }
             }
        }
    });

    tableView.setOnDragOver(new EventHandler <DragEvent>() {
        public void handle(DragEvent event) {
            event.acceptTransferModes(TransferMode.ANY);
            event.consume();
        }
    });

我用“// &lt;-- HERE I NEED CELL INDEX”和“// &lt;-- HERE I NEED ROW INDEX”评论了这些棘手的行

在这些行中,我需要删除单元格(新单元格)的 columnIndex 和 rowIndex

【问题讨论】:

  • 也许我没理解,但你为什么不在拖动检测函数之外声明你的 int x 和 y 变量,并且只在检测到拖动时设置它,然后你可以在你的拖放函数中获得当前值
  • 以及如何获得要放置的单元格的坐标(columnIndex 和 rowIndex)?

标签: java javafx drag-and-drop tableview tableviewcell


【解决方案1】:

您需要将setOnDragDropped 添加到表格单元格中,而不是将它们添加到整个TableView 中。下面是关于如何获取单元格的行和列索引的 MCVE。 MCVE 本身除了显示如何获取单元格的行和列索引之外没有其他用处。如果您需要任何进一步的帮助,请告诉我。

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class MCVE extends Application {

    @Override
    public void start(Stage stage) {
        TableView<ObservableList<String>> table = new TableView<ObservableList<String>>();
        table.getSelectionModel().setCellSelectionEnabled(true);

        TableColumn<ObservableList<String>, String> col1 = new TableColumn<ObservableList<String>, String>();
        TableColumn<ObservableList<String>, String> col2 = new TableColumn<ObservableList<String>, String>();

        ObservableList<TableColumn<ObservableList<String>, String>> columns = FXCollections.observableArrayList(col1,
                col2);

        table.getColumns().addAll(columns);

        // For each column we set a cellFactory and a cellValueFactory.
        for (TableColumn<ObservableList<String>, String> col : columns) {
            col.setCellValueFactory(e -> new SimpleStringProperty("1"));

            // We need to set the cell factory so that we can create a cell and manipulate its behavior.
            col.setCellFactory(e -> {
                TableCell<ObservableList<String>, String> cell = new TableCell<ObservableList<String>, String>() {
                    @Override
                    public void updateItem(String item, boolean empty) {
                        // Make sure you call super.updateItem, or you might get really weird bugs.
                        super.updateItem(item, empty);
                        if (item == null || empty) {
                            setText(null);
                            setGraphic(null);
                        } else {
                            setText(item);
                            setGraphic(null);
                        }
                    }
                };

                // HERE IS HOW TO GET THE ROW AND CELL INDEX
                cell.setOnDragDetected(eh -> {
                    // Get the row index of this cell
                    int rowIndex = cell.getIndex();
                    System.out.println("Cell row index: " + rowIndex);

                    // Get the column index of this cell.
                    int columnIndex = cell.getTableView().getColumns().indexOf(cell.getTableColumn());
                    System.out.println("Cell column index: " + columnIndex);
                });

                return cell;
            });
        }

        ObservableList<ObservableList<String>> items = FXCollections.observableArrayList(
                FXCollections.observableArrayList("1", "2"), FXCollections.observableArrayList("1", "2"));

        table.setItems(items);

        BorderPane view = new BorderPane();
        view.setCenter(table);

        stage.setScene(new Scene(view));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

【讨论】:

    【解决方案2】:

    您可以使用EventpickResult 获取当前单元格来访问TableCell 并使用它来获取坐标:

    private static TableCell getCell(Node node) {
        // traverse to parent until TableCell is reached
        // or it's clear there's no TableCell in the hierarchy above node (root visited)
        while (node != null && !(node instanceof TableCell)) {
            node = node.getParent();
        }
    
        return (TableCell) node;
    }
    
    TableCell targetCell = getCell(event.getPickResult().getIntersectedNode());
    if (targetCell != null) {
        int rowIndex = targetCell.getTableRow().getIndex();
        int columnIndex = columnToIndex(targetCell.getTableColumn());
        ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多