Reputation: 973
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.
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)?
Upvotes: 3
Views: 4942
Reputation: 49
Despite this being an old post, it still might be nice for those using a SceneBuilder to know that you can do this with a Button and an ImageView:
(I am using Gluon SceneBuilder)
Under 'Graphic' set the Display to 'GRAPHIC_ONLY'
Then for the in-line CSS use: -fx-background-colour: transparent;
Set the image to whatever you want
In the 'Hierarchy' pick up and drop the ImageView onto the button
Transparent Button ~ with only Image shown
Upvotes: 2
Reputation: 10253
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);
Upvotes: 5
Reputation: 82451
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();
}
/* 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;
}
Upvotes: 5