Skip to main content

Overview

JDraggableField extends JSidebarItem to create draggable field items for use with JDesignCanvas. It enables drag-and-drop field assignment in label design applications.

Constructor

JDraggableField field = new JDraggableField(
    String fieldId,
    String fieldName,
    JIcon icon
);
fieldId
String
required
Unique identifier for the field (e.g., "customer_name")
  • Used as drag data payload
  • Typically lowercase with underscores
fieldName
String
required
Display name shown in the sidebar (e.g., "Customer Name")
  • Human-readable label
  • Shown with the icon
icon
JIcon
Icon displayed next to the field name
  • Can be null for no icon
  • Rendered as SVG graphic

Properties

getFieldId
String
Returns the field’s unique identifier
String id = field.getFieldId();
getFieldName
String
Returns the field’s display name
String name = field.getFieldName();

Drag Behavior

Automatic Drag Detection

  • Drag starts on mouse press + drag gesture
  • Transfer mode: COPY (does not remove source)
  • Drag view: Snapshot of the field item
  • Clipboard content: The fieldId string

Drag Data

When dragged, the component places the fieldId in the dragboard:
Dragboard db = startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString(fieldId); // e.g., "customer_name"
db.setContent(content);
Drop targets (like JDesignCanvas) can read this string to identify the field.

Example Usage

Creating Draggable Fields

// Customer information fields
JDraggableField nameField = new JDraggableField(
    "customer_name",
    "Customer Name",
    JIcon.PERSON
);

JDraggableField addressField = new JDraggableField(
    "customer_address",
    "Address",
    JIcon.PLACE
);

JDraggableField phoneField = new JDraggableField(
    "customer_phone",
    "Phone Number",
    JIcon.CALL
);

// Order fields
JDraggableField orderIdField = new JDraggableField(
    "order_id",
    "Order ID",
    JIcon.BARCODE
);

JDraggableField orderDateField = new JDraggableField(
    "order_date",
    "Order Date",
    JIcon.CALENDAR
);

Organizing in Sidebar

JLabel customerHeader = new JLabel("Customer Info");
customerHeader.addClass("text-sm", "font-bold", "text-gray-600");

JLabel orderHeader = new JLabel("Order Info");
orderHeader.addClass("text-sm", "font-bold", "text-gray-600");

VBox sidebar = new VBox(8);
sidebar.setPadding(new Insets(16));
sidebar.getStyleClass().add("j-sidebar");
sidebar.getChildren().addAll(
    customerHeader,
    nameField,
    addressField,
    phoneField,
    new Separator(),
    orderHeader,
    orderIdField,
    orderDateField
);

Complete Label Designer

public class LabelDesigner extends BorderPane {
    
    private final JDesignCanvas canvas;
    private final VBox fieldsSidebar;
    
    public LabelDesigner() {
        canvas = new JDesignCanvas();
        canvas.setSupportedLines(3);
        
        // Create fields
        List<JDraggableField> fields = List.of(
            new JDraggableField("name", "Full Name", JIcon.PERSON),
            new JDraggableField("email", "Email", JIcon.EMAIL),
            new JDraggableField("phone", "Phone", JIcon.CALL),
            new JDraggableField("barcode", "Barcode", JIcon.BARCODE)
        );
        
        fieldsSidebar = new VBox(10);
        fieldsSidebar.setPadding(new Insets(20));
        fieldsSidebar.setPrefWidth(250);
        fieldsSidebar.getStyleClass().add("fields-panel");
        
        JLabel title = new JLabel("Available Fields");
        title.addClass("text-lg", "font-bold");
        
        fieldsSidebar.getChildren().add(title);
        fieldsSidebar.getChildren().addAll(fields);
        
        // Layout
        setLeft(fieldsSidebar);
        setCenter(canvas);
        
        // Add zoom controls
        JZoom zoom = new JZoom();
        zoom.setOnZoomIn(() -> canvas.zoomIn());
        zoom.setOnZoomOut(() -> canvas.zoomOut());
        
        StackPane canvasWrapper = new StackPane(canvas);
        StackPane.setAlignment(zoom, Pos.TOP_RIGHT);
        StackPane.setMargin(zoom, new Insets(20));
        canvasWrapper.getChildren().add(zoom);
        
        setCenter(canvasWrapper);
    }
}

Programmatic Field Data

// Load fields from database
List<FieldDefinition> fieldDefs = database.getFieldDefinitions();

VBox sidebar = new VBox(8);
for (FieldDefinition def : fieldDefs) {
    JIcon icon = switch (def.getType()) {
        case "text" -> JIcon.FILE_TEXT;
        case "barcode" -> JIcon.BARCODE;
        case "date" -> JIcon.CALENDAR;
        default -> JIcon.TAG;
    };
    
    JDraggableField field = new JDraggableField(
        def.getId(),
        def.getDisplayName(),
        icon
    );
    
    sidebar.getChildren().add(field);
}

Styling

Style classes:
  • .j-draggable-field - Main container
  • Inherits all styles from JSidebarItem
Custom styling:
.j-draggable-field {
    -fx-cursor: hand;
}

.j-draggable-field:hover {
    -fx-background-color: rgba(59, 130, 246, 0.1);
}

Integration with JDesignCanvas

The canvas automatically handles dropped fields:
// Canvas receives the fieldId string
setOnDragDropped(event -> {
    String fieldId = event.getDragboard().getString();
    // fieldId = "customer_name"
    updateSlot(slot, fieldId);
});

Notes

  • Extends JSidebarItem for consistent sidebar appearance
  • Drag snapshot provides visual feedback during drag
  • Field remains in sidebar after drag (copy mode)
  • Can be used with any drop target that accepts string data
  • Icon is optional (pass null for text-only fields)
  • fieldId should be unique within the field set

Build docs developers (and LLMs) love