add drag sort
This commit is contained in:
@@ -10,16 +10,22 @@ import com.imyeyu.lang.multi.ResourcesMultilingual;
|
||||
import javafx.beans.binding.DoubleBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableRow;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.ScrollEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
@@ -31,7 +37,10 @@ import lombok.RequiredArgsConstructor;
|
||||
@RequiredArgsConstructor
|
||||
public class HostTable extends TableView<Host> implements TimiFXUI {
|
||||
|
||||
private static final String DRAG_INDEX_KEY = "host-table-row-index";
|
||||
|
||||
private final ResourcesMultilingual multilingual;
|
||||
private int dragSourceIndex = -1;
|
||||
|
||||
@PostConstruct
|
||||
private void postConstruct() {
|
||||
@@ -78,6 +87,10 @@ public class HostTable extends TableView<Host> implements TimiFXUI {
|
||||
}
|
||||
});
|
||||
getColumns().add(activated);
|
||||
|
||||
TableColumn<Host, Void> drag = createDragColumn();
|
||||
getColumns().add(drag);
|
||||
|
||||
// IP
|
||||
TableColumn<Host, String> ip = new TableColumn<>("IP");
|
||||
ip.setCellValueFactory(new PropertyValueFactory<>("ip"));
|
||||
@@ -245,6 +258,7 @@ public class HostTable extends TableView<Host> implements TimiFXUI {
|
||||
|
||||
DoubleBinding db = widthProperty().subtract(8);
|
||||
db = db.subtract(activated.widthProperty());
|
||||
db = db.subtract(drag.widthProperty());
|
||||
db = db.subtract(ip.widthProperty());
|
||||
db = db.subtract(description.widthProperty());
|
||||
db = db.subtract(delete.widthProperty());
|
||||
@@ -256,5 +270,117 @@ public class HostTable extends TableView<Host> implements TimiFXUI {
|
||||
|
||||
// 滚动时编辑区主动失去焦点
|
||||
addEventFilter(ScrollEvent.ANY, e -> requestFocus());
|
||||
setRowFactory(table -> createDraggableRow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建拖动排序列。
|
||||
*
|
||||
* @return 拖动排序列
|
||||
*/
|
||||
private TableColumn<Host, Void> createDragColumn() {
|
||||
TableColumn<Host, Void> drag = new TableColumn<>("");
|
||||
drag.setPrefWidth(40);
|
||||
drag.setSortable(false);
|
||||
drag.setResizable(false);
|
||||
drag.setReorderable(false);
|
||||
drag.setCellFactory(cell -> new TableCell<>() {
|
||||
|
||||
private final Button dragButton = new Button("::");
|
||||
|
||||
{
|
||||
dragButton.getStyleClass().add(CSS.BORDER_N);
|
||||
dragButton.setFocusTraversable(false);
|
||||
dragButton.setOnDragDetected(this::startRowDrag);
|
||||
setAlignment(Pos.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(Void item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || getTableRow() == null || getTableRow().getItem() == null) {
|
||||
setGraphic(null);
|
||||
} else {
|
||||
setGraphic(dragButton);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从拖动按钮发起行拖拽。
|
||||
*
|
||||
* @param event 鼠标事件
|
||||
*/
|
||||
private void startRowDrag(MouseEvent event) {
|
||||
TableRow<Host> row = getTableRow();
|
||||
if (row == null || row.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dragSourceIndex = row.getIndex();
|
||||
Dragboard dragboard = row.startDragAndDrop(TransferMode.MOVE);
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.putString(DRAG_INDEX_KEY.formatted());
|
||||
dragboard.setContent(content);
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
return drag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支持拖动排序的表格行。
|
||||
*
|
||||
* @return 表格行
|
||||
*/
|
||||
private TableRow<Host> createDraggableRow() {
|
||||
TableRow<Host> row = new TableRow<>();
|
||||
row.setOnDragOver(event -> {
|
||||
if (dragSourceIndex < 0 || row.getIndex() == dragSourceIndex) {
|
||||
return;
|
||||
}
|
||||
if (event.getDragboard().hasString()) {
|
||||
event.acceptTransferModes(TransferMode.MOVE);
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
row.setOnDragDropped(event -> {
|
||||
if (dragSourceIndex < 0) {
|
||||
return;
|
||||
}
|
||||
int targetIndex = row.isEmpty() ? getItems().size() : row.getIndex();
|
||||
moveItem(dragSourceIndex, targetIndex);
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
});
|
||||
row.setOnDragDone(event -> dragSourceIndex = -1);
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整条目顺序。
|
||||
*
|
||||
* @param fromIndex 原索引
|
||||
* @param toIndex 目标索引
|
||||
*/
|
||||
private void moveItem(int fromIndex, int toIndex) {
|
||||
ObservableList<Host> items = getItems();
|
||||
if (fromIndex < 0 || items.size() <= fromIndex) {
|
||||
return;
|
||||
}
|
||||
if (toIndex < 0) {
|
||||
toIndex = 0;
|
||||
}
|
||||
if (items.size() < toIndex) {
|
||||
toIndex = items.size();
|
||||
}
|
||||
if (fromIndex == toIndex) {
|
||||
return;
|
||||
}
|
||||
Host movedItem = items.remove(fromIndex);
|
||||
if (fromIndex < toIndex) {
|
||||
toIndex--;
|
||||
}
|
||||
items.add(toIndex, movedItem);
|
||||
getSelectionModel().clearAndSelect(toIndex);
|
||||
scrollTo(toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user