在不同的javafx窗口之间拖放列表视图项

Top*_*pRS 3 javafx-8

我一直想知道如何在两个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.

谢谢

Jam*_*s_D 9

当拖动离开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请求,如果愿意则投票),那么这将更容易......