如何在javafx中拍摄所选屏幕区域的快照?

时间:2016-12-22 16:11:03

标签: java javafx javafx-2 javafx-8

我正在尝试对屏幕上当前打开的任何文件进行screeshots。谷歌之后我得到的只是在javafx中拍摄场景截图。我不想使用任何AWT或Swing组件。那有什么办法吗?

2 个答案:

答案 0 :(得分:2)

当前javafx.scene.robot.Robot可用,可以进行屏幕截图。我不知道是最初问这个问题的时候。方法是:

javafx.scene.robot.Robot robot = new Robot();
WritableImage imgReturn = robot.getScreenCapture(imgOut, new Rectangle2D());

可选的矩形指定要捕获的屏幕区域。如果未提供,则包括整个屏幕。可以为imgReturn分配生成的可写图像。 imgOut是可写的图像输出参数,如果您先前已定义结果并且尺寸正确,它也可以存储结果。否则,将其保留为空。

该方法必须在JavaFX Application线程上运行(如果从另一个线程调用它,则可以使用Platform.runLater()来确保此方法。)

如果您想获取特定应用程序窗口的屏幕截图,则可以分析整个屏幕的捕获情况,并查找包含要查找的窗口的区域。

如果您知道窗口的坐标和尺寸,则可以将其插入getScreenCapture中的第二个参数。

您还可以使用@ GOXR3PLUS中的半透明叠加阶段方法,用户可以在其中定义一个矩形(例如,通过单击和拖动以定义左上角和右下角)。然后,您可以隐藏叠加阶段,并对该矩形内的区域进行截图。

答案 1 :(得分:0)

这是我使用的主要机制:透明Stage透明Canvas,其BorderPane具有不透明度0.1

这是一个简单的例子(它只是用于选择区域......):

当您启动应用程序时,关闭它的唯一方法是使用ESCAPE

enter image description here

Tester 类:

