Я пытаюсь изменить размер узла, перетаскивая его пользовательскую границу, и это работает нормально. Однако родительская панель не увеличивается в одном направлении при перетаскивании верхней и левой границ. Вот демо, изначально у меня есть собственный класс рамки:
class Outline extends Group {
private final Path[] paths;
private final Node node;
private final DoubleProperty width;
public Outline(@NotNull Node node, double width) {
this.node = node;
this.width = new SimpleDoubleProperty(width);
paths = new Path[]{
createBorder(BorderLine.LEFT),
createBorder(BorderLine.TOP),
createBorder(BorderLine.RIGHT),
createBorder(BorderLine.BOTTOM)
};
setManaged(false);
getChildren().addAll(paths);
}
@NotNull
private Path createBorder(@NotNull BorderLine borderLine) {
MoveTo moveTo = new MoveTo();
LineTo lineTo = new LineTo();
applyBounds(borderLine, node.getLayoutBounds(), moveTo, lineTo);
node.boundsInParentProperty().addListener((observable, oldValue, newValue) ->
applyBounds(borderLine, newValue, moveTo, lineTo));
Path path = new Path(moveTo, lineTo);
path.strokeWidthProperty().bind(width);
return path;
}
private void applyBounds(@NotNull BorderLine borderLine,
Bounds bounds,
MoveTo moveTo,
LineTo lineTo) {
switch (borderLine) {
case LEFT -> {
moveTo.setX(bounds.getMinX());
moveTo.setY(bounds.getMinY());
lineTo.setX(bounds.getMinX());
lineTo.setY(bounds.getMaxY());
}
case TOP -> {
moveTo.setX(bounds.getMinX());
moveTo.setY(bounds.getMinY());
lineTo.setX(bounds.getMaxX());
lineTo.setY(bounds.getMinY());
}
case RIGHT -> {
moveTo.setX(bounds.getMaxX());
moveTo.setY(bounds.getMinY());
lineTo.setX(bounds.getMaxX());
lineTo.setY(bounds.getMaxY());
}
case BOTTOM -> {
moveTo.setX(bounds.getMinX());
moveTo.setY(bounds.getMaxY());
lineTo.setX(bounds.getMaxX());
lineTo.setY(bounds.getMaxY());
}
}
}
public Path[] getPaths() {
return paths;
}
public enum BorderLine {
LEFT, RIGHT, TOP, BOTTOM;
}
}
Далее у меня есть класс ResizableNode, который пытается ограничить себя предыдущей границей, а также добавляет изменение размера путем перетаскивания логики к границе:
class ResizableNode extends Pane {
public final double MIN_POSSIBLE_WIDTH = 10;
public final double MIN_POSSIBLE_HEIGHT = 10;
private final Rectangle nodeArea = new Rectangle(140, 140, Color.TRANSPARENT);
public ResizableNode() {
Outline outline = new Outline(nodeArea, 4);
makeResizeable(BorderLine.LEFT, outline.getPaths()[0]);
makeResizeable(BorderLine.TOP, outline.getPaths()[1]);
makeResizeable(BorderLine.RIGHT, outline.getPaths()[2]);
makeResizeable(BorderLine.BOTTOM, outline.getPaths()[3]);
Pane nodeAreaPane = new Pane(nodeArea, outline);
nodeAreaPane.setBackground(Background.fill(Color.RED));
getChildren().addAll(nodeAreaPane);
}
private void makeResizeable(@NotNull BorderLine borderLine, @NotNull Path path) {
final AtomicReference initialX = new AtomicReference(0.0),
initialY = new AtomicReference(0.0),
initialCoordX = new AtomicReference(0.0),
initialCoordY = new AtomicReference(0.0),
initialWidth = new AtomicReference(0.0),
initialHeight = new AtomicReference(0.0);
path.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
initialX.set(event.getX());
initialY.set(event.getY());
initialCoordX.set(nodeArea.getX());
initialCoordY.set(nodeArea.getY());
initialWidth.set(nodeArea.getWidth());
initialHeight.set(nodeArea.getHeight());
});
switch (borderLine) {
case LEFT -> {
path.setCursor(Cursor.E_RESIZE);
path.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
double deltaX = (event.getX() - initialX.get()) * 1, newWidth = initialWidth.get() - deltaX;
if (newWidth < MIN_POSSIBLE_WIDTH) {
event.consume();
return;
}
nodeArea.setWidth(newWidth);
nodeArea.setX(initialCoordX.get() + deltaX);
event.consume();
});
}
case TOP -> {
path.setCursor(Cursor.S_RESIZE);
path.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
double deltaY = (initialY.get() - event.getY()) * 1, newHeight = initialHeight.get() + deltaY;
if (newHeight < MIN_POSSIBLE_HEIGHT) {
event.consume();
return;
}
nodeArea.setHeight(newHeight);
nodeArea.setY(initialCoordY.get() - deltaY);
event.consume();
});
}
case RIGHT -> {
path.setCursor(Cursor.E_RESIZE);
path.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
double deltaX = (-initialX.get() + event.getX()) * 1, newWidth = initialWidth.get() + deltaX;
if (newWidth < MIN_POSSIBLE_WIDTH) {
event.consume();
return;
}
nodeArea.setWidth(newWidth);
event.consume();
});
}
case BOTTOM -> {
path.setCursor(Cursor.S_RESIZE);
path.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
double deltaY = (event.getY() - initialY.get()) * 1, newHeight = initialHeight.get() + deltaY;
if (newHeight < MIN_POSSIBLE_HEIGHT) {
event.consume();
return;
}
nodeArea.setHeight(newHeight);
event.consume();
});
}
}
}
}
Прямоугольник nodeArea и граница работают нормально при изменении размера путем перетаскивания, однако nodeAreaPane увеличивается в другом направлении при перетаскивании слева или сверху. Вот снимок после изменения размера узла:
Я пытаюсь изменить размер узла, перетаскивая его пользовательскую границу, и это работает нормально. Однако родительская панель не увеличивается в одном направлении при перетаскивании верхней и левой границ. Вот демо, изначально у меня есть собственный класс рамки: [code]class Outline extends Group {
private final Path[] paths; private final Node node; private final DoubleProperty width;
public Outline(@NotNull Node node, double width) { this.node = node; this.width = new SimpleDoubleProperty(width); paths = new Path[]{ createBorder(BorderLine.LEFT), createBorder(BorderLine.TOP), createBorder(BorderLine.RIGHT), createBorder(BorderLine.BOTTOM) };
setManaged(false); getChildren().addAll(paths); }
@NotNull private Path createBorder(@NotNull BorderLine borderLine) { MoveTo moveTo = new MoveTo(); LineTo lineTo = new LineTo();
Path path = new Path(moveTo, lineTo); path.strokeWidthProperty().bind(width); return path; }
private void applyBounds(@NotNull BorderLine borderLine, Bounds bounds, MoveTo moveTo, LineTo lineTo) { switch (borderLine) { case LEFT -> { moveTo.setX(bounds.getMinX()); moveTo.setY(bounds.getMinY()); lineTo.setX(bounds.getMinX()); lineTo.setY(bounds.getMaxY()); } case TOP -> { moveTo.setX(bounds.getMinX()); moveTo.setY(bounds.getMinY()); lineTo.setX(bounds.getMaxX()); lineTo.setY(bounds.getMinY()); } case RIGHT -> { moveTo.setX(bounds.getMaxX()); moveTo.setY(bounds.getMinY()); lineTo.setX(bounds.getMaxX()); lineTo.setY(bounds.getMaxY()); } case BOTTOM -> { moveTo.setX(bounds.getMinX()); moveTo.setY(bounds.getMaxY()); lineTo.setX(bounds.getMaxX()); lineTo.setY(bounds.getMaxY()); } } }
public Path[] getPaths() { return paths; }
public enum BorderLine { LEFT, RIGHT, TOP, BOTTOM; } } [/code] Далее у меня есть класс ResizableNode, который пытается ограничить себя предыдущей границей, а также добавляет изменение размера путем перетаскивания логики к границе: [code]class ResizableNode extends Pane {
public final double MIN_POSSIBLE_WIDTH = 10; public final double MIN_POSSIBLE_HEIGHT = 10;
private final Rectangle nodeArea = new Rectangle(140, 140, Color.TRANSPARENT);
public ResizableNode() { Outline outline = new Outline(nodeArea, 4);
Pane nodeAreaPane = new Pane(nodeArea, outline); nodeAreaPane.setBackground(Background.fill(Color.RED));
getChildren().addAll(nodeAreaPane); }
private void makeResizeable(@NotNull BorderLine borderLine, @NotNull Path path) { final AtomicReference initialX = new AtomicReference(0.0), initialY = new AtomicReference(0.0), initialCoordX = new AtomicReference(0.0), initialCoordY = new AtomicReference(0.0), initialWidth = new AtomicReference(0.0), initialHeight = new AtomicReference(0.0);
} [/code] Прямоугольник nodeArea и граница работают нормально при изменении размера путем перетаскивания, однако nodeAreaPane увеличивается в другом направлении при перетаскивании слева или сверху. Вот снимок после изменения размера узла: [img]https://i.sstatic.net/Jya4Ir2C.png[/img]
Pane nodeAreaPane = new Pane(nodeArea, outline); nodeAreaPane.setBackground(Background.fill(Color.RED));
getChildren().addAll(nodeAreaPane); }
private void makeResizeable(@NotNull BorderLine borderLine, @NotNull Path path) { final AtomicReference initialX = new AtomicReference(0.0), initialY = new AtomicReference(0.0), initialCoordX = new AtomicReference(0.0), initialCoordY = new AtomicReference(0.0), initialWidth = new AtomicReference(0.0), initialHeight = new AtomicReference(0.0);
I have four main functional areas of my app that can be accessed by the user via a custom tab bar at the bottom of the the ContentView. I want to use a slide transition to move between the views when the user taps the desired function in the tab...
Я пытаюсь анимировать маленькие пузырьки в своем SVG. Но когда масштаб применяется, создается впечатление, что он применяется к расстояниям между пузырьками, а не только к пузырькам. Это заставляет бубле двигаться в сторону, а не вверх, только так,...
Я пытаюсь анимировать маленькие пузырьки в своем SVG. Но когда масштаб применяется, создается впечатление, что он применяется к расстояниям между пузырьками, а не только к пузырькам. Это заставляет бубле двигаться в сторону, а не вверх, только так,...
Я создаю пользовательскую фото карусель в Jetpack Compose с использованием horizontalpager . Цель состоит в том, чтобы создать эффект «вентилятора» или «стека», в котором центральный элемент полностью видим, а элементы по бокам частично видны,...