Recommended Approach - Use built-in layout managers + sizing hints
I recommend not setting the layout values for the node unless you need to. Instead if you use standard layout containers, then it (should) by default snap any non-integer layout co-ordinates to integral values allowing clean layout of the system without potential bluriness caused by anti-aliasing of fractional layout values that cause text and lines to not align directly on the screen pixel grid.
Sample Code Without Fuzziness
When I ran a modified sample on my machine which does not perform layout by binding but instead does layout only using layout managers, I did not observe and blurry values (win 7, JavaFX 8u20). I also did not need to modify the default node caching hints.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class NonBlurryPane extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
VBox pane = new VBox();
pane.setPrefSize(500, 500);
Scene scene = new Scene(pane);
ScrollPane scroll = new ScrollPane();
StackPane scrollContainer = new StackPane(scroll);
VBox.setVgrow(scrollContainer, Priority.ALWAYS);
// Center ScrollPane
scroll.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
scroll.setPrefSize(200, 200);
scroll.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
ListView<String> list = new ListView<>();
scroll.setContent(list);
list.getItems().addAll("Resize the window", "and see how this list", "does NOT become blurry");
// Label indicates x, y coords of ScrolPane and their ratio.
TextField size = new TextField();
size.setMaxWidth(Double.MAX_VALUE);
size.setMinHeight(Region.USE_PREF_SIZE);
size.textProperty().bind(
scroll.layoutXProperty()
.asString("x: %s; ").concat(
scroll.layoutYProperty()
.asString("y: %s; ")).concat(
scroll.layoutXProperty().divide(scroll.layoutYProperty())
.asString("x/y: %s; ")).concat(
scroll.layoutYProperty().divide(scroll.layoutXProperty())
.asString("y/x: %s")));
pane.getChildren().addAll(size, scrollContainer);
stage.setScene(scene);
stage.show();
}
}
I also noticed that default layout managers round double coords to integer coords. Is that possible to make the number bindings work in this way?
Binding Integer Co-ordinates
Integer co-ordinates are a bit of a simplification. Sometimes you want co-ordinates which are x.5 (see How to draw a crisp, opaque hairline in JavaFX 2.2? for more details). It's a detail you don't need to worry about usually with the standard layout panes as they by default will handle clean snapping.
There is no kind of floor or round function in the standard bindings routines for Java 8. Either you can use invalidation listeners or change listeners and update based on them (instead of binding), or you can develop a custom binding which rounds to the appropriate value. For more information on these options, see the "Exploring Observable, ObservableValue, InvalidationListener, and ChangeListener" and "Using the Low-Level Binding API" sections of the Oracle JavaFX properties tutorial.
Layout Tip
The preferred way to do layout is (from easiest to more complex):
- Use a layout manager.
- Bindings or change listeners are (usually) OK for very simple layout tweaks.
- Override
layoutChildren()
in a parent for anything modestly custom and complex.
On layoutChildren()
Most of the custom layout calculations in the in-built JavaFX controls and layout managers are handled by over-riding layoutChildren()
and not through bindings. You can review the JavaFX source code and study how these are implemented. This is necessary to understand how to use layoutChildren (as I have not seen it thoroughly documented anywhere). Overriding layoutChildren is a little advanced and tricky to do well. To get predictable quality results from your layout algorithm, you need to manually account for things like padding insets, pixel snapping, accurately measuring the size of child components, etc.