import javafx.application.Application;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class Tester extends Application{

    @Override
    public void start(Stage primaryStage) throws Exception {
        CaptureWindow window = new CaptureWindow(Screen.getPrimary().getBounds().getWidth(),Screen.getPrimary().getBounds().getHeight(), primaryStage);
        window.show();

        primaryStage.show();
    }

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

捕获窗口类:

import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 * Is used to capture an area of the screen.
 *
 * @author GOXR3PLUS
 */
public class CaptureWindow extends Stage {

    /** The border pane. */
    // BorderPane and Canvas
    BorderPane borderPane = new BorderPane();

    /** The canvas. */
    Canvas canvas = new Canvas();

    /** The gc. */
    GraphicsContext gc = canvas.getGraphicsContext2D();

    /** The stage. */
    Stage stage;

    /** The width. */
    // Variables
    int width;

    /** The height. */
    int height;

    /** The x pressed. */
    int xPressed = 0;

    /** The y pressed. */
    int yPressed = 0;

    /** The x now. */
    int xNow = 0;

    /** The y now. */
    int yNow = 0;

    /** The foreground. */
    Color foreground = Color.rgb(255, 167, 0);

    /** The background. */
    Color background = Color.rgb(0, 0, 0, 0.3);

    /**
     * Constructor.
     *
     * @param screenWidth the screen width
     * @param screenHeight the screen height
     * @param primary the primary
     */
    public CaptureWindow(double screenWidth, double screenHeight, Stage primary) {
        stage = primary;

        setX(0);
        setY(0);
        setWidth(screenWidth);
        setHeight(screenHeight);
        initOwner(primary);
        initStyle(StageStyle.TRANSPARENT);
        setAlwaysOnTop(true);

        // BorderPane
        borderPane.setStyle("-fx-background-color:rgb(0,0,0,0.1);");

        // Canvas
        canvas.setWidth(screenWidth);
        canvas.setHeight(screenHeight);
        canvas.setOnMousePressed(m -> {
            xPressed = (int) m.getScreenX();
            yPressed = (int) m.getScreenY();
        });
        canvas.setOnMouseDragged(m -> {
            xNow = (int) m.getScreenX();
            yNow = (int) m.getScreenY();
            repaintCanvas();
        });

        borderPane.setCenter(canvas);

        // Scene
        setScene(new Scene(borderPane, Color.TRANSPARENT));
        getScene().setCursor(Cursor.CROSSHAIR);
        getScene().setOnKeyReleased(key -> {
            if (key.getCode() == KeyCode.B) {
                close();
                System.out.println("Key Released....");
            }else if(key.getCode() == KeyCode.ESCAPE)
                close();
        });

        // gc
        gc.setLineDashes(6);
        gc.setFont(Font.font("null", FontWeight.BOLD, 14));
    }

    /**
     * Repaints the canvas *.
     */
    protected void repaintCanvas() {

        gc.clearRect(0, 0, getWidth(), getHeight());
        gc.setStroke(foreground);
        gc.setFill(background);
        gc.setLineWidth(3);

        if (xNow > xPressed && yNow > yPressed) { // Right and Down

            calculateWidthAndHeight(xNow - xPressed, yNow - yPressed);
            gc.strokeRect(xPressed, yPressed, width, height);
            gc.fillRect(xPressed, yPressed, width, height);

        } else if (xNow < xPressed && yNow < yPressed) { // Left and Up

            calculateWidthAndHeight(xPressed - xNow, yPressed - yNow);
            gc.strokeRect(xNow, yNow, width, height);
            gc.fillRect(xNow, yNow, width, height);

        } else if (xNow > xPressed && yNow < yPressed) { // Right and Up

            calculateWidthAndHeight(xNow - xPressed, yPressed - yNow);
            gc.strokeRect(xPressed, yNow, width, height);
            gc.fillRect(xPressed, yNow, width, height);

        } else if (xNow < xPressed && yNow > yPressed) { // Left and Down

            calculateWidthAndHeight(xPressed - xNow, yNow - yPressed);
            gc.strokeRect(xNow, yPressed, width, height);
            gc.fillRect(xNow, yPressed, width, height);
        }

    }

    /**
     * Show the window.
     */
    public void showWindow() {
        xNow = 0;
        yNow = 0;
        xPressed = 0;
        yPressed = 0;
        repaintCanvas();
        show();
    }

    /**
     * Calculates the width and height of the rectangle.
     *
     * @param w the w
     * @param h the h
     */
    private final void calculateWidthAndHeight(int w, int h) {
        width = w;
        height = h;
    }

    /**
     * Selects whole Screen.
     */
    public void selectWholeScreen() {
        xPressed = 0;
        yPressed = 0;
        xNow = (int) getWidth();
        yNow = (int) getHeight();
    }

    /**
     * Return an array witch contains the (UPPER_LEFT) Point2D of the rectangle
     * and the width and height of the rectangle.
     *
     * @return the int[]
     */
    public int[] calculatedRectangle() {

        if (xNow > xPressed) { // Right
            if (yNow > yPressed) // and DOWN
                return new int[] { xPressed, yPressed, xNow - xPressed, yNow - yPressed };
            else if (yNow < yPressed) // and UP
                return new int[] { xPressed, yNow, xNow - xPressed, yPressed - yNow };
        } else if (xNow < xPressed) { // LEFT
            if (yNow > yPressed) // and DOWN
                return new int[] { xNow, yPressed, xPressed - xNow, yNow - yPressed };
            else if (yNow < yPressed) // and UP
                return new int[] { xNow, yNow, xPressed - xNow, yPressed - yNow };
        }

        return new int[] { xPressed, yPressed, xNow, yNow };
    }

这是一个完整的高级示例。它是GitHub项目Here的一部分。您可以克隆项目并根据需要进行修改。

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import org.controlsfx.control.Notifications;

import application.Main;
import application.SFileChooser;
import javafx.animation.AnimationTimer;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 * This is the Window which is used from the user to draw the rectangle
 * representing an area on the screen to be captured.
 *
 * @author GOXR3PLUS
 */
public class CaptureWindowController extends Stage {

    /** The stack pane. */
    @FXML
    private StackPane stackPane;

    /** The main canvas. */
    @FXML
    private Canvas mainCanvas;

    // -----------------------------

    /**
     * The Model of the CaptureWindow
     */
    CaptureWindowModel model = new CaptureWindowModel();

    /** The file saver. */
    SFileChooser fileSaver = new SFileChooser();

    /** The capture service. */
    final CaptureService captureService = new CaptureService();

    /** The graphics context of the canvas */
    GraphicsContext gc;

    /**
     * When a key is being pressed into the capture window then this Animation
     * Timer is doing it's magic.
     */
    AnimationTimer yPressedAnimation = new AnimationTimer() {

        private long nextSecond = 0L;
        // private static final long ONE_SECOND_NANOS = 1_000_000_000L
        private long precisionLevel;

        @Override
        public void start() {
            nextSecond = 0L;
            precisionLevel = (long) ( settingsWindowController.getPrecisionSlider().getValue() * 1_000_000L );
            super.start();
        }

        @Override
        public void handle(long nanos) {

            System.out.println("TimeStamp: " + nanos + " Current: " + nextSecond);
            System.out.println("Milliseconds Delay: " + precisionLevel / 1_000_000);

            if (nanos >= nextSecond) {
                nextSecond = nanos + precisionLevel;

                // With special key pressed
                // (we want [LEFT] and [DOWN] side of the rectangle to be
                // movable)

                // No Special Key is Pressed
                // (we want [RIGHT] and [UP] side of the rectangle to be
                // movable)

                // ------------------------------
                if (model.rightPressed.get()) {
                    if (model.shiftPressed.get()) { // Special Key?
                        if (model.mouseXNow > model.mouseXPressed) { // Mouse gone Right?
                            model.mouseXPressed += 1;
                        } else {
                            model.mouseXNow += 1;
                        }
                    } else {
                        if (model.mouseXNow > model.mouseXPressed) { // Mouse gone Right?
                            model.mouseXNow += 1;
                        } else {
                            model.mouseXPressed += 1;
                        }
                    }
                }

                if (model.leftPressed.get()) {
                    if (model.shiftPressed.get()) { // Special Key?
                        if (model.mouseXNow > model.mouseXPressed) { // Mouse gone Right?
                            model.mouseXPressed -= 1;
                        } else {
                            model.mouseXNow -= 1;
                        }
                    } else {
                        if (model.mouseXNow > model.mouseXPressed) { // Mouse gone Right?
                            model.mouseXNow -= 1;
                        } else {
                            model.mouseXPressed -= 1;
                        }
                    }
                }

                if (model.upPressed.get()) {
                    if (model.shiftPressed.get()) { // Special Key?
                        if (model.mouseYNow > model.mouseYPressed) { // Mouse gone UP?
                            model.mouseYNow -= 1;
                        } else {
                            model.mouseYPressed -= 1;
                        }
                    } else {
                        if (model.mouseYNow > model.mouseYPressed) { // Mouse gone UP?
                            model.mouseYPressed -= 1;
                        } else {
                            model.mouseYNow -= 1;
                        }
                    }
                }

                if (model.downPressed.get()) {
                    if (model.shiftPressed.get()) { // Special Key?
                        if (model.mouseYNow > model.mouseYPressed) { // Mouse gone UP?
                            model.mouseYNow += 1;
                        } else {
                            model.mouseYPressed += 1;
                        }
                    } else {
                        if (model.mouseYNow > model.mouseYPressed) { // Mouse gone UP?
                            model.mouseYPressed += 1;
                        } else {
                            model.mouseYNow += 1;
                        }
                    }
                }

                repaintCanvas();
            }
        }
    };

    /**
     * This AnimationTimer waits until the canvas is cleared before it can
     * capture the screen.
     */
    AnimationTimer waitFrameRender = new AnimationTimer() {
        private int frameCount = 0;

        @Override
        public void start() {
            frameCount = 0;
            super.start();
        }

        @Override
        public void handle(long timestamp) {
            frameCount++;
            if (frameCount >= 5) {
                stop();

                // Capture the Image
                BufferedImage image;
                int[] rect = getRectangleBounds();
                try {
                    image = new Robot().createScreenCapture(new Rectangle(rect[0], rect[1], rect[2], rect[3]));
                } catch (AWTException ex) {
                    Logger.getLogger(getClass().getName()).log(Level.INFO, null, ex);
                    return;
                } finally {
                    mainCanvas.setDisable(false);
                }

                // System.out.println("Starting Service")

                // Start the Service
                captureService.startService(image);

            }
        }
    };

    /** The counting thread. */
    Thread countingThread;

    /** The main window controller. */
    MainWindowController mainWindowController;

    /** The settings window controller. */
    SettingsWindowController settingsWindowController;

    /**
     * Constructor.
     */
    public CaptureWindowController() {

        setX(0);
        setY(0);
        getIcons().add(new Image(getClass().getResourceAsStream("/image/icon.png")));
        initStyle(StageStyle.TRANSPARENT);
        setAlwaysOnTop(true);

    }

    /**
     * Add the needed references from the other controllers.
     *
     * @param mainWindowController the main window controller
     * @param settingsWindowController the settings window controller
     */
    @SuppressWarnings("hiding")
    public void addControllerReferences(MainWindowController mainWindowController ,
            SettingsWindowController settingsWindowController) {

        this.mainWindowController = mainWindowController;
        this.settingsWindowController = settingsWindowController;
    }

    /**
     * Will be called as soon as FXML file is loaded.
     */
    @FXML
    public void initialize() {

        // System.out.println("CaptureWindow initialized")

        // Scene
        Scene scene = new Scene(stackPane, model.screenWidth, model.screenHeight, Color.TRANSPARENT);
        scene.setCursor(Cursor.NONE);
        setScene(scene);
        addKeyHandlers();

        // Canvas
        mainCanvas.setWidth(model.screenWidth);
        mainCanvas.setHeight(model.screenHeight);
        mainCanvas.setOnMousePressed(m -> {
            if (m.getButton() == MouseButton.PRIMARY) {
                model.mouseXPressed = (int) m.getScreenX();
                model.mouseYPressed = (int) m.getScreenY();
            }
        });

        mainCanvas.setOnMouseDragged(m -> {
            if (m.getButton() == MouseButton.PRIMARY) {
                model.mouseXNow = (int) m.getScreenX();
                model.mouseYNow = (int) m.getScreenY();
                repaintCanvas();
            }
        });

        // graphics context 2D
        gc = mainCanvas.getGraphicsContext2D();
        gc.setLineDashes(6);
        gc.setFont(Font.font("null", FontWeight.BOLD, 14));

        // HideFeaturesPressed
        model.hideExtraFeatures.addListener((observable , oldValue , newValue) -> repaintCanvas());
    }

    /**
     * Adds the KeyHandlers to the Scene.
     */
    private void addKeyHandlers() {

        // -------------Read the below to understand the Code-------------------

        // the default prototype of the below code is
        // 1->when the user is pressing RIGHT ARROW -> The rectangle is
        // increasing from the RIGHT side
        // 2->when the user is pressing LEFT ARROW -> The rectangle is
        // decreasing from the RIGHT side
        // 3->when the user is pressing UP ARROW -> The rectangle is increasing
        // from the UP side
        // 4->when the user is pressing DOWN ARROW -> The rectangle is
        // decreasing from the UP side

        // when ->LEFT KEY <- is pressed
        // 1->when the user is pressing RIGHT ARROW -> The rectangle is
        // increasing from the LEFT side
        // 2->when the user is pressing LEFT ARROW -> The rectangle is
        // decreasing from the LEFT side
        // 3->when the user is pressing UP ARROW -> The rectangle is increasing
        // from the DOWN side
        // 4->when the user is pressing DOWN ARROW -> The rectangle is
        // decreasing from the DOWN side

        // kemodel.yPressed
        getScene().setOnKeyPressed(key -> {
            if (key.isShiftDown())
                model.shiftPressed.set(true);

            if (key.getCode() == KeyCode.LEFT)
                model.leftPressed.set(true);

            if (key.getCode() == KeyCode.RIGHT)
                model.rightPressed.set(true);

            if (key.getCode() == KeyCode.UP)
                model.upPressed.set(true);

            if (key.getCode() == KeyCode.DOWN)
                model.downPressed.set(true);

            if (key.getCode() == KeyCode.H)
                model.hideExtraFeatures.set(true);

        });

        // keyReleased
        getScene().setOnKeyReleased(key -> {

            if (key.getCode() == KeyCode.SHIFT)
                model.shiftPressed.set(false);

            if (key.getCode() == KeyCode.RIGHT) {
                if (key.isControlDown()) {
                    model.mouseXNow = (int) getWidth();
                    repaintCanvas();
                }
                model.rightPressed.set(false);
            }

            if (key.getCode() == KeyCode.LEFT) {
                if (key.isControlDown()) {
                    model.mouseXPressed = 0;
                    repaintCanvas();
                }
                model.leftPressed.set(false);
            }

            if (key.getCode() == KeyCode.UP) {
                if (key.isControlDown()) {
                    model.mouseYPressed = 0;
                    repaintCanvas();
                }
                model.upPressed.set(false);
            }

            if (key.getCode() == KeyCode.DOWN) {
                if (key.isControlDown()) {
                    model.mouseYNow = (int) getHeight();
                    repaintCanvas();
                }
                model.downPressed.set(false);
            }

            if (key.getCode() == KeyCode.A && key.isControlDown())
                selectWholeScreen();

            if (key.getCode() == KeyCode.H)
                model.hideExtraFeatures.set(false);

            if (key.getCode() == KeyCode.ESCAPE || key.getCode() == KeyCode.BACK_SPACE) {

                // Stop Counting Thread
                if (countingThread != null)
                    countingThread.interrupt();

                // Stop MaryTTS
                Main.textToSpeech.stopSpeaking();

                // Deactivate all keys
                deActivateAllKeys();

                // show the appropriate windows
                Main.stage.show();
                close();
            } else if (key.getCode() == KeyCode.ENTER || key.getCode() == KeyCode.SPACE) {
                // Stop MaryTTS
                Main.textToSpeech.stopSpeaking();

                // Deactivate all keys
                deActivateAllKeys();

                // Capture Selected Area
                prepareImage();
            }

        });

        model.anyPressed.addListener((obs , wasPressed , isNowPressed) ->

        {
            if (isNowPressed.booleanValue()) {
                yPressedAnimation.start();
            } else {
                yPressedAnimation.stop();
            }
        });
    }

    /**
     * Deactivates the keys contained into this method.
     */
    private void deActivateAllKeys() {
        model.shiftPressed.set(false);
        model.upPressed.set(false);
        model.rightPressed.set(false);
        model.downPressed.set(false);
        model.leftPressed.set(false);
        model.hideExtraFeatures.set(false);
    }

    /**
     * Creates and saves the image.
     */
    public void prepareImage() {
        // return if it is alive
        if ( ( countingThread != null && countingThread.isAlive() ) || captureService.isRunning())
            return;

        countingThread = new Thread(() -> {
            mainCanvas.setDisable(true);
            boolean interrupted = false;

            // CountDown
            if (!mainWindowController.getTimeSlider().isDisabled()) {
                for (int i = (int) mainWindowController.getTimeSlider().getValue(); i > 0; i--) {
                    final int a = i;

                    // Lock until it has been refreshed from JavaFX
                    // Application Thread
                    CountDownLatch count = new CountDownLatch(1);

                    // Repaint the Canvas
                    Platform.runLater(() -> {
                        gc.clearRect(0, 0, getWidth(), getHeight());
                        gc.setFill(model.background);
                        gc.fillRect(0, 0, getWidth(), getHeight());
                        gc.setFill(Color.BLACK);
                        gc.fillOval(getWidth() / 2 - 90, getHeight() / 2 - 165, 250, 250);
                        gc.setFill(Color.WHITE);
                        gc.setFont(Font.font("", FontWeight.BOLD, 120));
                        gc.fillText(Integer.toString(a), getWidth() / 2, getHeight() / 2);

                        // Unlock the Parent Thread
                        count.countDown();
                    });

                    try {
                        // Wait JavaFX Application Thread
                        count.await();

                        // MaryTTS
                        if (settingsWindowController.getMarryTTSToggle().isSelected())
                            Main.textToSpeech.speak(i);

                        // Sleep 1 seconds after that
                        Thread.sleep(980);
                    } catch (InterruptedException ex) {
                        interrupted = true;
                        mainCanvas.setDisable(false);
                        countingThread.interrupt();
                        Logger.getLogger(getClass().getName()).log(Level.INFO, null, ex);
                        break;
                    }
                }
            }

            // !interrupted?
            if (!Thread.interrupted()) {
                // MaryTTS
                if (settingsWindowController.getMarryTTSToggle().isSelected())
                    Main.textToSpeech.speak("Select where the image will be saved.");

                Platform.runLater(() -> {
                    // Clear the canvas
                    gc.clearRect(0, 0, getWidth(), getHeight());

                    // Wait for frame Render
                    waitFrameRender.start();
                });
            } // !interrupted?
        });

        countingThread.setDaemon(true);
        countingThread.start();

    }

    /**
     * Repaint the canvas of the capture window.
     */
    protected void repaintCanvas() {

        gc.clearRect(0, 0, getWidth(), getHeight());
        gc.setFont(model.font);

        // draw the actual rectangle
        gc.setStroke(Color.AQUA);
        gc.setFill(model.background);
        gc.setLineWidth(1);

        // smart calculation of where the mouse has been dragged
        model.rectWidth = ( model.mouseXNow > model.mouseXPressed ) ? model.mouseXNow - model.mouseXPressed // RIGHT
                : model.mouseXPressed - model.mouseXNow // LEFT
        ;
        model.rectHeight = ( model.mouseYNow > model.mouseYPressed ) ? model.mouseYNow - model.mouseYPressed // DOWN
                : model.mouseYPressed - model.mouseYNow // UP
        ;

        model.rectUpperLeftX = // -------->UPPER_LEFT_X
                ( model.mouseXNow > model.mouseXPressed ) ? model.mouseXPressed // RIGHT
                        : model.mouseXNow// LEFT
        ;
        model.rectUpperLeftY = // -------->UPPER_LEFT_Y
                ( model.mouseYNow > model.mouseYPressed ) ? model.mouseYPressed // DOWN
                        : model.mouseYNow // UP
        ;

        gc.strokeRect(model.rectUpperLeftX - 1.00, model.rectUpperLeftY - 1.00, model.rectWidth + 2.00, model.rectHeight + 2.00);
        gc.fillRect(model.rectUpperLeftX, model.rectUpperLeftY, model.rectWidth, model.rectHeight);

        // draw the circles

        if (!model.hideExtraFeatures.getValue()) {
            // Show the Size
            double middle = model.rectUpperLeftX + model.rectWidth / 2.00;
            gc.setLineWidth(1);
            gc.setStroke(Color.AQUA);
            gc.strokeRect(middle - 78, model.rectUpperLeftY < 25 ? model.rectUpperLeftY + 2 : model.rectUpperLeftY - 26.00, 79, 25);
            gc.setFill(Color.rgb(0, 0, 00, 0.9));
            gc.fillRect(middle - 77, model.rectUpperLeftY < 25 ? model.rectUpperLeftY + 2 : model.rectUpperLeftY - 25.00, 77, 23);
            gc.setFill(Color.WHITE);
            gc.fillText(model.rectWidth + "," + model.rectHeight, middle - 77 + 9,
                    model.rectUpperLeftY < 25 ? model.rectUpperLeftY + 17.00 : model.rectUpperLeftY - 6.00);
        }
    }

    /**
     * Selects whole Screen.
     */
    private void selectWholeScreen() {
        model.mouseXPressed = 0;
        model.mouseYPressed = 0;
        model.mouseXNow = (int) getWidth();
        model.mouseYNow = (int) getHeight();
        repaintCanvas();
    }

    /**
     * Prepares the Window for the User.
     */
    public void prepareForCapture() {
        show();
        repaintCanvas();
        Main.stage.close();
        settingsWindowController.close();
        if (settingsWindowController.getMarryTTSToggle().isSelected())
            Main.textToSpeech.speak("Select an area of the screen dragging your mouse and then press Enter or Space");
    }

    /**
     * Return an array witch contains the (UPPER_LEFT) Point2D of the rectangle
     * and the width and height of the rectangle.
     *
     * @return An array witch contains the (UPPER_LEFT) Point2D of the
     *         rectangle
     *         and the width and height of the rectangle
     */
    public int[] getRectangleBounds() {

        return new int[]{ model.rectUpperLeftX , model.rectUpperLeftY , model.rectWidth , model.rectHeight };

    }

    /**
     * The work of the Service is to capture the Image based on the rectangle
     * that user drawn of the Screen.
     *
     * @author GOXR3PLUS
     */
    public class CaptureService extends Service<Boolean> {

        /** The file path. */
        String filePath;

        /** The image. */
        BufferedImage image;

        /**
         * Constructor.
         */
        public CaptureService() {

            setOnSucceeded(s -> done());

            setOnCancelled(c -> done());

            setOnFailed(f -> done());

        }

        /**
         * Starts the Service.
         *
         * @param image2 The image to be saved.
         */
        public void startService(BufferedImage image2) {
            if (!isRunning()) {

                this.image = image2;

                // Show the SaveDialog
                fileSaver.get().setInitialFileName("ScreenShot" + model.random.nextInt(50000));
                File file = fileSaver.get().showSaveDialog(CaptureWindowController.this);
                if (file != null) {
                    filePath = file.getAbsolutePath();
                    reset();
                    start();
                } else
                    repaintCanvas();
            }
        }

        /**
         * Service has been done.
         */
        private void done() {

            Main.stage.show();
            close();

            if (getValue()) // successful?
                Notifications.create().title("Successfull Capturing").text("Image is being saved at:\n" + filePath)
                        .showInformation();
            else
                Notifications.create().title("Error").text("Failed to capture the Screen!").showError();
        }

        /* (non-Javadoc)
         * @see javafx.concurrent.Service#createTask() */
        @Override
        protected Task<Boolean> createTask() {
            return new Task<Boolean>() {
                @Override
                protected Boolean call() throws Exception {

                    boolean written = false;

                    // Try to write the file to the disc
                    try {
                        written = ImageIO.write(image, fileSaver.get().getSelectedExtensionFilter().getDescription(),
                                new File(filePath));
                    } catch (IOException ex) {
                        Logger.getLogger(getClass().getName()).log(Level.WARNING, null, ex);
                        return written;
                    }

                    return written;
                }

            };
        }

    }

}