-
Bug
-
Resolution: Unresolved
-
P4
-
9, 10
This happens (only) if hbarPolicy is AS_NEEDED. To reproduce, run the example below
- the initial hPolicy is always, hBar showing and content fully visible (note the "g" completely visible)
- press button to toggle hBar to AS_NEEDED: hbar is hidden, height of scrollPane adjusted
- decrease width of window such the hBar is visible again
- expected: height of scrollPane adjusted such that its content is fully visible
- actual: height of scrollPane not adjusted, hBar is placed above content (note the "g" not completely visible)
Problem seems to be in ScrollPaneSkin.computePrefHeight which doesn't take the height of the hBar into account (see https://stackoverflow.com/a/49390093/203657 for a workaround). Probably similar for computePrefWidth, didn't check, though.
The example:
/**
* horizontal scrollbar hides content
* https://stackoverflow.com/q/49386416/203657
*
* @author Jeanette Winzenburg, Berlin
*/
public class ScrollPaneSizingBug extends Application{
private Parent createContent() {
Text bigFatText = new Text("something");
// increase size to get out of minHeight
bigFatText.setFont(bigFatText.getFont().font(100));
ScrollPane scroll = new ScrollPane(bigFatText);
// no vbar to not interfere
scroll.setVbarPolicy(NEVER);
// start with correct height
scroll.setHbarPolicy(ALWAYS);
Button policy = new Button("toggle HBarPolicy");
policy.setOnAction(e -> {
ScrollBarPolicy p = scroll.getHbarPolicy();
scroll.setHbarPolicy(p == ALWAYS ? AS_NEEDED : ALWAYS);
});
Button measure = new Button("measure");
measure.setOnAction(e -> {
Node content = bigFatText;
ScrollBar bar = ((ScrollPaneSkin) scroll.getSkin()).getHorizontalScrollBar();
LOG.info("hbar visible? parent/scroll: " + bar.isVisible() + " / "
+ content.prefHeight(-1) + " / " + scroll.prefHeight(-1));
});
Label policyText = new Label();
policyText.textProperty().bind(scroll.hbarPolicyProperty().asString());
HBox buttons = new HBox(10, measure, policy, policyText);
BorderPane content = new BorderPane();
content.setTop(scroll);
content.setBottom(buttons);
return content;
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(ScrollPaneSizingBug.class.getName());
}
- the initial hPolicy is always, hBar showing and content fully visible (note the "g" completely visible)
- press button to toggle hBar to AS_NEEDED: hbar is hidden, height of scrollPane adjusted
- decrease width of window such the hBar is visible again
- expected: height of scrollPane adjusted such that its content is fully visible
- actual: height of scrollPane not adjusted, hBar is placed above content (note the "g" not completely visible)
Problem seems to be in ScrollPaneSkin.computePrefHeight which doesn't take the height of the hBar into account (see https://stackoverflow.com/a/49390093/203657 for a workaround). Probably similar for computePrefWidth, didn't check, though.
The example:
/**
* horizontal scrollbar hides content
* https://stackoverflow.com/q/49386416/203657
*
* @author Jeanette Winzenburg, Berlin
*/
public class ScrollPaneSizingBug extends Application{
private Parent createContent() {
Text bigFatText = new Text("something");
// increase size to get out of minHeight
bigFatText.setFont(bigFatText.getFont().font(100));
ScrollPane scroll = new ScrollPane(bigFatText);
// no vbar to not interfere
scroll.setVbarPolicy(NEVER);
// start with correct height
scroll.setHbarPolicy(ALWAYS);
Button policy = new Button("toggle HBarPolicy");
policy.setOnAction(e -> {
ScrollBarPolicy p = scroll.getHbarPolicy();
scroll.setHbarPolicy(p == ALWAYS ? AS_NEEDED : ALWAYS);
});
Button measure = new Button("measure");
measure.setOnAction(e -> {
Node content = bigFatText;
ScrollBar bar = ((ScrollPaneSkin) scroll.getSkin()).getHorizontalScrollBar();
LOG.info("hbar visible? parent/scroll: " + bar.isVisible() + " / "
+ content.prefHeight(-1) + " / " + scroll.prefHeight(-1));
});
Label policyText = new Label();
policyText.textProperty().bind(scroll.hbarPolicyProperty().asString());
HBox buttons = new HBox(10, measure, policy, policyText);
BorderPane content = new BorderPane();
content.setTop(scroll);
content.setBottom(buttons);
return content;
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(ScrollPaneSizingBug.class.getName());
}