JavaFX: держите линию привязанной к центру двух панелей

avatar
Harkan
8 апреля 2018 в 11:31
324
1
0

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

Размеры Pane и GridPane уже изменяются по желанию, и мне удалось привязать ширину линии к размеру сцены (cellSize — это привязка ширины/высоты сцены).

Pane lastPane = panes[lastC][lastR];
Pane curPane = panes[c][r];

Bounds boundsInSceneLast = lastPane.localToScene(lastPane.getBoundsInLocal());
Bounds boundsInSceneCur = curPane.localToScene(curPane.getBoundsInLocal());
double lastX = (boundsInSceneLast.getMinX() + boundsInSceneLast.getMaxX())/2;
double lastY = (boundsInSceneLast.getMinY() + boundsInSceneLast.getMaxY())/2;
double x = (boundsInSceneCur.getMinX() + boundsInSceneCur.getMaxX())/2;
double y= (boundsInSceneCur.getMinY() + boundsInSceneCur.getMaxY())/2;

Line line = new Line(lastX, lastY, x, y);

line.setStroke(Color.web(couleurs.get(symbole)));
line.strokeWidthProperty().bind(cellSize.divide(10));
line.setStrokeLineCap(StrokeLineCap.BUTT);

anchor.getChildren().add(line);
lines.get(symbole).add(line);

anchor — это AnchorPane, который является корнем моего Scene, а lines — это HashMap, который отслеживает строки, но они не должны иметь отношения к моей проблеме.<647241022

Я уверен, что это можно сделать довольно просто, но я довольно тщательно прошерстил Интернет, и все, что я мог понять и попытаться сделать, это не сделать работу, поэтому я прошу вашей помощи.

Заранее спасибо!! :)

Источник
fabian
8 апреля 2018 в 11:47
0

Является ли AnchorPane родителем как GridPane, так и всех Line? Можно ли добавить Line к GridPane, если это не мешает компоновке других узлов?

Harkan
8 апреля 2018 в 12:07
0

Да, AnchorPane является родителем как GridPane, так и всех строк. На самом деле AnchorPane является родителем StackPane и всех строк, и этот StackPane содержит GridPane и метку, центрированную по сравнению с GridPane. Ну, я был бы не против, но что это изменит в моей проблеме? И смогу ли я таким образом рисовать линии по нескольким ячейкам сетки? :о

Ответы (1)

avatar
fabian
8 апреля 2018 в 12:22
1

Прослушивание границ Node в сцене проблематично, так как для границ сцены нет свойств, и каждый Parent на пути к корневому узлу сцены может применить преобразование, которое потребует от вас настроить положение концов линии. Это потребует от вас добавления слушателя к потомку Panes.

Было бы проще сделать линии частью самого GridPane в качестве неуправляемых узлов. Это позволяет работать с границами узлов в диапазоне GridPane:

.
final Pane lastPane = panes[lastC][lastR];
final Pane curPane = panes[c][r];

final Line line = new Line();

line.setStroke(Color.web(couleurs.get(symbole)));
line.strokeWidthProperty().bind(cellSize.divide(10));
line.setStrokeLineCap(StrokeLineCap.BUTT);

InvalidationListener listener = o -> {
    Bounds boundsInSceneLast = lastPane.getBoundsInParent();
    Bounds boundsInSceneCur = curPane.getBoundsInParent();
    double lastX = (boundsInSceneLast.getMinX() + boundsInSceneLast.getMaxX())/2;
    double lastY = (boundsInSceneLast.getMinY() + boundsInSceneLast.getMaxY())/2;
    double x = (boundsInSceneCur.getMinX() + boundsInSceneCur.getMaxX())/2;
    double y = (boundsInSceneCur.getMinY() + boundsInSceneCur.getMaxY())/2;

    line.setStartX(lastX);
    line.setStartY(lastY);
    line.setEndX(x);
    line.setEndY(y);
};

// listen to location & size changes of panes in the GridPane
lastPane.boundsInParentProperty().addListener(listener);
curPane.boundsInParentProperty().addListener(listener);

// initial refresh
listener.invalidated(null);

// add line to GridPane without considering it for layout
line.setManaged(false);
gridPane.getChildren().add(line);

lines.get(symbole).add(line);