2017-12-22 57 views
0

私はペイントプログラムを作成していますが、ユーザが作成した図面の周囲にはDropShadowがあります。また、消去すると、DropShadowも消去されます。 DropShadow(図面の新しい境界線を囲むように)を再適用しようとすると機能しますが、残りの部分はすでに適用されていますが、望ましくない部分が暗くなっています(DropShadow)。JavaFXキャンバス上に別のレイヤーとしてDropShadowを適用します。

私は考えることができるソリューションが2つある:

  1. DropShadow効果を削除し、すべての消去にそれを再適用します。私が知る限り、これは使用できません。GraphicsContext.applyEffect()
  2. DropShadowを別のキャンバスに適用して消去し、すべての消去時に再描画します。以下のコードは、この解決策で私の恥ずかしい試みを実装しています。

    FXMLDocumentController.javaここenter image description here

    が私のコードである

    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> 
    

    :ここ

は現在、何が起こるかの写真です

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

} 

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

} 

答えて

1

みんながシーングラフは、タスクのためにはるかに優れて適しているだろうというときのキャンバスを使用しているように見える理由を私は理解していません。なぜ普通のペインとパスだけを使ってみませんか?ドロップシャドウ効果をパスに直接適用することができます。シーングラフの利点は、すべての要素を必要なだけ個別に編集できることです。一方、キャンバスは基本的に概念的には一度描かれた画像を編集することはできません。

+0

あなたがgoogleで「javafxで描く」ときはすべての結果がキャンバスを使っていますが、私はそれを調べて、シーングラフを使ってみるとうまくいくようです。 'clearRect()'と似た振る舞いを持つ消しゴムをどのように置くことができるか知っていますか? – KingDan

+0

このチュートリアルをご覧ください:http://blog.ngopal.com.np/2011/06/18/shapes-intersection-subtract-and-union-in-javafx-2-0/消しゴムについては、シェイプの減算法を用いることができる。 – mipa

関連する問題