Creating Custom Menu Separator in JavaFX

We can create custom menu easily in JavaFX using CustomMenuItem class. I was thinking that using that class, I can creat menu separator that has label. What I want to use with that was to group menu items. Each group should have label name using the menu separator. So, I created a component namely LabelSeparator that will fill CustomMenuItem.

public class LabelSeparator extends StackPane {

    private Label lblText;

    public LabelSeparator(String label) {
        this(label, true);

    public LabelSeparator(String label, boolean topPading) {
        HBox line = HBoxBuilder.create()
        if (topPading) {
            setPadding(new Insets(10, 0, 0, 0));
        lblText = LabelBuilder.create().text(label).build();
        this.getChildren().addAll(line, lblText);


    public void setText(String label) {

    public String getText() {
        return textProperty().get();

    public StringProperty textProperty() {
        return lblText.textProperty();

But when I used that class to fill CustomMenuItem and added it to ContextMenu, the menu item didn’t fill horizontally as I expected. It also still received blue-background when hovered. I checked the source code of SeparatorMenuItem, but I found no clues. I checked deeper by searching what classes use SeparatorMenuItem. I found that there are many line of

if (item instanceof SeparatorMenuItem) {

I came to a conclusion that SeparatorMenuItem is treated differently.

So I changed my approach. I created a class extending SeparatorMenuItem so it will be treated as one.

public class LabelSeparatorMenuItem extends SeparatorMenuItem {

    public LabelSeparatorMenuItem(String label) {
        this(label, true);

    public LabelSeparatorMenuItem(String label, boolean topPading) {
        LabelSeparator content = new LabelSeparator(label, topPading);



Nice, It worked as expected. The separator filled horizontally and it ignored mouse events.


The CSS for LabelSeparator is below

.label-separator .line {
    -fx-border-color: derive(-fx-background, -25%) -fx-background derive(-fx-background, 40%) -fx-background;

.label-separator .label {
        linear-gradient(#38424b 0%, #1f2429 20%, #191d22 100%),
        linear-gradient(#20262b, #191d22),
        radial-gradient(center 50% 0%, radius 100%, rgba(114,131,148,0.9), rgba(255,255,255,0));
    -fx-background-radius: 5,4,3,5;
    -fx-background-insets: 0,1,2,0;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
    -fx-font-family: "Arial";
    -fx-text-fill: linear-gradient(white, #d0d0d0);
    -fx-font-size: 12px;
    -fx-padding: 2 10;


  • Daniel

    What specifically did you have to do to disable mouse events? I’ve got separators in a ListView inside a PopupControl, and I want to have just plain lines, without them taking up a row in the list… any ideas?

  • Robert Lichtenberger

    Thanks for the great article. Exactly what I was looking for :-)