/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package us.guihouse.projector.projection;

import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;


/**
 *
 * @author guilherme
 */
public class PreviewImageView extends ImageView implements Runnable {
    private final CanvasDelegate delegate;
    private ProjectionCanvas projectionCanvas;

    private BufferedImage targetRender;
    private Graphics2D targetGraphics;
    private WritableImage fxTargetRender;
    private final Object sync = new Object();

    private boolean repainting = false;
    private boolean running = false;
    private Thread updateThread = null;

    public PreviewImageView(CanvasDelegate delegate) {
        this.delegate = delegate;
        setPreserveRatio(true);
    }

    private void updateTargetRenderIfNeeded() {
        int width = delegate.getWidth();
        int height = delegate.getHeight();

        if (targetRender == null || targetRender.getWidth() != width || targetRender.getHeight() != height) {
            if (targetGraphics != null) {
                targetGraphics.dispose();
            }

            targetRender = delegate.getDefaultDevice().getDefaultConfiguration().createCompatibleImage(width, height);
            targetGraphics = targetRender.createGraphics();

            fxTargetRender = new WritableImage(width, height);
        }
    }

    void setProjectionCanvas(ProjectionCanvas projectionCanvas) {
        this.projectionCanvas = projectionCanvas;

        if (projectionCanvas == null) {
            running = false;
            if (updateThread != null) {
                try {
                    updateThread.join();
                    updateThread = null;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            if (updateThread == null) {
                running = true;
                updateThread = new Thread(this);
                updateThread.start();
            }
        }
    }

    @Override
    public void run() {
        while (running) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                running = false;
                e.printStackTrace();
            }

            if (repainting) {
                continue;
            }

            repainting = true;

            updateTargetRenderIfNeeded();

            int width = targetRender.getWidth();
            int height = targetRender.getHeight();

            targetGraphics.setColor(Color.BLACK);
            targetGraphics.fillRect(0, 0, width, height);

            if (projectionCanvas != null) {
                int dw = delegate.getWidth();
                int dh = delegate.getHeight();

                double scaleX = width / (double) dw;
                double scaleY = height / (double) dh;
                double scale = Math.min(scaleX, scaleY);

                int pw = (int) Math.round(dw * scale);
                int ph = (int) Math.round(dh * scale);
                int px = (width - pw) / 2;
                int py = (height - ph) / 2;

                AffineTransform old = targetGraphics.getTransform();
                targetGraphics.translate(px, py);
                targetGraphics.scale(scale, scale);
                projectionCanvas.paintComponent(targetGraphics);
                targetGraphics.setTransform(old);

                SwingFXUtils.toFXImage(targetRender, fxTargetRender);

                Platform.runLater(() -> {
                    setImage(fxTargetRender);
                    repainting = false;
                });
            }
        }
    }
}

@@ -1974,49 +1974,8 @@
 ();%0A
-                    updateThread = null;%0A
     
@@ -2096,43 +2096,12 @@
     
-%7D%0A
     
-    %7D else %7B%0A            if (
 upda
@@ -2110,30 +2110,54 @@
 Thread =
-=
  null
-) %7B%0A    
+;%0A            %7D%0A        %7D else %7B%0A
         
@@ -2172,32 +2172,60 @@
 ing = true;%0A    
+        repainting = false;%0A
             upda
@@ -2257,36 +2257,32 @@
 s);%0A            
-    
 updateThread.sta
@@ -2287,30 +2287,16 @@
 tart();%0A
-            %7D%0A
         

Fix preview