在不同的Javafx窗口之间拖放列表视图项 [英] Dragging and dropping list view items between different javafx windows

查看:119
本文介绍了在不同的Javafx窗口之间拖放列表视图项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直想知道您如何在2个Java fx窗口之间拖放列表视图项.

I've been wondering how you would be able to drag and drop list view items between 2 java fx windows.

我使用的代码是

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();
    });

列表视图和图块窗格以前都在一个窗口中,但是我决定将它们分开到不同的javafx窗口中,以便提供更大的灵活性.一个窗口具有列表视图,另一个窗口具有图块.

Both the list view and tile pane used to be in one window but I've decided to make seperate them into different javafx windows so it would allow for more flexibility. One window has the list view and the other has the tilepane.

我想将列表视图项拖动到tilepane(其他窗口),但是此代码不再起作用,因为不同应用程序的getGestureTarget()为null.

I would like to drag the list view item to the tilepane(other window) but this code no longer works because getGestureTarget() is null for different applications.

谢谢

推荐答案

当拖动离开JavaFX应用程序(例如,在两个窗口之间移动)时,手势来源和目标确实都设置为null.

It does look like the gesture source and target both get set to null when the drag leaves the JavaFX application (e.g. moving it between two windows).

对于手势源,您可能需要通过创建属性并在onDragDetected处理程序中设置其值来自行管理.

For the gesture source, you may need to manage that yourself by creating a property and setting its value in the onDragDetected handler.

手势目标肯定只是您已将onDragDropped侦听器附加到的图块窗格.因此,我认为您无需从事件中访问它;尽管您可以使用相同的技术.

The gesture target is surely just the tile pane to which you attached the onDragDropped listener. So I don't see that you need to access that from the event; though you could use the same technique.

示例:

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);
    }
}

如果拖动板支持在同一JVM内附加任意对象引用以进行拖放操作(请参见JIRA请求,如果愿意的话再投票),这样会容易得多...

If the dragboard supported attaching arbitrary object references for drag and drop within the same JVM (see JIRA request, and vote if so inclined) then this would be quite a bit easier...

这篇关于在不同的Javafx窗口之间拖放列表视图项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