Skeleton loading placeholders with pulse animation, providing visual feedback while content is loading.
Factory Methods
JSkeleton provides static factory methods for common skeleton patterns.
JSkeleton.line(double width)
Creates a single line skeleton placeholder. Width of the line in pixels
A line skeleton with 14px height
JSkeleton.rect(double width, double height)
Creates a rectangular skeleton placeholder.
JSkeleton.avatar(double size)
Creates a circular avatar skeleton. Diameter of the circle in pixels
A circular avatar skeleton
Creates a circular avatar skeleton with default size (40px). A 40px circular avatar skeleton
JSkeleton.text(int lines)
Creates multiple text line skeletons. Number of text lines to create
A VBox containing multiple line skeletons (last line is shorter)
Creates a card skeleton with image and text placeholders. A 300px wide card skeleton with image (300x140) and text lines
Creates a user row skeleton with avatar and text lines. An HBox with 40px avatar and 2 text lines
JSkeleton.table(int rows, int cols)
Creates a table skeleton with the specified dimensions. A VBox containing table-like skeleton rows
Instance Methods
Stops the pulse animation and hides the skeleton.
Usage Examples
Basic Skeletons
// Single line
Region line = JSkeleton . line ( 280 );
// Rectangle (e.g., image placeholder)
Region imagePlaceholder = JSkeleton . rect ( 400 , 250 );
// Avatar
Region avatar = JSkeleton . avatar (); // 40px default
Region largeAvatar = JSkeleton . avatar ( 80 );
Text Loading
// 3 lines of text
Region textSkeleton = JSkeleton . text ( 3 );
// Use in a container
VBox container = new VBox ( 12 );
container . getChildren (). add ( JSkeleton . text ( 5 ));
Card Loading
// Pre-built card skeleton
Region cardSkeleton = JSkeleton . card ();
// Or build custom card
VBox customCard = new VBox ( 12 );
customCard . getChildren (). addAll (
JSkeleton . rect ( 300 , 200 ), // Image
JSkeleton . line ( 250 ), // Title
JSkeleton . text ( 3 ) // Description
);
User List Loading
VBox userList = new VBox ( 16 );
for ( int i = 0 ; i < 5 ; i ++ ) {
userList . getChildren (). add ( JSkeleton . userRow ());
}
Table Loading
// 5 rows x 4 columns
Region tableSkeleton = JSkeleton . table ( 5 , 4 );
Replace with Real Content
VBox container = new VBox ();
Region skeleton = JSkeleton . text ( 3 );
container . getChildren (). add (skeleton);
// Load data
loadData (). thenAccept (data -> {
Platform . runLater (() -> {
skeleton . setVisible ( false );
skeleton . setManaged ( false );
container . getChildren (). add ( createRealContent (data));
});
});
Stop Animation
JSkeleton skeleton = JSkeleton . line ( 300 );
// ... later
skeleton . stop (); // Stops pulsing and hides
Dashboard Skeleton
GridPane dashboard = new GridPane ();
dashboard . setHgap ( 24 );
dashboard . setVgap ( 24 );
// Stats cards
for ( int i = 0 ; i < 4 ; i ++ ) {
VBox statCard = new VBox ( 12 );
statCard . getChildren (). addAll (
JSkeleton . line ( 100 ),
JSkeleton . rect ( 60 , 40 )
);
dashboard . add (statCard, i % 2 , i / 2 );
}
// Main chart area
VBox chartArea = new VBox ( 12 );
chartArea . getChildren (). addAll (
JSkeleton . line ( 150 ),
JSkeleton . rect ( 600 , 300 )
);
dashboard . add (chartArea, 0 , 2 , 2 , 1 );
Profile Page Skeleton
VBox profile = new VBox ( 24 );
// Header with avatar
HBox header = new HBox ( 16 );
header . getChildren (). addAll (
JSkeleton . avatar ( 100 ),
new VBox ( 8 ,
JSkeleton . line ( 200 ),
JSkeleton . line ( 150 ),
JSkeleton . line ( 180 )
)
);
// Content sections
VBox content = new VBox ( 16 );
for ( int i = 0 ; i < 3 ; i ++ ) {
content . getChildren (). addAll (
JSkeleton . line ( 120 ),
JSkeleton . text ( 2 )
);
}
profile . getChildren (). addAll (header, content);
Animation
The skeleton automatically pulses with an opacity animation:
Cycles between 0.6 and 0.3 opacity
1600ms cycle duration (800ms fade out, 800ms fade in)
Infinite repeat
Automatically stops when removed from scene
Features
Automatic pulse animation
Multiple pre-built patterns
Customizable dimensions
Auto-stop when removed from scene
Lightweight and performant
Chainable factory methods
Style Classes
.j-skeleton - Base skeleton class
.j-skeleton-line - Line variant
.j-skeleton-rect - Rectangle variant
.j-skeleton-avatar - Circular avatar variant
.j-skeleton-card - Card container
Best Practices
Use skeletons that match the shape of your actual content
Keep the same layout structure as your real content
Stop animations when replacing with real content
Use appropriate sizes to avoid layout shifts
Consider showing skeletons only after a short delay to avoid flashing on fast loads