4

I have tried to iconified JavaFX menu item label. I got the icon duplicated for both menu item label and accelerator label. Here is an image that illustrates my issue.

enter image description here

Here is the Javafx css code:

.menu-item > .label {

}

#miRestore .label{
    -fx-graphic: url("/img/Upload_16x16.png");
}
#miBackup .label {
    -fx-graphic: url("/img/Flash%20Disk_16x16.png");
}
#miClose .label {
    -fx-graphic: url("/img/Delete_16x16.png");
}

#miSettings .label {
    -fx-graphic: url("/img/Settings_16x16.png");
}

#miRegistre . label{
    -fx-graphic: url("/img/Help_16x16.png");
}
abdou amer
  • 819
  • 2
  • 16
  • 43
  • Evidently, a MenuItem internally uses a second Label to hold its accelerator text. Changing your selectors to use `.label:first-child` might work. – VGR Apr 12 '16 at 21:27
  • @VGR, unfortunately, this not works for me at all. Even the menu icon disappears. – abdou amer Apr 13 '16 at 19:30
  • A reliable approach is to set your MenuItem graphic to a Node with a custom [style class](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#getStyleClass--), and use that in your CSS instead of (or in addition to) `.label`. – VGR Apr 14 '16 at 14:12
  • According the the [JavaFX CSS documentation](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#introscenegraph), "The structural pseudo‑classes are not supported." Which explains why the [`:first-child`](https://www.w3.org/wiki/CSS/Selectors/pseudo-classes/:first-child) would not work. – jewelsea Apr 26 '17 at 21:56

1 Answers1

6

I have found a reliable solution to this: in Scene Builder / FXML (whatever you prefer), attach a Style Class (not id) to every menu-Item you want to have an icon. Now add a stylesheet to the menubar in which you put the following CSS for every item with an icon:

.yourClassName > .label{
    -fx-graphic: url("yourImageUrl");
}

At the end of the CSS file, add the following to remove all the second images:

.context-menu .accelerator-text{
    -fx-graphic: none;
}

What this does is set the -fx-graphic of every -accelerator-text to 'none'. So it basically removes the image again.

Now you will only have icons in front of your menu-Item Text, not the accelerator text. To give you a concrete idea on how this is done I have made a small example for you: sample

which is the result of following CSS stylesheet added to my menubar, and corresponding CSS Style Classes added to my menu-Items:

.newIcon > .label{
    -fx-graphic: url("px16/file.png");
}
.openIcon > .label{
    -fx-graphic: url("px16/folderEmpty.png");
}
.closeIcon > .label{
    -fx-graphic: url("px16/minus.png");
}
.saveIcon > .label{
    -fx-graphic: url("px16/save.png");
}
.saveAsIcon > .label{
    -fx-graphic: url("px16/folder.png");
}
.quitIcon > .label{
    -fx-graphic: url("px16/error.png");
}
.context-menu .accelerator-text{
    -fx-graphic: none;
}

This was my first answer here on StackOverflow, I hope this will be helpful to someone.

stefan croes
  • 61
  • 1
  • 6