Масштабируйте фигуры, не раздвигая их

Я пытаюсь создать две одинаковые размерные формы (прямоугольники) одна под другой с эффектом масштабирования. Но, однако, когда прямоугольники масштабируются, две формы накладываются друг на друга. Такое поведение не ожидается.

Я ожидал, что прямоугольники будут масштабированы (увеличены), и, кроме того, два прямоугольника должны располагаться один под другим без каких-либо промежутков между ними. Как этого добиться?

Один из вариантов - обеспечить масштабирование группы. Но это сделало бы текст внутри тоже масштабированным, что не требуется. Другой вариант - использовать VBox, но я хочу реализовать эту функциональность на панели.

Кто-то предлагает мне решение здесь

Код, с которым я пытался достичь, ниже

      import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.input.ScrollEvent;
import javafx.stage.Stage;


@SuppressWarnings("restriction")
public class TestRectScaling extends Application {

/**
 * @param args
 */
public static void main(final String[] args) {
  launch(args);
}

/**
 * {@inheritDoc}
 */
@Override
public void start(final Stage primaryStage) throws Exception {
  javafx.scene.layout.Pane p = new javafx.scene.layout.Pane();
  javafx.scene.Group g = new javafx.scene.Group(p);
  javafx.scene.control.ScrollPane sp = new javafx.scene.control.ScrollPane(g);

  javafx.scene.layout.StackPane stackPane1 = new javafx.scene.layout.StackPane();

  javafx.scene.shape.Rectangle rect1 = new javafx.scene.shape.Rectangle();
  stackPane1.getChildren().add(rect1);
  rect1.setWidth(100);
  rect1.setHeight(100);
  rect1.setFill(javafx.scene.paint.Color.BLUE);
  javafx.scene.text.Text text1 = new javafx.scene.text.Text("This is sample Text Rect 1");
  text1.setWrappingWidth(30);
  stackPane1.getChildren().add(text1);

  javafx.scene.layout.StackPane stackPane2 = new javafx.scene.layout.StackPane();
  javafx.scene.shape.Rectangle rect2 = new javafx.scene.shape.Rectangle();
  rect2.setWidth(100);
  rect2.setHeight(100);
  rect2.setFill(javafx.scene.paint.Color.BLUEVIOLET);
  javafx.scene.text.Text text2 = new javafx.scene.text.Text("This is sample Text Rect 2");
  text2.setWrappingWidth(30);
  stackPane2.getChildren().add(rect2);
  stackPane2.getChildren().add(text2);

  stackPane1.setLayoutX(30);
  stackPane1.setLayoutY(20);

  stackPane2.setLayoutX(30);
  stackPane2.setLayoutY(120);

  g.getChildren().add(stackPane1);
  g.getChildren().add(stackPane2);


  sp.addEventFilter(javafx.scene.input.ScrollEvent.ANY, new EventHandler<ScrollEvent>() {

    @Override
    public void handle(final ScrollEvent event) {
      double scaleDelta = 1.3d;
      double scaleFactor = 0;
      double deltaY = event.getDeltaY();
      if (deltaY < 0) {
        scaleFactor = 1 / scaleDelta;
      }
      else {
        scaleFactor = scaleDelta;
      }
      rect1.setScaleY(rect1.getScaleY() * scaleFactor);
      rect2.setScaleY(rect2.getScaleY() * scaleFactor);
    }
  });

  javafx.scene.Scene s = new javafx.scene.Scene(sp);
  primaryStage.setScene(s);
  primaryStage.show();
}
}

Позвольте мне помочь с изображением

Таким образом, основная цель - масштабировать прямоугольники без изменения расстояния между ними. Это в основном означает, что мне нужен способ вычислить новые координаты Y после их масштабирования.

3 ответа

Независимо от вашего обсуждения реализации, если вы все еще ищете решение с вашим текущим подходом, вам необходимо включить нижеприведенные слушатели в свойство boundsInParent ваших прямоугольников.

Идея в том, что когда вы масштабируете узел, boundsInParent обновляется. И если вы слушаете это свойство, вы можете обновить высоту stackPanes и layoutY второй stackPane.

      double gap = 15.0;
rect1.boundsInParentProperty().addListener((obs, old, bounds) -> {
    stackPane1.setPrefHeight(bounds.getHeight());
    stackPane2.setLayoutY(stackPane1.getLayoutY() + bounds.getHeight() + gap);
});

rect2.boundsInParentProperty().addListener((obs, old, val) -> {
    stackPane2.setPrefHeight(val.getHeight());
});

Вышеупомянутое решение идеально, когда есть промежуток между прямоугольниками, расположенными один под другим, но как мы можем решить тот же сценарий, если прямоугольники смежны друг с другом.

Изображение:https://stackru.com/images/39cddd932b273348d064b2502c6be59d64c4c30a.png

        rect1.boundsInParentProperty().addListener((obs, old, bounds) -> {
        stackPane1.setPrefHeight(bounds.getHeight());
        stackPane2.setLayoutY(stackPane1.getLayoutY() + bounds.getHeight() + gap);
    });

При масштабировании 2 прямоугольника необходимо разместить пропорционально, что означает при масштабировании, какой параметр необходимо использовать для вычисления новых координат y для второй панели стека в приведенном выше фрагменте кода?

Удалив нижнюю строку, она не будет соответствовать пропорциональному масштабированию и соответственно расположению прямоугольников.

stackPane2.setLayoutY ..

Позвольте мне попытаться объяснить это.

В программе, указанной в заданном вопросе, внесите следующие изменения

stackPane2.setLayoutX(170);

stackPane2.setLayoutY(100);

Во-первых, теперь прямоугольники прилегают друг к другу. Однако есть часть прямоугольников, которые имеют перекрывающиеся области с точки зрения значений оси y. см. прикрепленное изображение

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

Первоначально 2-й прямоугольник, вероятно, находится на нижней 1/4 высоты 1-го прямоугольника. Таким образом, ожидаемый результат будет заключаться в том, что при масштабировании 2-й прямоугольник должен быть помещен на 1/4 высоты 1-го прямоугольника.

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

Я понимаю, что все зависит от линии stackPane2.setLayoutY... Но проблема в том, что координаты оси y вычисляются неправильно. Следовательно, вторая панель прямоугольника / стопки размещена неправильно.

Итак, как рассчитать координаты y второго прямоугольника при масштабировании?

Другие вопросы по тегам