Efecto JavaFX en el fondo

Estoy usando esto para crear una aplicación JavaFX2 (Java7) con tema iOS y un efecto de vidrio esmerilado. El problema es que este código usa su efecto en un ImageView. Me gustaría usar su efecto en lo que está detrás de la ventana, así:

¿Hay alguna forma de hacer eso? También me gustaría ese pequeño efecto de sombra que ves alrededor de la imagen de arriba.

Para ser claro, no quiero ese control deslizante ni nada, solo el efecto de poder ver a través de la ventana y tener esa pequeña sombra alrededor de los bordes. Sin embargo, quiero usar este efecto iOS7-ish en lugar de aerodynamic.

Esto podría ser importante: estoy usando una versión modificada de Undecorator .

escarchado

import javafx.animation.*; import javafx.application.*; import javafx.beans.property.*; import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Insets; import javafx.scene.*; import javafx.scene.control.Label; import javafx.scene.effect.*; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.image.*; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.util.Duration; public class FrostyTech extends Application { private static final double BLUR_AMOUNT = 10; private static final Effect frostEffect = new BoxBlur(BLUR_AMOUNT, BLUR_AMOUNT, 3); private static final ImageView background = new ImageView(); private static final StackPane layout = new StackPane(); @Override public void start(Stage stage) { layout.getChildren().setAll(background, createContent()); layout.setStyle("-fx-background-color: null"); Scene scene = new Scene( layout, 200, 300, Color.TRANSPARENT ); Platform.setImplicitExit(false); scene.setOnMouseClicked(event -> { if (event.getClickCount() == 2) Platform.exit(); }); makeSmoke(stage); stage.initStyle(StageStyle.TRANSPARENT); stage.setScene(scene); stage.show(); background.setImage(copyBackground(stage)); background.setEffect(frostEffect); makeDraggable(stage, layout); } // copy a background node to be frozen over. private Image copyBackground(Stage stage) { final int X = (int) stage.getX(); final int Y = (int) stage.getY(); final int W = (int) stage.getWidth(); final int H = (int) stage.getHeight(); try { java.awt.Robot robot = new java.awt.Robot(); java.awt.image.BufferedImage image = robot.createScreenCapture(new java.awt.Rectangle(X, Y, W, H)); return SwingFXUtils.toFXImage(image, null); } catch (java.awt.AWTException e) { System.out.println("The robot of doom strikes!"); e.printStackTrace(); return null; } } // create some content to be displayed on top of the frozen glass panel. private Label createContent() { Label label = new Label("Create a new question for drop shadow effects.\n\nDrag to move\n\nDouble click to close"); label.setPadding(new Insets(10)); label.setStyle("-fx-font-size: 15px; -fx-text-fill: green;"); label.setMaxWidth(250); label.setWrapText(true); return label; } // makes a stage draggable using a given node. public void makeDraggable(final Stage stage, final Node byNode) { final Delta dragDelta = new Delta(); byNode.setOnMousePressed(mouseEvent -> { // record a delta distance for the drag and drop operation. dragDelta.x = stage.getX() - mouseEvent.getScreenX(); dragDelta.y = stage.getY() - mouseEvent.getScreenY(); byNode.setCursor(Cursor.MOVE); }); final BooleanProperty inDrag = new SimpleBooleanProperty(false); byNode.setOnMouseReleased(mouseEvent -> { byNode.setCursor(Cursor.HAND); if (inDrag.get()) { stage.hide(); Timeline pause = new Timeline(new KeyFrame(Duration.millis(50), event -> { background.setImage(copyBackground(stage)); layout.getChildren().set( 0, background ); stage.show(); })); pause.play(); } inDrag.set(false); }); byNode.setOnMouseDragged(mouseEvent -> { stage.setX(mouseEvent.getScreenX() + dragDelta.x); stage.setY(mouseEvent.getScreenY() + dragDelta.y); layout.getChildren().set( 0, makeSmoke(stage) ); inDrag.set(true); }); byNode.setOnMouseEntered(mouseEvent -> { if (!mouseEvent.isPrimaryButtonDown()) { byNode.setCursor(Cursor.HAND); } }); byNode.setOnMouseExited(mouseEvent -> { if (!mouseEvent.isPrimaryButtonDown()) { byNode.setCursor(Cursor.DEFAULT); } }); } private javafx.scene.shape.Rectangle makeSmoke(Stage stage) { return new javafx.scene.shape.Rectangle( stage.getWidth(), stage.getHeight(), Color.WHITESMOKE.deriveColor( 0, 1, 1, 0.08 ) ); } /** records relative x and y co-ordinates. */ private static class Delta { double x, y; } public static void main(String[] args) { launch(args); } } 

preguntas relacionadas

  • Efecto de vidrio esmerilado en JavaFX?
  • ¿Cómo creo una etapa transparente JavaFX con sombras solo en el borde?

El efecto visual que desea para la decoración de ventana dependiente del sistema operativo solo se puede lograr a través de las API que proporciona el sistema operativo. Y así fue eliminado por StageStyle.TRANSPARENT continuación.

Para el contenido de JavaFX, puede controlar las imágenes de la stage > scene > root pane jerarquía del stage > scene > root pane . El escenario y la escena no (y no están destinados a) admiten estilos avanzados, por lo que se eliminaron al establecer como transparente a continuación.

 @Override public void start(Stage primaryStage) { StackPane root = new StackPane(); root.setStyle("-fx-background-color: null;"); root.setPadding(new Insets(10)); DoubleProperty doubleProperty = new SimpleDoubleProperty(0); Region region = new Region(); region.styleProperty().bind(Bindings .concat("-fx-background-radius:20; -fx-background-color: rgba(56, 176, 209, ") .concat(doubleProperty) .concat(");")); region.setEffect(new DropShadow(10, Color.GREY)); Slider slider = new Slider(0, 1, .3); doubleProperty.bind(slider.valueProperty()); root.getChildren().addAll(region, slider); primaryStage.initStyle(StageStyle.TRANSPARENT); Scene scene = new Scene(root, 300, 250); scene.setFill(Color.TRANSPARENT); primaryStage.setTitle("Hello World!"); primaryStage.setScene(scene); primaryStage.show(); } 

Sin embargo, el efecto de sombra no funciona bien con el valor alfa del color de fondo. Puedes observarlo cambiando el color de la sombra por otro de contraste.

Salida:
enter image description here

Para expandir la respuesta de Jewlsea … Y usando el ejemplo anterior con JavaFX SOLAMENTE …

Si bien las clases no son API pública, evita la stack AWT por completo. Aquí hay un ejemplo no público :

 // copy a background node to be frozen over. private Image copyBackground(Stage stage) { final int X = (int) stage.getX(); final int Y = (int) stage.getY(); final int W = (int) stage.getWidth(); final int H = (int) stage.getHeight(); final Screen screen = Screen.getPrimary(); try { Robot rbt = com.sun.glass.ui.Application.GetApplication().createRobot(); Pixels p = rbt.getScreenCapture( (int)screen.getBounds().getMinX(), (int)screen.getBounds().getMinY(), (int)screen.getBounds().getWidth(), (int)screen.getBounds().getHeight(), true ); WritableImage dskTop = new WritableImage((int)screen.getBounds().getWidth(), (int)screen.getBounds().getHeight()); dskTop.getPixelWriter().setPixels( (int)screen.getBounds().getMinX(), (int)screen.getBounds().getMinY(), (int)screen.getBounds().getWidth(), (int)screen.getBounds().getHeight(), PixelFormat.getByteBgraPreInstance(), p.asByteBuffer(), (int)(screen.getBounds().getWidth() * 4) ); WritableImage image = new WritableImage(W,H); image.getPixelWriter().setPixels(0, 0, W, H, dskTop.getPixelReader(), X, Y); return image; } catch (Exception e) { System.out.println("The robot of doom strikes!"); e.printStackTrace(); return null; } } 

Resultados con una pequeña sombra añadida:

  DropShadow shdw = new DropShadow(); shdw.setBlurType(BlurType.GAUSSIAN); shdw.setColor(Color.GAINSBORO); shdw.setRadius(10); shdw.setSpread(0.12); shdw.setHeight(10); shdw.setWidth(10); layout.setEffect(shdw); 

fxScreenCapture

La opacidad es una propiedad de Node, que es la clase principal en JavaFX para las cosas que aparecen en la pantalla. http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#opacityProperty

De modo que puede establecer la opacidad del objeto que desea que se desvanezca. Luego debe agregar algún tipo de forma para cambiar la opacidad en el objeto deseado. Usar el control deslizante desde su imagen es de una manera, pero hay otras.

Las sombras paralelas se pueden hacer usando el efecto DropShadow … http://docs.oracle.com/javafx/2/api/javafx/scene/effect/DropShadow.html . Nunca lo he usado. Este es un pequeño nivel alto, pero si hay preguntas de seguimiento en los comentarios puedo ayudar a responderlas.