Overview
JFile is a versatile file upload component supporting multiple display modes, drag-and-drop, file validation, and image previews.
Constructors
// Default mode (BUTTON)
JFile fileUpload = new JFile();
// With specific mode
JFile fileUpload = new JFile(JFile.Mode mode);
Display mode (BUTTON, AVATAR, SQUARE, DROP_ZONE)
Modes
Mode Enum
public enum Mode {
BUTTON, // Standard upload button
AVATAR, // Circular avatar uploader (120x120)
SQUARE, // Square image uploader (120x120)
DROP_ZONE // Large drag-and-drop area
}
Properties
Current display modefileUpload.setMode(JFile.Mode.AVATAR);
Mode current = fileUpload.getMode();
List of selected filesObservableList<File> files = fileUpload.getSelectedFiles();
- Read-only, observable
- Automatically updated on file selection
Allowed file extensionsfileUpload.getValidExtensions().addAll(".png", ".jpg", ".jpeg");
- Empty list = all extensions allowed
- Include the dot:
".pdf" not "pdf"
Maximum file size in bytesfileUpload.setMaxFileSize(5 * 1024 * 1024); // 5 MB
long max = fileUpload.getMaxFileSize();
- Default: 10 MB (10,485,760 bytes)
Maximum number of files allowedfileUpload.setMaxFileCount(3);
int max = fileUpload.getMaxFileCount();
- Default: 1
- When > 1, enables multi-file selection
Show remove button on AVATAR/SQUARE modesfileUpload.setShowRemove(true);
Show edit button on AVATAR/SQUARE modesfileUpload.setShowEdit(true);
Methods
File Management
Clears all selected files
Returns the list of selected filesObservableList<File> files = fileUpload.getSelectedFiles();
if (!files.isEmpty()) {
File first = files.get(0);
System.out.println("Selected: " + first.getName());
}
Image Preview
Sets a preview image (AVATAR/SQUARE modes)Image img = new Image("file:/path/to/image.png");
fileUpload.setPreviewImage(img);
JavaFX Image to display, or null to clear
Loads and sets preview from a fileFile imageFile = new File("/path/to/profile.jpg");
fileUpload.setPreviewFromFile(imageFile);
Image file to load and display
Mode Control
Rebuilds the UI for the current mode
- Called automatically when mode changes
- Useful for manual refresh after property changes
Example Usage
Button Mode (Default)
JFile fileUpload = new JFile();
fileUpload.setMaxFileSize(20 * 1024 * 1024); // 20 MB
fileUpload.getValidExtensions().addAll(".pdf", ".doc", ".docx");
fileUpload.getSelectedFiles().addListener(
(ListChangeListener.Change<? extends File> c) -> {
while (c.next()) {
if (c.wasAdded()) {
c.getAddedSubList().forEach(file ->
System.out.println("Uploaded: " + file.getName())
);
}
}
}
);
Avatar Mode (Profile Picture)
JFile avatarUpload = new JFile(JFile.Mode.AVATAR);
avatarUpload.getValidExtensions().addAll(".png", ".jpg", ".jpeg");
avatarUpload.setMaxFileSize(2 * 1024 * 1024); // 2 MB
avatarUpload.setShowRemove(true);
avatarUpload.setShowEdit(true);
// Load existing avatar
File existingAvatar = user.getAvatarFile();
if (existingAvatar != null) {
avatarUpload.setPreviewFromFile(existingAvatar);
}
// Listen for changes
avatarUpload.getSelectedFiles().addListener(
(ListChangeListener.Change<? extends File> c) -> {
if (!avatarUpload.getSelectedFiles().isEmpty()) {
File newAvatar = avatarUpload.getSelectedFiles().get(0);
uploadAvatarToServer(newAvatar);
}
}
);
Square Mode (Product Image)
JFile productImage = new JFile(JFile.Mode.SQUARE);
productImage.getValidExtensions().addAll(".png", ".jpg", ".webp");
productImage.setMaxFileSize(5 * 1024 * 1024); // 5 MB
productImage.setShowEdit(true);
// Set from URL
Image defaultImage = new Image(product.getImageUrl());
productImage.setPreviewImage(defaultImage);
Drop Zone Mode (Multiple Files)
JFile dropZone = new JFile(JFile.Mode.DROP_ZONE);
dropZone.setMaxFileCount(10);
dropZone.setMaxFileSize(50 * 1024 * 1024); // 50 MB per file
dropZone.getValidExtensions().addAll(".pdf", ".doc", ".xls", ".ppt");
dropZone.setPrefHeight(200);
dropZone.getSelectedFiles().addListener(
(ListChangeListener.Change<? extends File> c) -> {
int count = dropZone.getSelectedFiles().size();
System.out.println(count + " files selected");
}
);
Form Integration
public class UserProfileForm extends VBox {
private final JTextField nameField;
private final JTextField emailField;
private final JFile avatarUpload;
public UserProfileForm() {
setSpacing(16);
setPadding(new Insets(20));
nameField = new JTextField();
nameField.setPlaceholder("Full Name");
emailField = new JTextField();
emailField.setPlaceholder("Email Address");
avatarUpload = new JFile(JFile.Mode.AVATAR);
avatarUpload.getValidExtensions().addAll(".png", ".jpg");
avatarUpload.setShowRemove(true);
avatarUpload.setShowEdit(true);
JLabel avatarLabel = new JLabel("Profile Picture");
avatarLabel.addClass("text-sm", "font-bold");
getChildren().addAll(
new JLabel("Personal Information").addClass("text-lg", "font-bold"),
nameField,
emailField,
avatarLabel,
avatarUpload
);
}
public void loadUser(User user) {
nameField.setText(user.getName());
emailField.setText(user.getEmail());
if (user.getAvatarPath() != null) {
avatarUpload.setPreviewFromFile(new File(user.getAvatarPath()));
}
}
public void save() {
User user = new User();
user.setName(nameField.getText());
user.setEmail(emailField.getText());
if (!avatarUpload.getSelectedFiles().isEmpty()) {
File avatar = avatarUpload.getSelectedFiles().get(0);
user.setAvatar(avatar);
}
userService.save(user);
}
}
Validation
The component automatically validates:
- File count: Ensures
selectedFiles.size() <= maxFileCount
- File size: Each file must be
<= maxFileSize
- Extensions: Files must match
validExtensions (if not empty)
Errors are displayed below the component with the .error-text style class.
Drag & Drop
- All modes support drag-and-drop from file explorer
- Visual feedback with
.drag-over style class
- Validates files before accepting drop
- Shows error message if validation fails
Styling
Style classes:
.j-file - Main container
.j-file.button - Button mode
.j-file.avatar - Avatar mode
.j-file.square - Square mode
.j-file.drop-zone - Drop zone mode
.j-file-preview-wrapper - Image preview container
.j-file-overlay - Hover overlay (AVATAR/SQUARE)
.j-file-actions - Action buttons container
.j-file-action-btn - Edit/remove buttons
.error-text - Validation error label
.drag-over - Applied during drag hover
Notes
- Avatar and Square modes are 120×120px by default
- Avatar uses circular clipping (
Circle)
- Square uses rounded rectangle clipping (12px arc)
- Drop zone adapts height to content
- File chooser dialog respects
maxFileCount (single vs. multiple)
- Image preview uses
ImagePattern for proper scaling
- Error state applies
.error class to main container
- Supports both click-to-upload and drag-and-drop