如何将子级拖到父布局JavaFX之外

问题描述 投票:0回答:1

您好,提前感谢您的任何建议。

基本上我有一个流程窗格作为滚动窗格的内容,用于显示包含数据的用户按钮。我需要能够将它们拖动到屏幕上的任何位置,但按钮会夹在滚动窗格的边缘。我使用此代码来拖动按钮:

dataButton.setOnMousePressed(e -> {
            nodeCoordinates[0] = e.getSceneX() - dataButton.getTranslateX();
            nodeCoordinates[1] = e.getSceneY() - dataButton.getTranslateY();
            dragData = data;
        });
dataButton.setOnMouseDragged(e -> {
            dataButton.setTranslateX(e.getSceneX()-nodeCoordinates[0]);
            dataButton.setTranslateY(e.getSceneY()-nodeCoordinates[1]);
        });
dataButton.setOnMouseReleased(e -> {
            dataButton.setTranslateX(0);
            dataButton.setTranslateY(0);
            if(e.getButton().equals(MouseButton.SECONDARY)){
                openDataPanel((Credential) data);
            }
            DragClearer clear= new DragClearer();//An extension of Thread for nulling a drag variable I have which gets filled with the respective data when the button is dragged
            clear.start();
        });

流程窗格包含每个按钮,滚动窗格不占据整个屏幕,还显示其他内容。我需要按钮返回到其原始位置,除非它们被拖动到它们所做的特定区域。有一段时间,我确实使用了内置的拖放功能,但并没有真正满足我的需要。我想说我是 javaFX 的中级人员,所以我的知识并没有那么深入。当在线搜索时,我还没有真正找到任何与我的问题类似的东西,所以我要么做错了什么,要么我肯定做错了。

再次感谢你们提供的任何建议。

java javafx drag mousepress
1个回答
0
投票

这是一个示例,希望可以帮助您找到正确的方向。

此代码拍摄节点的快照,然后将节点设置为不可见。快照可拖动到

Scene
的任何部分。在目标节点上发布时,将使用原始按钮的信息重新创建按钮。我还没有尝试过,但我猜想在目标节点上发布时,您可以将按钮作为子节点添加到目标节点。

我从这里更改了代码。 @James_D here的答案可能会更好。我没有尝试他的代码。

主要

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 * Demonstrates a drag-and-drop feature.
 */
public class App extends Application
{

    @Override
    public void start(Stage stage)
    {
        //Source Buttons.
        final Button boat1 = new Button("boat1");
        final Button boat2 = new Button("boat2");
        final Button boat3 = new Button("boat3");
        final Button boat4 = new Button("boat4");

        //Adding OnDragDetected to source Buttons.
        setOnDragDetected(boat1);
        setOnDragDetected(boat2);
        setOnDragDetected(boat3);
        setOnDragDetected(boat4);

        //Adding onDragDone to source Buttons.
        setOnDragDone(boat1);
        setOnDragDone(boat2);
        setOnDragDone(boat3);
        setOnDragDone(boat4);

        //Creating GridPane
        GridPane gridPane = new GridPane();
        gridPane.setVgap(5);
        gridPane.setHgap(5);
        gridPane.setPadding(new Insets(5, 5, 5, 5));
        gridPane.setStyle("-fx-background-color: black;");
        //Adding StackPane to every Cell in the GridPane and Adding the Target Events to each StackPane.
        for (int i = 0; i < 6; i++) {
            StackPane stackPane = new StackPane();
            stackPane.setPrefSize(150, 50);
            stackPane.setStyle("-fx-background-color: yellow;");
            setOnDragOver(stackPane);
            setOnDragEntered(stackPane);
            setOnDragExited(stackPane);
            setOnDragDropped(stackPane);

            gridPane.add(stackPane, i / 3, i % 3);
        }

        HBox root = new HBox(new VBox(boat1, boat2, boat3, boat4), gridPane);
        stage.setTitle("Hello Drag And Drop");
        Scene scene = new Scene(root, 400, 200);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args)
    {
        Application.launch(args);
    }

    //source events handlers
    public void setOnDragDetected(Button source)
    {
        source.setOnDragDetected((MouseEvent event) -> {
            /* drag was detected, start drag-and-drop gesture*/
            System.out.println("onDragDetected");
            final ImageView preview = new ImageView(source.snapshot(null, null));
            
            /* allow any transfer mode */
            Dragboard db = source.startDragAndDrop(TransferMode.ANY);

            /* put a string on dragboard */
            ClipboardContent content = new ClipboardContent();
            content.putString(source.getText());
            db.setContent(content);
            db.setDragView(preview.getImage());
            source.setVisible(false);
            event.consume();
        });
    }

    public void setOnDragDone(Button source)
    {
        source.setOnDragDone((DragEvent event) -> {
            /* the drag-and-drop gesture ended */
            System.out.println("onDragDone");
            /* if the data was successfully moved, clear it */
//            if (event.getTransferMode() == TransferMode.MOVE) {
//                source.setText("");
//            }

            event.consume();
        });
    }

    //target event handlers
    public void setOnDragOver(StackPane target)
    {
        target.setOnDragOver((DragEvent event) -> {
            /* data is dragged over the target */
            System.out.println("onDragOver");

            /* accept it only if it is  not dragged from the same node
            * and if it has a string data */
            if (event.getGestureSource() != target
                    && event.getDragboard().hasString()) {
                /* allow for both copying and moving, whatever user chooses */
                event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
            }

            event.consume();
        });
    }

    public void setOnDragEntered(StackPane target)
    {
        target.setOnDragEntered((DragEvent event) -> {
            /* the drag-and-drop gesture entered the target */
            System.out.println("onDragEntered");
            /* show to the user that it is an actual gesture target */
            if (event.getGestureSource() != target
                    && event.getDragboard().hasString()) {
                target.setStyle("-fx-background-color: green;");
            }

            event.consume();
        });
    }

    public void setOnDragExited(StackPane target)
    {
        target.setOnDragExited((DragEvent event) -> {
            /* mouse moved away, remove the graphical cues */
            target.setStyle("-fx-background-color: yellow;");

            event.consume();
        });
    }

    public void setOnDragDropped(StackPane target)
    {
        target.setOnDragDropped((DragEvent event) -> {
            /* data dropped */
            System.out.println("onDragDropped");
            /* if there is a string data on dragboard, read it and use it */
            Dragboard db = event.getDragboard();
            boolean success = false;
            if (db.hasString()) {
                //target.setText(db.getString());
                Button tempBoat = new Button(db.getString());
                tempBoat.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
                target.getChildren().clear();
                target.getChildren().add(tempBoat);
                success = true;
            }
            /* let the source know whether the string was successfully
            * transferred and used */
            event.setDropCompleted(success);

            event.consume();
        });
    }    
}

输出

© www.soinside.com 2019 - 2024. All rights reserved.