ImageView上的Border-Radius和Shadow

时间:2013-12-10 08:54:33

标签: javafx

我想在JavaFX中应用border-radius和shadow。

在CSS3中它将是:

box-shadow: rgba(0,0,0,0.8) 0 0 10px;
border-radius: 3px;

现在我想在JavaFX中使用它,但即使是border-radius也不能在JavaFX Scene Builder中使用。以下是我的问题的屏幕截图:

JavaFX Screenshot http://rapid-img.de/images/b92e2112.jpg

在屏幕截图中,您可以看到我使用:

-fx-border-radius: 10 10 10 10;
-fx-background-radius: 10 10 10 10;

3 个答案:

答案 0 :(得分:44)

使用以下css获取投影:

-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 0);

有关详细信息,请参阅JavaFX CSS Reference guide

要获得除投影之外的边框,请将包含图像的ImageView放在StackPane中。并将上面的效果css应用于StackPane,以及StackPane上的背景和填充。

例如,下面应用于包含ImageView的StackPane的CSS将在图像周围提供红色边框:

-fx-padding: 10;
-fx-background-color: firebrick;

如果您希望定义边框的背景在边缘处弯曲,请使用:

-fx-background-radius: 5;

这会为您提供如下图像,其中您的图像被包围在阴影边框中:

batmanlost

如果你想实际对图像进行舍入,那就有点棘手了。您需要将一些代码应用于:

  1. 将图像剪切为圆角矩形。
  2. 快照剪裁的图像。
  3. 将快照图像存储回ImageView。
  4. 从ImageView中删除剪辑。
  5. 将阴影效果应用于ImageView。
  6. 然后你可以得到类似下面的东西:

    whereisbatman

    一些代码" 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();
        }
    }
    

    使用一些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>
    

答案 1 :(得分:7)

如果您使用jewelsea提供的答案,请务必先测试是否支持剪辑:

Platform.isSupported(ConditionalFeature.SHAPE_CLIP)

我尝试避免使用条件功能,除非我必须使用它们。就我而言,我想拍一张照片。因此,另一种方法是使用Circle代替ImageView

Circle circle = new Circle(14);
ImagePattern pattern = new ImagePattern(myImage);
circle.setFill(pattern);

如果支持,可以增强圆圈以使用阴影:

if (Platform.isSupported(ConditionalFeature.EFFECT)) {
    circle.setEffect(new DropShadow(8, Color.rgb(0, 0, 0, 0.8)));
}

答案 2 :(得分:1)

感谢马丁指向ImagePattern

enter image description here

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

请注意,此处我会调整图像的大小以使其在加载过程中与矩形大小匹配,以确保平滑度。