Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX - Create Button from Icon

I've been into custom controls with JavaFX recently and was wondering what the best way is to create a button that simply is an image. For instance here on Stack Overflow we have these buttons (I suppose that in reality they are links but I want the same effect in JavaFX) that do not look like buttons at all.

enter image description here

What is the best way of creating something similar in JavaFX? I know you can add images to buttons but is there then also a way of completely removing the background (I suspect there is)?

like image 819
Ivar Eriksson Avatar asked Mar 01 '26 02:03

Ivar Eriksson


2 Answers

Just set the graphic property of the button accordingly.

Since stackoverflow uses svg paths, the following example uses SVGPath, but it could easily be changed to an ImageView and the scaling could replaced with setting fitWidth/fitHeight. If you do want to use ImageView though, you should be aware of the fact that ImageView does not provide a fill property and you need to work with opacity or with different images instead.

public static Button createIconButton(String svg) {
    SVGPath path = new SVGPath();
    path.setContent(svg);
    Bounds bounds = path.getBoundsInLocal();

    // scale to size 20x20 (max)
    double scaleFactor = 20 / Math.max(bounds.getWidth(), bounds.getHeight());
    path.setScaleX(scaleFactor);
    path.setScaleY(scaleFactor);
    path.getStyleClass().add("button-icon");

    Button button = new Button();
    button.setPickOnBounds(true); // make sure transparent parts of the button register clicks too
    button.setGraphic(path);
    button.setAlignment(Pos.CENTER);
    button.getStyleClass().add("icon-button");

    return button;
}

@Override
public void start(Stage primaryStage) {
    // the following svg paths were copied from the stackoverflow website
    HBox root = new HBox(
            createIconButton("M15.19 1H4.63c-.85 0-1.6.54-1.85 1.35L0 10.79V15c0 1.1.9 2 2 2h16a2 2 0 0 0 2-2v-4.21l-2.87-8.44A2 2 0 0 0 15.19 1zm-.28 10l-2 2h-6l-2-2H1.96L4.4 3.68A1 1 0 0 1 5.35 3h9.12a1 1 0 0 1 .95.68L17.86 11h-2.95z"),
            createIconButton("M15 2V1H3v1H0v4c0 1.6 1.4 3 3 3v1c.4 1.5 3 2.6 5 3v2H5s-1 1.5-1 2h10c0-.4-1-2-1-2h-3v-2c2-.4 4.6-1.5 5-3V9c1.6-.2 3-1.4 3-3V2h-3zM3 7c-.5 0-1-.5-1-1V4h1v3zm8.4 2.5L9 8 6.6 9.4l1-2.7L5 5h3l1-2.7L10 5h2.8l-2.3 1.8 1 2.7h-.1zM16 6c0 .5-.5 1-1 1V4h1v2z"));

    Scene scene = new Scene(root);
    scene.getStylesheets().add("style.css");
    primaryStage.setScene(scene);
    primaryStage.show();
}

style.css

/* set default fill of svg path */
.icon-button .button-icon {
    -fx-fill: #888888;
}

/* set default fill of svg path */
.icon-button:focused {
    -fx-background-color: lightblue;
    -fx-background-radius: 0;
}

/* remove default button style & set size */
.icon-button {
    -fx-background-color: transparent, transparent, transparent, transparent, transparent;
    -fx-pref-height: 30;
    -fx-pref-width: 30;
    -fx-min-height: 30;
    -fx-min-width: 30;
    -fx-max-height: 30;
    -fx-max-width: 30;
}

/* modify svg path fill for hovered/pressed button */
.icon-button:pressed .button-icon,
.icon-button:hover .button-icon {
    -fx-fill: #444444;
}
like image 112
fabian Avatar answered Mar 04 '26 18:03

fabian


I use a custom ImageButton class in my projects. This is similar to fabian's approach, but uses an ImageView. It is also a bit simpler to implement, in my view.

public class ImageButton extends Button {

    private final String STYLE_NORMAL = "-fx-background-color: transparent; -fx-padding: 2, 2, 2, 2;";
    private final String STYLE_PRESSED = "-fx-background-color: transparent; -fx-padding: 3 1 1 3;";

    public ImageButton(Image originalImage, double h, double w) {

        ImageView image = new ImageView(originalImage);
        image.setFitHeight(h);
        image.setFitHeight(w);
        image.setPreserveRatio(true);
        setGraphic(image);
        setStyle(STYLE_NORMAL);

        setOnMousePressed(event -> setStyle(STYLE_PRESSED));
        setOnMouseReleased(event -> setStyle(STYLE_NORMAL));
    }

}

Then you just need to pass it the Image and dimensions:

ImageButton newButton = new ImageButton(new Image("icon.png"), 16, 16);
like image 30
Zephyr Avatar answered Mar 04 '26 18:03

Zephyr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!