I want to apply a border-radius and a shadow in JavaFX.
In CSS3 it would be:
box-shadow: rgba(0,0,0,0.8) 0 0 10px;
border-radius: 3px;
Now I want this in JavaFX, but even the border-radius is not working in the JavaFX Scene Builder. Here is a screenshot of my problem:
(source: rapid-img.de)
On the screenshot you can see that I use:
-fx-border-radius: 10 10 10 10;
-fx-background-radius: 10 10 10 10;
This example demonstrates how to add a shadow and a border on circular imageView android Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml.
Add stroke on ImageView image to display image with border using xml file. Adding border to ImageView image makes your ImageView highlight from the activity layout surface so image will look individually on application. We can easily set border on ImageView using external layout.xml file setting as ImageView background.
Border Radius in CSS3 As the name suggests, this property defines a rounded edge according to the supplied value, which indicates the radius of a circle theoretically positioned at the verticals of the element and from which you get the desired effect.
Android Round Corner ImageView Making round corners on the image by using a mask Put an ImageView and a mask view in a RelativeLayout. Make the mask view round corners and put it on top of the ImageView.
Use the following css to get a drop shadow:
-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 0);
See the JavaFX CSS Reference guide for details.
To get the border in addition to the drop shadow, place your ImageView containing your Image in a StackPane. And apply the effect css above to the StackPane, in addition to a background and padding on the StackPane.
For example the css below applied to the StackPane containing your ImageView will provide a red border around your image:
-fx-padding: 10;
-fx-background-color: firebrick;
If you want the background defining your border curved at the edges, then use:
-fx-background-radius: 5;
That gets you an image like below where your image is enclosed in a shadowed border:
If you want to actually round the image itself, it's a bit trickier. You need to apply some code to:
Then you can get something like below:
Some code for that "BatmanLost.java":
import javafx.application.Application;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.io.IOException;
public class BatmanLost extends Application {
class WingClipper {
@FXML
private ImageView imageView;
@FXML
public void initialize() {
// set a clip to apply rounded border to the original image.
Rectangle clip = new Rectangle(
imageView.getFitWidth(), imageView.getFitHeight()
);
clip.setArcWidth(20);
clip.setArcHeight(20);
imageView.setClip(clip);
// snapshot the rounded image.
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
WritableImage image = imageView.snapshot(parameters, null);
// remove the rounding clip so that our effect can show through.
imageView.setClip(null);
// apply a shadow effect.
imageView.setEffect(new DropShadow(20, Color.BLACK));
// store the rounded image in the imageView.
imageView.setImage(image);
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"batmanlostinthemix.fxml"
)
);
loader.setController(new WingClipper());
Pane batman = loader.load();
stage.setTitle("Where's Batman?");
stage.setScene(new Scene(batman));
stage.show();
}
}
With some FXML "batmanlostinthemix.fxml":
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="313.0" prefWidth="477.0" style="-fx-background-color: azure;" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<ImageView fx:id="imageView" layoutX="29.0" layoutY="44.0" fitHeight="224.0" fitWidth="400.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="http://collider.com/wp-content/uploads/lego-batman-movie-dc-super-heroes-unite-1.jpg" />
</image>
</ImageView>
</children>
</AnchorPane>
If you use the answer that jewelsea provided, then make sure to test first whether or not clipping is supported:
Platform.isSupported(ConditionalFeature.SHAPE_CLIP)
I try to avoid conditional features unless I have to use them. In my case, I wanted to make a picture round. So an alternative would be to use a Circle
instead of an ImageView
:
Circle circle = new Circle(14);
ImagePattern pattern = new ImagePattern(myImage);
circle.setFill(pattern);
The circle can be enhanced to use a shadow if supported:
if (Platform.isSupported(ConditionalFeature.EFFECT)) {
circle.setEffect(new DropShadow(8, Color.rgb(0, 0, 0, 0.8)));
}
Thanks martin for pointing ImagePattern
Rectangle rectangle = new Rectangle(0, 0, 280, 180);
rectangle.setArcWidth(30.0); // Corner radius
rectangle.setArcHeight(30.0);
ImagePattern pattern = new ImagePattern(
new Image("file:images/mustang-gt.jpg", 280, 180, false, false) // Resizing
);
rectangle.setFill(pattern);
rectangle.setEffect(new DropShadow(20, Color.BLACK)); // Shadow
Note that here Iam resizing the image to match the size of the rectangle during its load to ensure smoothness.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With