JavaFX - 拖放 TableCell
Posted
技术标签:
【中文标题】JavaFX - 拖放 TableCell【英文标题】:JavaFX - Drag and Drop 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();
);
我用“// <-- HERE I NEED CELL INDEX
”和“// <-- HERE I NEED ROW INDEX
”评论了这些棘手的行
在这些行中,我需要删除单元格(新单元格)的 columnIndex 和 rowIndex
【问题讨论】:
也许我没理解,但你为什么不在拖动检测函数之外声明你的 int x 和 y 变量,并且只在检测到拖动时设置它,然后你可以在你的拖放函数中获得当前值 以及如何获得要放置的单元格的坐标(columnIndex 和 rowIndex)? 【参考方案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】:您可以使用Event
的pickResult
获取当前单元格来访问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());
...
【讨论】:
以上是关于JavaFX - 拖放 TableCell的主要内容,如果未能解决你的问题,请参考以下文章
使用CheckBoxListCell的Javafx listview不适用于拖放