我一直想知道如何在两个java fx窗口之间拖放列表视图项.
我使用的代码是
tilePane.setOnDragDropped((event) -> {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
TilePane pane = (TilePane) event.getGestureTarget();
if (pane.getChildren().size() >= 10) {
//error
} else {
ListView<Item> list = (ListView<Item>) event
.getGestureSource();
addShopItem(pane, list.getSelectionModel()
.getSelectedItem());
success = true;
}
}
event.setDropCompleted(success);
event.consume();
});
Run Code Online (Sandbox Code Playgroud)
列表视图和磁贴窗格都曾在一个窗口中,但我决定将它们分成不同的javafx窗口,这样可以提供更大的灵活性.一个窗口具有列表视图,另一个窗口具有tilepane.
我想将列表视图项拖到tilepane(其他窗口),但此代码不再有效,因为getGestureTarget()对于不同的应用程序为null.
谢谢
当拖动离开JavaFX应用程序时(例如,在两个窗口之间移动),它看起来像手势源和目标都被设置为null.
对于手势源,您可能需要通过创建属性并在onDragDetected
处理程序中设置其值来自行管理.
手势目标肯定只是您将onDragDropped
侦听器附加到的平铺窗格.所以我没有看到你需要从事件中访问它; 虽然你可以使用相同的技术.
例:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class DnDListViews extends Application {
private int counter = 0 ;
private final ObjectProperty<ListCell<String>> dragSource = new SimpleObjectProperty<>();
@Override
public void start(Stage primaryStage) {
populateStage(primaryStage);
primaryStage.show();
Stage anotherStage = new Stage();
populateStage(anotherStage);
anotherStage.setX(primaryStage.getX() + 300);
anotherStage.show();
}
private void populateStage(Stage stage) {
ListView<String> listView = new ListView<>();
for (int i=0; i<5; i++ ) {
listView.getItems().add("Item "+(++counter));
}
listView.setCellFactory(lv -> {
ListCell<String> cell = new ListCell<String>(){
@Override
public void updateItem(String item , boolean empty) {
super.updateItem(item, empty);
setText(item);
}
};
cell.setOnDragDetected(event -> {
if (! cell.isEmpty()) {
Dragboard db = cell.startDragAndDrop(TransferMode.MOVE);
ClipboardContent cc = new ClipboardContent();
cc.putString(cell.getItem());
db.setContent(cc);
dragSource.set(cell);
}
});
cell.setOnDragOver(event -> {
Dragboard db = event.getDragboard();
if (db.hasString()) {
event.acceptTransferModes(TransferMode.MOVE);
}
});
cell.setOnDragDone(event -> listView.getItems().remove(cell.getItem()));
cell.setOnDragDropped(event -> {
Dragboard db = event.getDragboard();
if (db.hasString() && dragSource.get() != null) {
// in this example you could just do
// listView.getItems().add(db.getString());
// but more generally:
ListCell<String> dragSourceCell = dragSource.get();
listView.getItems().add(dragSourceCell.getItem());
event.setDropCompleted(true);
dragSource.set(null);
} else {
event.setDropCompleted(false);
}
});
return cell ;
});
BorderPane root = new BorderPane(listView);
Scene scene = new Scene(root, 250, 450);
stage.setScene(scene);
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
如果dragboard支持在同一个JVM中拖放任意对象引用以进行拖放(请参阅JIRA请求,如果愿意则投票),那么这将更容易......
归档时间: |
|
查看次数: |
5665 次 |
最近记录: |