JoseRivas1998
JoseRivas1998

Reputation: 553

Text with Icon on MenuItem JavaFx

I am working on a project using JavaFX. I have included FontAwesome in my project to avoid using images for simple icons. I created the following function in a constants class that generates an HBox with an icon and text that will be called in the setGraphic(Node node). The function is as follows:

public static HBox iconText(String icon, String text) {
    return ConstantsClass.iconText(icon, text, 5);
}

public static HBox iconText(String icon, String text, int spacing) {
    HBox box = new HBox(spacing);
    Label iconLabel = new Label(icon);
    iconLabel.setFont(ConstantsClass.fontAwesome);
    Label textLabel = new Label(text);
    box.getChildren().addAll(iconLabel, textLabel);
    return box;
}

The method works perfectly on buttons, such as having a back button with an arrow icon. However it does not seem to work on MenuItems.

I have a menu bar at the top of my application with Menus in them, and MenuItems in those. I tried the same process with a "settings" MenuItem, but the text does not appear unless the cursor is over the item.

MenuItem settings = new MenuItem();
settings.setGraphic(ConstantsClass.iconText(FontAwesome.COG, "Settings")); //Obscuring name of Constants Class

This code has the following results:

When the user just clicks on the menu drop down

When the user hovers over the Menu Item

How can I make the MenuItem always show the icon and text?

Upvotes: 2

Views: 2690

Answers (1)

jewelsea
jewelsea

Reputation: 159566

It's kind of weird it looks like a bug. If there is no label in the graphic, the graphic seems to display OK (for instance a rectangle seems to work correctly as a graphic). My guess is it is some kind of mess-up in the interaction between the CSS styling rules and the menu skin implementation.

A workaround is to use a snapshot, but that somehow makes the thing being snapshot slightly bold in appearance.

broken broken highlight fixed snapshot

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class MenuDisplay extends Application {
    public void start(Stage stage) throws Exception {
        Label label = new Label("(*)");
        label.setStyle("-fx-background-color: null;");
        Scene dummyScene = new Scene(label, Color.TRANSPARENT);
        SnapshotParameters params = new SnapshotParameters();
        params.setFill(Color.TRANSPARENT);
        Image snapshot = label.snapshot(params, null);
        ImageView imageView = new ImageView(snapshot);

        Menu menu = new Menu("Choices");
        menu.getItems().addAll(
            new MenuItem("Broken Label Graphic", new Label("(*)")),
            new MenuItem("OK Rect", new Rectangle(16, 16, Color.FORESTGREEN)),
            new MenuItem("Fixed Snapshot", imageView)
        );
        MenuBar menuBar = new MenuBar(menu);

        Scene scene = new Scene(
                new VBox(menuBar), 100, 100
        );

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Maybe somebody else can come up with a better workaround (or fix).

Upvotes: 3

Related Questions