После перевода узла разметка x и y остается прежней - PullRequest
0 голосов
/ 12 ноября 2018

В настоящее время у меня есть несколько панелей стека на панели, и при перетаскивании мышью они перемещаются по панели. Я делаю это, получая координаты мыши и перевод x и y панели стека, когда я нажимаю на панель стека. Затем, когда я начинаю перетаскивать панель стека, я устанавливаю перевод x и y панели стека в координаты мыши, когда я нажимаю панель стека + разницу новых координат мыши и старых координат мыши.

Моя проблема заключается в том, что после перетаскивания StackPane макет x и y остается неизменным. Я хочу обновить его, так как я использовал его где-то еще.

Мой обработчик событий при нажатии на StackPane:

EventHandler<MouseEvent> circleOnMousePressedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                currentStackPane  = ((StackPane)(t.getSource()));
                orgSceneX = t.getSceneX();
                orgSceneY = t.getSceneY();
                layoutX =  currentStackPane.getLayoutX();
                layoutY =  currentStackPane.getLayoutY();

            }
        };

Мой обработчик событий при перетаскивании StackPane:

EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {


                double offsetX = t.getSceneX() - orgSceneX;
                double offsetY = t.getSceneY() - orgSceneY;
                currentStackPane.setTranslateX(offsetX);
                currentStackPane.setTranslateY(offsetY);
             }
        };

Я попытался создать обработчик событий после завершения перетаскивания:

EventHandler<MouseEvent> circleOnMouseReleasedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                currentStackPane.setLayoutX(layoutX + ((StackPane)(t.getSource())).getTranslateX());
                currentStackPane.setLayoutY(layoutY + ((StackPane)(t.getSource())).getTranslateY());
                currentStackPane.setTranslateX(0);
                currentStackPane.setTranslateY(0);
        }
};

Но, похоже, это не работает. Любая помощь будет оценена спасибо!

EDIT:

Я изменил свои обработчики событий. Кажется, что я корректно обновляю компоновку x и y в первый раз, когда я перетаскиваю панель стека, но когда я сначала перетаскиваю панель стека, а затем отпускаю мышь, панель стека перемещается в другое положение, тогда каждый раз, когда я перетаскиваю ее после того, как она полностью испортилась , Не уверен, почему, любая помощь приветствуется!

EDIT2: я понял, что установил translate x в 0, но не установил translate y в 0 в событии, отпущенном мышью. Теперь все работает!

1 Ответ

0 голосов
/ 12 ноября 2018

Чтобы понять проблему, я сначала рекомендовал бы взглянуть на документацию свойств layoutX / layoutY узла.

публичный финал DoubleProperty layoutXProperty

Определяет координату х перевода, который добавляется к этому Преобразование узла для макета. Значение должно быть вычисляется как смещение, необходимое для регулировки положения узла от текущей позиции layoutBounds minX (которая может быть не 0) до нужное место.

Например, если текстовый узел должен быть расположен в finalX

 textnode.setLayoutX(finalX - textnode.getLayoutBounds().getMinX());  

Неспособность вычесть layoutBounds minX может привести к неправильному размещению узел. Метод relocate (x, y) автоматически сделает правильный вычисления и, как правило, должны использоваться над настройкой layoutX непосредственно.

Окончательный перевод узла будет вычислен как layoutX + translateX, где layoutX устанавливает стабильную позицию узла и translateX при необходимости вносит динамические корректировки в эту позицию.

Если узел управляется и имеет Region в качестве родителя, тогда макет Регион будет устанавливать layoutX в соответствии со своей собственной политикой размещения. Если узел не управляется или парентируется группой, тогда приложение может установить layoutX непосредственно, чтобы позиционировать его.

Короче говоря, для каждого узла, который визуализируется в сцене, его позиция фактически является суммой значений layoutX / Y и translateX / Y относительно его родительского узла. LayoutX / Y изначально обновляется в соответствии с его политикой размещения родителей. По этой причине нет смысла обновлять / полагаться на значения layoutX / Y узла, IF его родительский элемент (например, .StackPane, HBox, VBox и т. Д.) Управляет его положением.

Панель не будет управлять / определять свой дочерний макет. По этой причине значения layoutX / Y по умолчанию его дочерних элементов всегда равны 0.

Из приведенной выше информации, если мы сейчас посмотрим на ваш код, вы обновляете значения перевода и неправильно устанавливаете значения макета. Вместо этого вам нужно сделать следующее:

  1. Взять начальные значения layoutX / Y.
  2. Обновите translateX / Y при перетаскивании.
  3. А при отпускании мыши пересчитать значения layoutX / Y и сбросить значения translateX / Y.

Ниже приведена краткая демонстрация того, что я описал.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class PaneLayoutDemo extends Application {
    double sceneX, sceneY, layoutX, layoutY;

    @Override
    public void start(Stage stage) throws Exception {
        Pane root = new Pane();
        Scene sc = new Scene(root, 600, 600);
        stage.setScene(sc);
        stage.show();
        root.getChildren().addAll(getBox("green"), getBox("red"), getBox("yellow"));
    }

    private StackPane getBox(String color) {
        StackPane box = new StackPane();
        box.getChildren().add(new Label("Drag me !!"));
        box.setStyle("-fx-background-color:" + color + ";-fx-border-width:2px;-fx-border-color:black;");
        box.setPrefSize(150, 150);
        box.setMaxSize(150, 150);
        box.setMinSize(150, 150);
        box.setOnMousePressed(e -> {
            sceneX = e.getSceneX();
            sceneY = e.getSceneY();
            layoutX = box.getLayoutX();
            layoutY = box.getLayoutY();
            System.out.println(color.toUpperCase() + " Box onStart :: layoutX ::" + layoutX + ", layoutY::" + layoutY);
        });
        box.setOnMouseDragged(e -> {
            double offsetX = e.getSceneX() - sceneX;
            double offsetY = e.getSceneY() - sceneY;
            box.setTranslateX(offsetX);
            box.setTranslateY(offsetY);
        });
        box.setOnMouseReleased(e -> {
            // Updating the new layout positions
            box.setLayoutX(layoutX + box.getTranslateX());
            box.setLayoutY(layoutY + box.getTranslateY());

            // Resetting the translate positions
            box.setTranslateX(0);
            box.setTranslateY(0);
        });
        return box;
    }

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

Как только вы ознакомитесь с демо, попробуйте изменить корень с Pane на StackPane и посмотрите разницу в поведении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...