JavaFX对后台的影响

我正在使用它来制作一个带有磨砂玻璃效果的iOS主题JavaFX2(Java7)应用程序。 问题是此代码在ImageView上使用它的效果。 我希望它对窗口后面的任何东西使用它的效果,如下所示:

反正有吗? 我也喜欢你在上面的图像周围看到的小阴影效果。

要清楚,我不想要那个滑块或任何东西,只是能够透过窗户看到边缘周围有轻微阴影的效果。 我想使用这个iOS7-ish效果而不是aero。

这可能很重要:我正在使用Undecorator的修改版本。

冷冰冰

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); } } 

相关问题

  • JavaFX中的磨砂玻璃效果?
  • 如何创建仅在边框上具有阴影的JavaFX透明舞台?

您希望操作系统依赖窗口装饰的视觉效果只能通过操作系统提供的API实现。 因此被下面的StageStyle.TRANSPARENT淘汰了。

对于JavaFX内容本身,您可以控制stage > scene > root pane层次结构的视觉效果。 舞台和场景不(并且不旨在)支持高级样式,因此通过在下面设置为透明来消除。

 @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(); } 

但是,阴影效果与背景颜色的alpha值不相符。 您可以通过将阴影的颜色更改为另一个对比色来观察它。

输出:
在此处输入图像描述

扩展Jewlsea的答案..并且仅使用JavaFX的上述示例..

虽然这些类不是公共API,但它确实完全避免了AWT堆栈。 这是一个非公开的例子:

 // 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; } } 

添加了小阴影的结果:

  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

不透明度是Node的一个属性,它是JavaFX中用于显示在屏幕上的内容的父类。 http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#opacityProperty

因此,您只需在要消失的对象上设置不透明度即可。 然后,您必须添加某种方法来更改所需对象的不透明度。 使用图像中的滑块是一种方式,但还有其他方法。

可以使用DropShadow效果来完成阴影效果… http://docs.oracle.com/javafx/2/api/javafx/scene/effect/DropShadow.html 。 我从来没用过它。 这有点高,但如果评论中有跟进问题,我可以帮助解答。

Interesting Posts