Scroll View
The ScrollView class provides a scrollable view of the UI controls. This control enables the user to scroll the content by panning the viewport or by using scrollbars. The following example shows a simple task of creating a scroll view with the default set to view an image.
import javafx.scene.control.ScrollView;
import javafx.scene.image.*;
def image = Image {url: "{__DIR__}roses.jpg"}
ScrollView {
node: ImageView {image: image}
}
When added to the application, this code fragment produces the following image. You can view the image by dragging the thumbs of the scrollbars, clicking the track, or clicking a left or right button (down or up button to scroll vertically).

The node instance variable defines a node that is used as the content of this scroll view. You can specify only one node here, so if you need to create a scroll view with more than one component, use layout containers, the Group class, or the CustomNode class.
In the example shown, both horizontal and vertical scrollbars are enabled. By default, scrollbars are shown when a dimension of the contents exceeds the corresponding dimension of the scroll view. However, you can change this behavior. The ScrollView class provides the scrollbar policy, which determines when scrollbars are displayed: always, never, or only when they are needed. Use the hbarPolicy and vbarPolicy instance variables to specify the scrollbar policy for the horizontal and vertical scrollbars respectively.
Set the pannable variable to true and you will be able to preview the image by clicking it and moving the mouse cursor around. The position of the scrollbars changes accordingly.
When designing a UI interface, you might need to resize the components so that they match the width or height of the scroll view. Take a moment to review the source code of the following application.
package scrollviewtofit;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.geometry.VPos;
import javafx.geometry.Insets;
def group = ToggleGroup {};
var scene: Scene;
Stage {
title: "ScrollView Sample"
scene: scene = Scene {
width: 200
height: 80
content: [
ScrollView {
width: bind scene.width
height: bind scene.height
fitToWidth: true
node: HBox {
padding: Insets {
top: 10
bottom: 10
}
spacing: 20
vpos: VPos.BOTTOM
content: [
VBox {
spacing: 10
content: [
RadioButton {
toggleGroup: group
text: "High"
}
RadioButton {
toggleGroup: group
text: "Medium"
},
RadioButton {
toggleGroup: group
text: "Low"
}
]
}
VBox {
content: [
TextBox {
columns: 15
promptText: "Type your name"
},
PasswordBox {
columns: 15
promptText: "Type your password"
echoChar: "*"
}
]
}
]
}
}
] //content
} //Scene
} //Stage
The scroll view contains radio buttons, a text box, and a password box. The size of the content exceeds the predefined size of the scroll view and a vertical scrollbar appears. However, because fitToWidth is true, the content shrinks in width and never scrolls horizontally.

By default, both fitToWidth and fitToHeight variables are false and the resizable content keeps its original size. Now remove the fitToWidth variable from the code of this application, then compile and run it again. You will see the following output.

The ScrollView class enables developers to retrieve and set the current, minimum, and maximum values of the contents in the horizontal and vertical directions. The following application uses a scroll view to display a vertical box with images. The vvalue instance variable of the ScrollView class helps to identify the currently displayed image and is used to identify the image file's name.

Look at the source code of the application.
package scrollviewsample;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.paint.Color;
def imageFiles = for (i in [1..5]) ["fw{i}.jpg"];
def images = for (file in imageFiles)Image {url: "{__DIR__}{file}" };
var box: VBox;
var sv: ScrollView;
Stage {
title: "Application title"
scene: Scene {
fill: Color.BLACK
width: 250
height: 280
content: [
sv = ScrollView {
layoutX: 10
layoutY: 10
hbarPolicy: ScrollBarPolicy.NEVER
vbarPolicy: ScrollBarPolicy.ALWAYS
node: box = VBox{
content:[
for (image in images) ImageView {
image: image
fitHeight: 80
preserveRatio: true
}
]
}
vmax: bind box.height
layoutInfo: LayoutInfo {
width: 95
height: 150
}
},//ScrollView
Label{
text: bind "{imageFiles[(sv.vvalue - 1)/80 as Integer]}"
font: Font{
size: 16
name: "Arial Bold"
}
textFill: Color.rgb(218, 218, 218)
layoutX: 20
layoutY: 160
}//Label
]//content
}//Scene
}//Stage
The hbarPolicy and vbarPolicy variables are set so that the horizontal scrollbar is never shown but the vertical scrollbar is always enabled. The maximum value of the vertical scrollbar is bound to the height of the vertical box. The following code line renders the name of the currently displayed image file.
text: bind "{imageFiles[(sv.vvalue - 1)/80 as Integer]}"
The ImageView object constrains the image height by 80 pixels. Therefore, when the vvalue - 1 is divided by 80, the result is the number of the current image in the imageFiles sequence.
In your application, you can pass specific values to the vmin/hmin, vmax/hmax, or hvalue/vvalue variables, thus dynamically updating your UI. Moreover, the ScrollView class inherits all the instance variables of the Node class, so you can apply animation or transformations to it.
Related Documents
- API Specification: ScrollView
Samples That Use Scroll View