Skip to content

Commit

Permalink
8295078: TextField blurry when inside an TitledPane -> AnchorPane
Browse files Browse the repository at this point in the history
Reviewed-by: angorya, kcr, jhendrikx
  • Loading branch information
Marius Hanl committed May 17, 2023
1 parent bff41c2 commit 6aeaff3
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -265,72 +265,99 @@ private double computeWidth(final boolean minimum, final double height) {
double contentHeight = height != -1 ? height - getInsets().getTop() - getInsets().getBottom() : -1;
final List<Node> children = getManagedChildren();
for (Node child : children) {
Double leftAnchor = getLeftAnchor(child);
Double rightAnchor = getRightAnchor(child);
Double leftAnchor = getSnappedLeftAnchor(child);
Double rightAnchor = getSnappedRightAnchor(child);

double left = leftAnchor != null? leftAnchor :
(rightAnchor != null? 0 : child.getLayoutBounds().getMinX() + child.getLayoutX());
double right = rightAnchor != null? rightAnchor : 0;
double childHeight = -1;
if (child.getContentBias() == Orientation.VERTICAL && contentHeight != -1) {
// The width depends on the node's height!
childHeight = computeChildHeight(child, getTopAnchor(child), getBottomAnchor(child), contentHeight, -1);
childHeight = computeChildHeight(child, getSnappedTopAnchor(child), getSnappedBottomAnchor(child), contentHeight, -1);
}
max = Math.max(max, left + (minimum && leftAnchor != null && rightAnchor != null?
child.minWidth(childHeight) : computeChildPrefAreaWidth(child, -1, null, childHeight, false)) + right);
}

final Insets insets = getInsets();
return insets.getLeft() + max + insets.getRight();
return snappedLeftInset() + max + snappedRightInset();
}

private Double getSnappedTopAnchor(Node child) {
Double topAnchor = getTopAnchor(child);
if (topAnchor == null) {
return null;
}
return snapPositionY(topAnchor);
}

private Double getSnappedBottomAnchor(Node child) {
Double bottomAnchor = getBottomAnchor(child);
if (bottomAnchor == null) {
return null;
}
return snapPositionY(bottomAnchor);
}

private Double getSnappedLeftAnchor(Node child) {
Double leftAnchor = getLeftAnchor(child);
if (leftAnchor == null) {
return null;
}
return snapPositionX(leftAnchor);
}

private Double getSnappedRightAnchor(Node child) {
Double rightAnchor = getRightAnchor(child);
if (rightAnchor == null) {
return null;
}
return snapPositionX(rightAnchor);
}

private double computeHeight(final boolean minimum, final double width) {
double max = 0;
double contentWidth = width != -1 ? width - getInsets().getLeft()- getInsets().getRight() : -1;
final List<Node> children = getManagedChildren();
for (Node child : children) {
Double topAnchor = getTopAnchor(child);
Double bottomAnchor = getBottomAnchor(child);
Double topAnchor = getSnappedTopAnchor(child);
Double bottomAnchor = getSnappedBottomAnchor(child);

double top = topAnchor != null? topAnchor :
(bottomAnchor != null? 0 : child.getLayoutBounds().getMinY() + child.getLayoutY());
double bottom = bottomAnchor != null? bottomAnchor : 0;
double childWidth = -1;
if (child.getContentBias() == Orientation.HORIZONTAL && contentWidth != -1) {
childWidth = computeChildWidth(child, getLeftAnchor(child), getRightAnchor(child), contentWidth, -1);
childWidth = computeChildWidth(child, getSnappedLeftAnchor(child), getSnappedRightAnchor(child), contentWidth, -1);
}
max = Math.max(max, top + (minimum && topAnchor != null && bottomAnchor != null?
child.minHeight(childWidth) : computeChildPrefAreaHeight(child, -1, null, childWidth)) + bottom);
}

final Insets insets = getInsets();
return insets.getTop() + max + insets.getBottom();
return snappedTopInset() + max + snappedBottomInset();
}

private double computeChildWidth(Node child, Double leftAnchor, Double rightAnchor, double areaWidth, double height) {
if (leftAnchor != null && rightAnchor != null && child.isResizable()) {
final Insets insets = getInsets();
return areaWidth - insets.getLeft() - insets.getRight() - leftAnchor - rightAnchor;
return areaWidth - snappedLeftInset() - snappedRightInset() - leftAnchor - rightAnchor;
}
return computeChildPrefAreaWidth(child, -1, Insets.EMPTY, height, true);
}

