我正在制作一个绘画程序,但是用户制作的图纸周围有一个DropShadow。当它们擦除时,它也会同时擦除DropShadow。如果我尝试重新应用DropShadow(使它包围图形的新边界),它会起作用,但是会使得已经应用的DropShadow其余部分变暗,这是我所不希望的。

我能想到的解决方案有两个:


删除DropShadow效果,并在每次擦除时重新应用。据我所知,使用GraphicsContext.applyEffect()时这是不可能的
在单独的画布上应用DropShadow并清除它,并在每次擦除时重画。下面的代码实现了我对此解决方案的尴尬尝试。


这是当前情况的图片:
java - 将DropShadow用作JavaFX canvas上的单独层-LMLPHP

这是我的代码

FXMLDocument.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>

<AnchorPane id="AnchorPane" prefHeight="399.0" prefWidth="465.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cartographerfx.FXMLDocumentController">
    <children>
      <Pane fx:id="canvasPane" layoutX="26.0" layoutY="20.0" prefHeight="362.0" prefWidth="417.0" style="-fx-border-style: solid;">
         <children>
            <Canvas fx:id="canvas" height="362.0" onMouseDragged="#CanvasMouseDragged" onMousePressed="#CanvasMouseDown" onMouseReleased="#CanvasMouseUp" width="417.0" />
         </children>
      </Pane>
    </children>
</AnchorPane>


FXMLDocumentController.java

package cartographerfx;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

/**
 *
 * @author Dan
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    Canvas canvas;
    Canvas shadowLayer;

    @FXML
    Pane canvasPane;

    private GraphicsContext gc;
    private GraphicsContext sgc;
    private boolean isDragging;
    private double lastX;
    private double lastY;

    @FXML
    public void CanvasMouseDragged(MouseEvent event) {

        if (isDragging) {
            if (event.getButton() == MouseButton.PRIMARY) {

                gc.setStroke(Color.BLUE);

                gc.setLineWidth(10);
                gc.strokeLine(lastX, lastY, event.getX(), event.getY());
            } else if (event.getButton() == MouseButton.SECONDARY) {
                gc.clearRect(event.getX(), event.getY(), 10, 10);
            }

            lastX = event.getX();
            lastY = event.getY();
        }


    }

    @FXML
    public void CanvasMouseDown(MouseEvent event) {
        isDragging = true;

        lastX = event.getX();
        lastY = event.getY();

        if (event.getButton() == MouseButton.MIDDLE)
        {
            sgc = gc;
            sgc.applyEffect(new DropShadow());

        }
    }

    @FXML
    public void CanvasMouseUp(MouseEvent event) {
        isDragging = false;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {

        gc = canvas.getGraphicsContext2D();
        isDragging = false;

        shadowLayer = new Canvas(canvas.getWidth(), canvas.getHeight());

        sgc = shadowLayer.getGraphicsContext2D();
        canvasPane.getChildren().add(shadowLayer);
        shadowLayer.toBack();
    }

}


制图师FX.java

package cartographerfx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author Dan
 */
public class CartographerFX extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

最佳答案

我不明白为什么场景图会更适合该任务时,为什么每个人似乎都在使用Canvas。您为什么不只使用普通的窗格和路径。然后,您可以将阴影效果直接应用于路径。场景图的优点是您可以根据需要单独编辑每个元素,而画布在概念上基本上只是一张图像,绘制后根本无法编辑。

关于java - 将DropShadow用作JavaFX canvas上的单独层,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47934981/

10-10 10:08