Reputation: 2523
I realize that I can't be the first person who desires to keep the content of a ScrollPane within the borders of the ScrollPanes viewport, yet after several hours of searching, I cannot find an answer to my question.
I've scoured Google, you.com and duckduckgo with various search terms such as
And other variations of the wording, and I have not found an answer.
I have created basic reproducible code that accurately models the data I am presenting in my actual program. It's actually quite simple:
The problem: When scrolling, the contents of the ScrollPane overlap the borders of the ScrollPanes viewport, and I cannot figure out how to tell the ScrollPane to keep the contents of the viewport within its borders.
If there is another way of doing this so that the scrollable contents stay within the borders of the viewport, I do not know of it and would appreciate any guidance towards that end.
My assumption is that the actual border of the viewport is something that can obviously be defined as to its width and color etc. but that it happens to be "painted" within the same space as the actual contents of the viewport. So that it should not be assumed that the border is any kind of an expected boundary by which the contents would then be bound... and if that is true, I accept that of course, but that doesn't help me achieve the behavior I'm after, which is to make sure that the contents do not show over the viewports borders.
Here, you can see what I'm talking about
Here is the code that will show the behavior:
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Separator;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.util.Random;
public class Main extends Application {
@Override public void start(Stage stage) throws Exception {
random = new Random(System.currentTimeMillis());
makeScrollPane();
Scene scene = new Scene(scrollPane);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.centerOnScreen();
stage.setWidth(width);
stage.setHeight(height);
stage.show();
}
private Random random;
private final double width = 300;
private final double height = 500;
private ScrollPane scrollPane;
private final String scrollStyle = Main.class.getResource("scrollpane.css").toExternalForm();
private final String labelStyle = Main.class.getResource("label.css").toExternalForm();
private void makeScrollPane() {
VBox[] contentArray = new VBox[15];
for (int x = 0; x < 15; x++) {
String boxIndex = String.valueOf(random());
String boxNum = String.valueOf(random());
String lbl1 = "Title " + boxIndex;
String lbl2 = "Item " + boxIndex;
contentArray[x] = getVBox(lbl1, lbl2, boxNum);
}
VBox vBoxContent = new VBox(contentArray);
scrollPane = new ScrollPane(vBoxContent);
scrollPane.fitToWidthProperty().set(true);
scrollPane.fitToHeightProperty().set(true);
scrollPane.getStylesheets().add(scrollStyle);
scrollPane.hbarPolicyProperty().set(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.vbarPolicyProperty().set(ScrollPane.ScrollBarPolicy.NEVER);
}
private VBox getVBox(String label1, String label2, String label3) {
Label lbl1 = newLabel(label1);
Label lbl2 = newLabel(label2);
Label lbl3 = newLabel(label3);
lbl3.setId("big");
Separator separator = new Separator();
separator.setMaxWidth(250);
separator.setHalignment(HPos.CENTER);
separator.setPadding(new Insets(0, 0, 25, 0));
VBox vBox = new VBox(20, lbl1, lbl2, lbl3, separator);
vBox.setPrefWidth(width * .9);
vBox.setPrefHeight(100);
vBox.setAlignment(Pos.CENTER);
return vBox;
}
private int random() {
return random.nextInt(1000, 9999);
}
private Label newLabel(String content) {
Label label = new Label(content);
label.getStylesheets().add(labelStyle);
label.setPrefWidth(width * .9);
label.setPrefHeight(25);
label.setAlignment(Pos.CENTER);
return label;
}
};
And the two stylesheets to go with it:
label.css
.label {
-fx-font-size: 13pt;
-fx-background-color: transparent;
-fx-font-family: "Arial";
-fx-text-fill: ghostwhite;
}
#big {
-fx-font-size: 40;
-fx-text-fill: yellow;
}
scrollpane.css
.scroll-pane .viewport {
-fx-background-color: black;
-fx-border-color: darkorange;
-fx-border-width: .7em;
}
.root {
-fx-background-color: black;
}
I appreciate any guidance in finding a way to accomplish what I'm after here.
Thank you
Upvotes: 5
Views: 209
Reputation: 2523
The solution in this case, which is technically a workaround I suppose, was to only style the ScrollPane itself with the border and leave the viewport with a black background as suggested by James_D.
Simply changing scrollpane.css did the trick:
.scroll-pane {
-fx-background-color: black;
-fx-border-color: darkorange;
-fx-border-width: .7em;
}
.scroll-pane .viewport {
-fx-background-color: black;
}
.root {
-fx-background-color: black;
}
Upvotes: 3