private double computeChildHeight(Node child, Double topAnchor, Double bottomAnchor, double areaHeight, double width) {
if (topAnchor != null && bottomAnchor != null && child.isResizable()) {
final Insets insets = getInsets();
return areaHeight - insets.getTop() - insets.getBottom() - topAnchor - bottomAnchor;
return areaHeight - snappedTopInset() - snappedBottomInset() - topAnchor - bottomAnchor;
}
return computeChildPrefAreaHeight(child, -1, Insets.EMPTY, width);
}

@Override protected void layoutChildren() {
final Insets insets = getInsets();
final List<Node> children = getManagedChildren();
for (Node child : children) {
final Double topAnchor = getTopAnchor(child);
final Double bottomAnchor = getBottomAnchor(child);
final Double leftAnchor = getLeftAnchor(child);
final Double rightAnchor = getRightAnchor(child);
final Double topAnchor = getSnappedTopAnchor(child);
final Double bottomAnchor = getSnappedBottomAnchor(child);
final Double leftAnchor = getSnappedLeftAnchor(child);
final Double rightAnchor = getSnappedRightAnchor(child);
final Bounds childLayoutBounds = child.getLayoutBounds();
final Orientation bias = child.getContentBias();

Expand All @@ -355,15 +382,15 @@ private double computeChildHeight(Node child, Double topAnchor, Double bottomAnc
}

if (leftAnchor != null) {
x = insets.getLeft() + leftAnchor;
x = snappedLeftInset() + leftAnchor;
} else if (rightAnchor != null) {
x = getWidth() - insets.getRight() - rightAnchor - w;
x = getWidth() - snappedRightInset() - rightAnchor - w;
}

if (topAnchor != null) {
y = insets.getTop() + topAnchor;
y = snappedTopInset() + topAnchor;
} else if (bottomAnchor != null) {
y = getHeight() - insets.getBottom() - bottomAnchor - h;
y = getHeight() - snappedBottomInset() - bottomAnchor - h;
}

child.resizeRelocate(x, y, w, h);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,27 @@

package test.javafx.scene.layout;

import static org.junit.Assert.assertEquals;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.ParentShim;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;

import org.junit.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AnchorPaneTest {

@Test public void testNoAnchorsSet() {
@Test
public void testNoAnchorsSet() {
AnchorPane anchorpane = new AnchorPane();
MockResizable child = new MockResizable(100,200, 300,400, 500,600);
child.relocate(10, 20); // should honor position if no anchors set
Expand Down Expand Up @@ -717,4 +725,115 @@ public void testBottomAnchoredMinSizeOverridden() {
assertEquals(300, child.getWidth(), 1e-100);
assertEquals(400, child.getHeight(), 1e-100);
}

/**
* Tests the {@link Insets} snapping of the {@link AnchorPane} with different scales.
*
* @param scale the scale which is used as render scale on the {@link Stage}
* @see <a href="https://bugs.openjdk.org/browse/JDK-8295078">JDK-8295078</a>
*/
@ValueSource(doubles = { 1.0, 1.25, 1.5, 1.75, 2.0 })
@ParameterizedTest
void testAnchorPaneInsetsSnappingWithDifferentScales(double scale) {
double padding = 9.6;

StackPane child = new StackPane();
AnchorPane anchorPane = new AnchorPane(child);
anchorPane.setStyle("-fx-padding: " + padding + "px;");

AnchorPane.setTopAnchor(child, 0d);
AnchorPane.setLeftAnchor(child, 0d);
AnchorPane.setBottomAnchor(child, 0d);
AnchorPane.setRightAnchor(child, 0d);

DoubleProperty renderScaleProperty = new SimpleDoubleProperty(scale);

Stage stage = new Stage();
stage.renderScaleXProperty().bind(renderScaleProperty);
stage.renderScaleYProperty().bind(renderScaleProperty);

int widthHeight = 500;
Scene scene = new Scene(anchorPane, widthHeight, widthHeight);
stage.setScene(scene);
stage.show();

Bounds boundsInParent = child.getBoundsInParent();

double snappedPaddingX = child.snapPositionX(padding);
double snappedPaddingY = child.snapPositionY(padding);

assertEquals(snappedPaddingX, boundsInParent.getMinX(), 0.0001);
assertEquals(snappedPaddingY, boundsInParent.getMinY(), 0.0001);

double expectedMaxX = widthHeight - snappedPaddingX;
assertEquals(expectedMaxX, boundsInParent.getMaxX(), 0.0001);

double expectedMaxY = widthHeight - snappedPaddingY;
assertEquals(expectedMaxY, boundsInParent.getMaxY(), 0.0001);

double expectedWidth = widthHeight - snappedPaddingX * 2;
assertEquals(expectedWidth, boundsInParent.getWidth(), 0.0001);

double expectedHeight = widthHeight - snappedPaddingY * 2;
assertEquals(expectedHeight, boundsInParent.getHeight(), 0.0001);
}

/**
* Tests the anchor snapping of the {@link AnchorPane} with different scales.
*
* @param scale the scale which is used as render scale on the {@link Stage}
* @see <a href="https://bugs.openjdk.org/browse/JDK-8295078">JDK-8295078</a>
*/
@ValueSource(doubles = { 1.0, 1.25, 1.5, 1.75, 2.0 })
@ParameterizedTest
void testAnchorPaneAnchorSnappingWithDifferentScales(double scale) {
StackPane child = new StackPane();
AnchorPane anchorPane = new AnchorPane(child);

double topAnchor = 4d;
double leftAnchor = 5d;
double bottomAnchor = 6d;
double rightAnchor = 7d;

AnchorPane.setTopAnchor(child, topAnchor);
AnchorPane.setLeftAnchor(child, leftAnchor);
AnchorPane.setBottomAnchor(child, bottomAnchor);
AnchorPane.setRightAnchor(child, rightAnchor);

DoubleProperty renderScaleProperty = new SimpleDoubleProperty(scale);

Stage stage = new Stage();
stage.renderScaleXProperty().bind(renderScaleProperty);
stage.renderScaleYProperty().bind(renderScaleProperty);

int widthHeight = 500;
Scene scene = new Scene(anchorPane, widthHeight, widthHeight);
stage.setScene(scene);
stage.show();

Bounds boundsInParent = child.getBoundsInParent();

double snappedLeftAnchor = child.snapPositionY(leftAnchor);
double snappedRightAnchor = child.snapPositionY(rightAnchor);
double horizontalAnchor = snappedLeftAnchor + snappedRightAnchor;

double snappedTopAnchor = child.snapPositionX(topAnchor);
double snappedBottomAnchor = child.snapPositionX(bottomAnchor);
double verticalAnchor = snappedTopAnchor + snappedBottomAnchor;

assertEquals(snappedLeftAnchor, boundsInParent.getMinX(), 0.0001);
assertEquals(snappedTopAnchor, boundsInParent.getMinY(), 0.0001);

double expectedMaxX = widthHeight - snappedRightAnchor;
assertEquals(expectedMaxX, boundsInParent.getMaxX(), 0.0001);

double expectedMaxY = widthHeight - snappedBottomAnchor;
assertEquals(expectedMaxY, boundsInParent.getMaxY(), 0.0001);

double expectedWidth = widthHeight - horizontalAnchor;
assertEquals(expectedWidth, boundsInParent.getWidth(), 0.0001);

double expectedHeight = widthHeight - verticalAnchor;
assertEquals(expectedHeight, boundsInParent.getHeight(), 0.0001);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
Expand Down Expand Up @@ -152,7 +153,8 @@ static Stream<ContainerCreator<?>> getContainerCreators() {
GridPane gridPane = new GridPane();
gridPane.getChildren().add(node);
return gridPane;
})
}),
new ContainerCreator<>(AnchorPane::new)
// new ContainerCreator<>(Pane::new),
// new ContainerCreator<>(StackPane::new),
// new ContainerCreator<>(BorderPane::new),
Expand All @@ -161,7 +163,6 @@ static Stream<ContainerCreator<?>> getContainerCreators() {
// tilePane.setPrefColumns(1);
// return tilePane;
// }),
// new ContainerCreator<>(AnchorPane::new), // fixed by JDK-8295078
// new ContainerCreator<>(node -> {
// FlowPane flowPane = new FlowPane(node);
// flowPane.setPrefWrapLength(0);
Expand Down

1 comment on commit 6aeaff3

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.