javafx类似于桌面的拖动选择

时间:2018-06-05 10:42:52

标签: javafx drag

我正在尝试通过拖动来创建一些带有矩形的节点的选择 一切都很好,但我不能让选择回归正常。 更清楚的是,我的问题是:想象一下,在桌面中你做了一个矩形选择,当回来时(不想选择最后一个图标),最后一个图标仍然被选中。

public class BorderPaneConInstallazioni extends BorderPane {


    List<DragSelectable> selectable = new LinkedList<>();

    public BorderPaneConInstallazioni() {

        VBoxSelectable v1 = new VBoxSelectable(Color.FUCHSIA);
        VBoxSelectable v2 = new VBoxSelectable(Color.BLACK);
        VBoxSelectable v3 = new VBoxSelectable(Color.RED);
        VBoxSelectable v4 = new VBoxSelectable(Color.BLUEVIOLET);
        VBoxSelectable v5 = new VBoxSelectable(Color.FORESTGREEN);
        v1.getChildren().add(new Label("Ciao"));
        v2.getChildren().add(new Label("Ciao"));
        v3.getChildren().add(new Label("Ciao"));
        v4.getChildren().add(new Label("Ciao"));
        v5.getChildren().add(new Label("Ciao"));

        selectable.add(v1);
        selectable.add(v2);
        selectable.add(v3);
        selectable.add(v4);
        selectable.add(v5);

        setTop(v1);
        setLeft(v2);
        setCenter(v3);
        setRight(v4);
        setBottom(v5);

        registerEvents();

    }

    private void deselectAll(){
        for(DragSelectable sel : selectable) sel.deselect();
    }

    private Rectangle resizeRectangle = null;

    public void registerEvents() {


        setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle (MouseEvent event){
                resizeRectangle = new Rectangle(event.getSceneX(), event.getSceneY(), 0, 0);
                resizeRectangle.setStyle("    -fx-fill: transparent;\n" +
                        "    -fx-stroke: #00000080;\n" +
                        "    -fx-stroke-width: 1;\n" +
                        "    -fx-stroke-dash-array: 4 4 4 4;");
                getChildren().add(resizeRectangle);
                event.consume();
            }
        });

        setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                startFullDrag();
            }
        });





        setOnMouseDragged( (mouseEvent) -> {
            // only on primary
            if (mouseEvent.getButton().equals(MouseButton.PRIMARY) == false) {
                return;
            }
            List<Node> lista = pick(this,mouseEvent.getSceneX(),mouseEvent.getSceneY(),new LinkedList<Node>());
            System.out.println(lista);

            List<Node> selezionati = new LinkedList<>();

            for(Node nodo : lista){
                if(nodo instanceof DragSelectable){
                    DragSelectable b = (DragSelectable) nodo;
                    b.seleziona();
                    selezionati.add(nodo);

                }
            }
            System.out.println(selezionati);

            if(selezionati.size() != 0) {
                for (DragSelectable corrente : selectable) {
                    if (!selezionati.contains(corrente)) {
                        //  corrente.deseleziona();
                        Node nodo = (Node) corrente;

                        if(!resizeRectangle.getBoundsInLocal().intersects(nodo.getBoundsInLocal())){
                            corrente.deseleziona();
                        }
                    }
                }
            }

            mouseEvent.consume();
            nodeY (layoutY) to on-screen mouseY
            Bounds boundsInScene = resizeRectangle.localToScene(resizeRectangle.getBoundsInLocal());



            double width = mouseEvent.getSceneX() - boundsInScene.getMinX();
            double height = mouseEvent.getSceneY() - boundsInScene.getMinY();
            if(width >= 0) {
                resizeRectangle.setHeight(height);
                resizeRectangle.setWidth(width);
            } else{
                resizeRectangle.setHeight(0);
                resizeRectangle.setWidth(0);
            }
        });



        setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent event) {
                deselectAll();
                getChildren().remove(resizeRectangle);
                resizeRectangle = null;

                event.consume();
            }
        });

    }

    public static List<Node> pick(Node node, double sceneX, double sceneY, List<Node> result) {
        Point2D p = node.sceneToLocal(sceneX, sceneY, true /* rootScene */);

        // check if the given node has the point inside it, or else we drop out
        if (!node.contains(p)) return result;

        // at this point we know that _at least_ the given node is a valid
        // answer to the given point, so we will return that if we don't find
        // a better child option
        if (node instanceof Parent) {
            // we iterate through all children in reverse order, and stop when we find a match.
            // We do this as we know the elements at the end of the list have a higher
            // z-order, and are therefore the better match, compared to children that
            // might also intersect (but that would be underneath the element).
            Node bestMatchingChild = null;
            List<Node> children = ((Parent)node).getChildrenUnmodifiable();
            for (int i = children.size() - 1; i >= 0; i--) {
                Node child = children.get(i);
                p = child.sceneToLocal(sceneX, sceneY, true /* rootScene */);
                if (child.isVisible() && !child.isMouseTransparent() && child.contains(p)) {
                    bestMatchingChild = child;
                    break;
                }
            }

            if (bestMatchingChild != null) {
                result.add(bestMatchingChild);
                return pick(bestMatchingChild, sceneX, sceneY,result);
            }
        }

        return result;
    }
}
public class VBoxSelectable extends VBox implements DragSelectable {


    public Background back = new Background(new BackgroundFill(Color.FUCHSIA, new CornerRadii(2), new Insets(0)));

    public final Background backBianco = new Background(new BackgroundFill(Color.WHITE, new CornerRadii(2), new Insets(0)));



    String selezionato;


    public VBoxSelectable(Color color){
        back = new Background(new BackgroundFill(color, new CornerRadii(2), new Insets(0)));

        selezionato = color.toString();

    }

    @Override
    public void select() {
        setBackground(back);

    }

    @Override
    public void deselect() {
        setBackground(backBianco);
    }

    @Override
    public String toString(){
        return selezionato;
    }
}

DragSelectable是方法select()deselect()的界面。

我注意到的是,当我返回时,pick功能选择的唯一节点(我在这里找到http://fxexperience.com/2016/01/node-picking-in-javafx/)是矩形而没有别的,所以什么都不会被取消选择。

为了完整性,我还将插入接口和主类。

 public interface DragSelectable {

     public void select();
     public void deselect();

 }

和主

public class Main extends Application {

    public static Scene scena;

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = new BorderPaneConInstallazioni();



        primaryStage.setTitle("Hello World");
        Scene scene = new Scene(root,800,800);
        scena = scene;
        primaryStage.setScene(scene);
        primaryStage.show();
    }


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

我如何解决我的问题?
javafx中是否内置了实现此功能的内容?

0 个答案:

没有答案