Nazim
Nazim

Reputation: 219

How to take snapshot of selected area of screen in javafx?

I am trying to take screeshots of any file open currently on screen. After google all i got is to take screenshot of scene only in javafx. I don't want to use any AWT or Swing component. So is there any way ?

Upvotes: 4

Views: 8237

Answers (2)

owengall
owengall

Reputation: 463

Currently javafx.scene.robot.Robot is available, which can take screen captures. I don’t know if it was when the question was originally asked. The method is:

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

The optional rectangle specifies the region of the screen to capture. If not supplied, the whole screen is included. imgReturn can be assigned the resulting writable image. imgOut is an writable image output parameter that can also store the result, if you’ve defined it previously and it’s the correct dimensions. Otherwise, leave it null.

The method must be run on the JavaFX Application thread (you can use Platform.runLater() to ensure this if it’s invoked from another thread).

If you’re looking to take a screenshot of a specific application window, you could analyze the capture of the whole screen and look for the region containing the window you’re looking for.

If you know the window coordinates and dimensions, you can plug that in for the second argument in getScreenCapture.

You can also use the semitransparent overlay stage method from @GOXR3PLUS in which the user can define a rectangle (by clicking and dragging to define upper-left and lower-right corners, for example). Then you can hide the overlay stage and take a screenshot of the region within that rectangle.

Upvotes: 6

GOXR3PLUS
GOXR3PLUS

Reputation: 7255

This is the main mechanism I have used: A transparent Stage with Transparent Canvas which has a BorderPane with Opacity 0.1

Here is the simple example (it is just for selecting areas...):

WHEN YOU START THE APP THE ONLY WAY TO CLOSE IT IS USING ESCAPE

enter image description here


Tester class:

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

Capture Window class:

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

Here is a full advanced example.It is part of a GitHub Project Here . You can clone the project and modify on your needs.

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

            };
        }

    }

}

Upvotes: 1

Related Questions