2016-06-19 6 views
0

내가 그런 아래 그림과 같이 투명 무대를 만들고 싶어 (윈도우 7) javaFX를 사용하여 투명한 창 스테이지를 만드는 방법은 무엇입니까? ...

that is windows 7 gadget window.. it looks like a fully glass

그래서 나는 그 형태 screencapture 방법을 만들려고 .. 그러나 그것은 혼란이었다

여기 내 코드는 희망이 문제를 더 잘 설명 할 수있다 :

import javafx.application.*; 
import javafx.embed.swing.SwingFXUtils; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.effect.*; 
import javafx.scene.image.*; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 

public class Demo extends Application{ 
    private static final double BLUR_AMOUNT = 7; 
    private static final Effect myBlur = new BoxBlur(BLUR_AMOUNT, BLUR_AMOUNT, 3); 
    private static final ImageView background = new ImageView(); 
    private static final StackPane layout = new StackPane(); 

    private Button btn=new Button("hello"); 

    @Override 
    public void start(Stage stage) { 
     layout.getChildren().addAll(background,btn); 
     layout.setStyle("-fx-background-color: null"); 

     Scene scene = new Scene(layout,300, 300,Color.TRANSPARENT); 

     stage.initStyle(StageStyle.TRANSPARENT); 
     stage.setScene(scene); 
     stage.show(); 
     stage.setX(0); 
     stage.setY(0); 

     background.setImage(copyBackground(stage)); 
     background.setEffect(myBlur); 

     makeDraggable(stage); 
    } 

    private static class Delta { 
     double x,y; 
    } 

    public void makeDraggable(final Stage stage) { 
     final Delta dragDelta = new Delta(); 
     btn.setOnMousePressed(mouseEvent -> { 
      dragDelta.x = stage.getX() - mouseEvent.getScreenX(); 
      dragDelta.y = stage.getY() - mouseEvent.getScreenY();  
     }); 

     btn.setOnMouseDragged(mouseEvent -> { 
      stage.setX(mouseEvent.getScreenX() + dragDelta.x); 
      stage.setY(mouseEvent.getScreenY() + dragDelta.y); 
      btn.setOpacity(0.0); 
      background.setImage(copyBackground(stage)); 
     }); 

     btn.setOnMouseReleased(mouseEvent -> { 
      btn.setOpacity(1.0); 
     }); 
    } 

    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!"); 
      return null; 
     } 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

답변

0

당신이보고있는 효과에 대한 이유는 로봇이 창 당신을 포함하여, 화면의 일부의 스냅 샷을 취하고 있다는 점이다 만들었습니다. 또한이 스냅 샷은 무대의 xy 속성이 변경되었지만 실제로 이동하기 전에 (따라서 로봇이 변경된 속성의 효과를보기 전에) 발생합니다. 따라서 잘못된 이미지가 생성 될 수 있습니다.

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.embed.swing.SwingFXUtils; 
import javafx.geometry.Rectangle2D; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.effect.BoxBlur; 
import javafx.scene.effect.Effect; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Screen; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 

public class Demo extends Application{ 
    private static final double BLUR_AMOUNT = 7; 
    private static final Effect myBlur = new BoxBlur(BLUR_AMOUNT, BLUR_AMOUNT, 3); 
    private static final ImageView background = new ImageView(); 
    private static final StackPane layout = new StackPane(); 

    private Button btn=new Button("hello"); 

    @Override 
    public void start(Stage stage) { 
     layout.getChildren().addAll(background,btn); 
     layout.setStyle("-fx-background-color: null"); 

     Scene scene = new Scene(layout,300, 300,Color.TRANSPARENT); 

     stage.initStyle(StageStyle.TRANSPARENT); 
     stage.setScene(scene); 
     stage.show(); 
     stage.setX(0); 
     stage.setY(0); 

     background.setImage(copyBackground(stage)); 

     background.viewportProperty().bind(Bindings.createObjectBinding(() -> 
      new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight()), 
      stage.xProperty(), stage.yProperty(), stage.widthProperty(), stage.heightProperty())); 

     background.setEffect(myBlur); 

     makeDraggable(stage); 
    } 

    private static class Delta { 
     double x,y; 
    } 

    public void makeDraggable(final Stage stage) { 
     final Delta dragDelta = new Delta(); 
     btn.setOnMousePressed(mouseEvent -> { 
      dragDelta.x = stage.getX() - mouseEvent.getScreenX(); 
      dragDelta.y = stage.getY() - mouseEvent.getScreenY();  
     }); 

     btn.setOnMouseDragged(mouseEvent -> { 
      stage.setX(mouseEvent.getScreenX() + dragDelta.x); 
      stage.setY(mouseEvent.getScreenY() + dragDelta.y); 
      btn.setOpacity(0.0); 
//   background.setImage(copyBackground(stage)); 
     }); 

     btn.setOnMouseReleased(mouseEvent -> { 
      btn.setOpacity(1.0); 
     }); 
    } 

    private Image copyBackground(Stage stage) { 

     Rectangle2D screen = Screen.getPrimary().getBounds() ; 

     final int X = (int) screen.getMinX(); 
     final int Y = (int) screen.getMinX(); 
     final int W = (int) screen.getWidth(); 
     final int H = (int) screen.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!"); 
      return null; 
     } 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

단점에 여기 :

간단한 수정 때 단계 이동 (또는 변경 크기) 이미지 뷰에 적용 뷰포트를 당신이 무대를 보여 전에 전체 화면을 스냅 샷, 다음 업데이트하는 것입니다 이미지가 응용 프로그램과 독립적으로 발생하는 바탕 화면의 변경 사항을 나타내지 않을 것이라는 점입니다. 이 문제의 한 가지 가능한 해결 방법은 WritableImage을 사용하고 해당 이미지의 일부를 동적으로 업데이트하는 것입니다. 이 아니라이 창으로 바뀌면 위치가 바뀝니다. 여기 논리는 조금 까다 롭지 만 그리 나쁘지는 않습니다.

+0

당신의 대답은 좋다 ..하지만 그것은 윈도우 7 에어로 효과처럼 작동하지 않습니다 .. 당신이 프로그램을 실행 후 당신은 화면 뒤에서 변경 ..하지만 프로그램 투명한 모양이 변경되지 않습니다 .... –

+0

예 그것이 제가 마지막 단락에서 언급 한 것입니다. –

+0

그래서 마지막 단락에서 말한 writableImage를 사용하여 올바른 코드를 보내 주실 수 있습니까? –