1

This is example of 4 buttons with different paddings, which demontrates the rounding of padding values.

 1st button: (3,6,4,6)   2nd button: (2.5, 6, 4.5, 6)   3rd button: (2,6,5,6)   4th button: (2.4, 6, 4.6, 6)

enter image description here

I expected some kind of antialiasing to create illusion that text is being placed between pixels.

Can this rounding be avoided? If not, then what's the purpose of padding values being double?

public class ButtonTest extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        StackPane root = new StackPane();
        HBox hBox = new HBox();
        hBox.setAlignment(Pos.CENTER);

        Button firstButton = new Button("Text");
        Button secondButton = new Button("Text");
        Button thirdButton = new Button("Text");
        Button fourthButton = new Button("Text");

        Insets firstPadding = new Insets(3, 6, 4, 6);
        Insets secondPadding = new Insets(2.5, 6, 4.5, 6);
        Insets thirdPadding = new Insets(2, 6, 5, 6);
        Insets fourthPadding = new Insets(2.4, 6, 4.6, 6);

        firstButton.setPadding(firstPadding);
        secondButton.setPadding(secondPadding);
        thirdButton.setPadding(thirdPadding);
        fourthButton.setPadding(fourthPadding);

        firstButton.setTooltip(new Tooltip(firstPadding.toString()));
        secondButton.setTooltip(new Tooltip(secondPadding.toString()));
        thirdButton.setTooltip(new Tooltip(thirdPadding.toString()));
        fourthButton.setTooltip(new Tooltip(fourthPadding.toString()));

        hBox.getChildren().add(firstButton);
        hBox.getChildren().add(secondButton);
        hBox.getChildren().add(thirdButton);
        hBox.getChildren().add(fourthButton);
        root.getChildren().add(hBox);

        Scene scene = new Scene(root, 300, 200);
        scene.getStylesheets().add("test.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }


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

}

CSS:

.button {
    -fx-snap-to-pixel: false;
}


UPDATE

The weird thing: If button is translated 0.5 or -0.5 along the Y axis, then the button is moved but text remains the same.

The first button is not translated, the second is translated by -0.5 and the third by -1. All have the same paddings.

enter image description here

The second button is blurred as expected, since it is on a mid-pixel position, but it seems that text is for some reason translated only by integer values. Maybe text is restricted to integer translations to ensure that it is always clear (readable) and not excessively blurred.

krsi
  • 1,045
  • 2
  • 14
  • 24
  • Take a look at [Region::snapToPixel](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Region.html#snapToPixelProperty) and try setting snap to pixel to false on the containers you are using (e.g. the HBox you are placing your buttons into). – jewelsea May 26 '15 at 00:50
  • Perhaps, then the [font smoothing type](http://stackoverflow.com/questions/24254000/how-to-force-anti-aliasing-in-javafx-fonts)? – jewelsea May 26 '15 at 01:00
  • It changes the font rendering, but vertical placement remains exactly the same. – krsi May 26 '15 at 01:05
  • 1
    Try setting a line graphic for each button (e.g. `button.setGraphic(new Line(0, 0, 20, 0));`). The line will be aliased across pixel boundaries if `button.setSnapToPixel(false)` and the aliasing will differ if you have button padding for partial pixels. So, I think your guess in your update is probably correct that text is always snapped to pixels regardless of the `snapToPixel` setting, while other things like graphics are not. At least with Java 8u40 on OS X 10.9 on a non-retina mac (which was my text environment). ` – jewelsea May 26 '15 at 09:16

1 Answers1

0

Although the parameters to Inset() are doubles, there is no such thing it's only a convenience. For example, you may be inside a loop and/or arrive to these coordinates by math operations, JavaFX frees you from doing the rounding yourself. Eventually coordinates have to map to pixels - the address to which is whole integer numbers of course, hence the rounding. If you have a 1400 x 1050 screen resolution, then those are the pixels you have coordinated for, only.

As for antialiasing, you set that when you define your scene as in Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing).

mohsenmadi
  • 2,277
  • 1
  • 23
  • 34