JavaFX场景生成器 - 父节点之间的拖放

时间:2016-05-15 20:41:36

标签: java javafx fxml

我正在使用FXML和Scene Builder来开发一个非常简单的界面。下面,第一个图像表示布局层次结构。按下按钮时,第二个图像显示文本区域。

动作事件方法实例化新文本区域并将其分配给第一个流动窗格(从左到右)。我的目标是将每个文本区域拖放到任何其他流窗格。

我的第一次尝试是使用assign使用事件处理程序来检测MOUSE_PRESSED:textArea.addEventHandler(MouseEvent.DRAG_DETECTED, e-> handle(e));

当我设置句柄方法时,事情变得令人困惑。例如,我是否应该包含其他各种MouseEvent,例如MOUSE_EXITED_TARGET,MOUSE_ENTERED_TARGET? MOUSE_RELEASED句柄是如何组成的?

我开始关注Dragboard和剪贴板,并且在那里也没有找到太多运气。剪贴板似乎只能处理字符串值,或者以迂回的方式处理图像。我确信我的困境有一个简单的答案,因为它清楚地表明我在未知的领域中徘徊。

我已阅读了几本教科书"资源,但它们都解决了在运行时构造的对象的移动,并且大多数都符合看似通用或简单的示例。

注意 我为这些图片道歉,我发现它并不是很清楚。网格窗格中分布有5个流窗格。我会尽快编辑和更新它。

initial interface hierarchy after button is pressed

1 个答案:

答案 0 :(得分:1)

因此,我了解到您正试图将TextAreas拖放到其他FlowPanes。您可以使用DragEvents而非MouseEvents来实现此目的。这是一个例子:

考虑到像您这样的简单布局,只考虑TextArea和两个FlowPanes,我们会有以下字段:

@FXML
private TextArea textArea;

@FXML
private FlowPane flowPane1;

@FXML
private FlowPane flowPane2;

一开始,textArea位于flowPane1左侧的GridLayout

TextArea on left grid

我们想将'textArea'拖放到右侧flowPane。首先,我们必须告诉textArea它应该是可拖动的。在这种情况下,移动。您可以通过不同的方式实现它,但在此我将向您展示将现有的TextArea移动到另一个FlowPane。另一种方法是重新创建一个带有文本的方法。

textArea.setOnDragDetected((MouseEvent event) -> {
    //We want the textArea to be dragged. Could also be copied.
    Dragboard db = textArea.startDragAndDrop(TransferMode.MOVE);

    // Put a string on a dragboard as an identifier
    ClipboardContent content = new ClipboardContent();
    content.putString(textArea.getId());
    db.setContent(content);

    //Consume the event
    event.consume();
});

然后,我们希望flowPane2在被拖动时接受textArea。首先,我们告诉它在拖动时接受textArea。

flowPane2.addEventHandler(DragEvent.DRAG_OVER, (DragEvent event) -> {
    if (event.getGestureSource() != flowPane2
            && event.getDragboard().hasString()) {
        event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
    }
    event.consume();
});

在我们允许它被拖动之后,我们确实希望它实际上做某事并在被删除时接受它。所以我们添加另一个处理程序来接受被删除的textArea

flowPane2.addEventHandler(DragEvent.DRAG_DROPPED, (DragEvent event) -> {
    //Get the dragboard back
    Dragboard db = event.getDragboard();
    boolean success = false;
    //Could have some more thorough checks of course.
    if (db.hasString()) {
        //Get the textarea and place it into flowPane2 instead
        flowPane2.getChildren().add(textArea);
        success = true;
    }
    //Complete and consume the event.
    event.setDropCompleted(success);
    event.consume();
});

结果,textArea可以从flowPane1移至flowPane2。反之亦然,但这会让你去!

Dragged textArea