2015-11-01 45 views
1

我需要使用Canvas场景创建JavaFX 8 Paint程序,但问题是当我在Canvas中拖动鼠标时尝试创建正方形或圆形时,我将其擦除与gcs[fig].clearRect(startX, startY, bufferX, bufferY);使用缓冲区的最后一个数字,但这删除了数字,是波纹管。我不想那样,它必须像windows Paint一样。也许一层可以帮助我,但我不知道该怎么做。JavaFX:使用Canvas绘制程序

我使用GraphicsContext的数组在图的每个位置绘制图形。

我使用NetBeans IDE

的JavaFX应用FXML

MicroPaint.java

package micropaint; 

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


public class MicroPaint 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); 
} 

} 

FXMLDocument.fxml

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

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.canvas.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="micropaint.FXMLDocumentController"> 
    <children> 
     <ToolBar orientation="VERTICAL" prefHeight="453.0" prefWidth="107.0"> 
     <items> 
      <Button fx:id="rectButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setRectangleAsCurrentShape" text="Rectangulo" /> 
      <Button fx:id="lineButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setLineAsCurrentShape" text="Linea" /> 
      <Button fx:id="ovlButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setOvalAsCurrentShape" text="Ovalo" /> 
      <Button fx:id="pencButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setFreeDesign" text="Lapiz" /> 
      <MenuButton mnemonicParsing="false" prefWidth="78.0" text="Borrador"> 
       <items> 
       <MenuItem fx:id="eraser" mnemonicParsing="false" onAction="#setErase" text="Borrador" /> 
       <MenuItem fx:id="clean" mnemonicParsing="false" onAction="#clearCanvas" text="Limpiar" /> 
       </items> 
      </MenuButton> 
      <ColorPicker fx:id="colorPick" prefHeight="25.0" prefWidth="78.0" /> 
      <RadioButton fx:id="strokeRB" mnemonicParsing="false" selected="true" text="Stroke"> 
       <toggleGroup> 
        <ToggleGroup fx:id="shapes" /> 
       </toggleGroup> 
      </RadioButton> 
      <RadioButton fx:id="fillRB" mnemonicParsing="false" text="Fill" toggleGroup="$shapes" /> 
      <Slider fx:id="sliderSize" prefHeight="14.0" prefWidth="38.0" />   
     </items> 
     </ToolBar> 
     <Canvas fx:id="TheCanvas" height="453.0" layoutX="107.0" onMouseDragged="#onMouseDraggedListener" onMouseExited="#onMouseExitedListener" onMousePressed="#onMousePressedListener" onMouseReleased="#onMouseReleaseListener" width="512.0" />   
    </children> 
</AnchorPane> 

FXMLDocumentController.java

package micropaint; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Button; 
import javafx.scene.control.ColorPicker; 
import javafx.scene.control.MenuItem; 
import javafx.scene.control.RadioButton; 
import javafx.scene.control.Slider; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 

public class FXMLDocumentController implements Initializable { 

    private GraphicsContext[] gcs; 
    private GraphicsContext gc; 
    private int fig=0; 
    private boolean drawline = false,drawoval = false,drawrectangle = false,erase = false,freedesign = true; 
    double startX, startY, lastX,lastY, bufferX,bufferY; 
    double hg; 

    @FXML private RadioButton strokeRB,fillRB; 
    @FXML private Slider sliderSize; 
    @FXML private ColorPicker colorPick; 
    @FXML private Canvas TheCanvas; 
    @FXML private Button rectButton,lineButton,ovlButton,pencButton; 
    @FXML private MenuItem eraser; 



    @FXML 
    private void clearCanvas(ActionEvent e){ 
     gc.setFill(Color.WHITE); 
     gc.fillRect(0, 0, 515, 453); 
    } 

    //private int bufferFig=0; 

    @FXML 
    private void onMousePressedListener(MouseEvent e){ 

     sliderSize.setMin(0); 
     sliderSize.setMax(300); 
     this.hg = sliderSize.getValue(); 

     gcs[fig]=TheCanvas.getGraphicsContext2D(); 

     this.startX = e.getX(); 
     this.startY = e.getY(); 
     System.err.println("mousePressed at" + startX + ", "+ startY); 
     /*if(drawoval) 
      this.dibujaOValo(); 
     if(drawrectangle) 
      this.dibujaRect();*/ 
     bufferX = startX; 
     bufferY = startY; 
    } 

    @FXML 
    private void onMouseReleaseListener(MouseEvent e){ 
     //this.lastX = e.getX(); 
     //this.lastY = e.getY(); 
     //if(drawline) 
     // this.dibujarLinea(); 
     fig++; 

     System.err.println(fig); 
    } 

    @FXML 
    private void onMouseDraggedListener(MouseEvent e){ 
     this.lastX = e.getX() - startX; 
     this.lastY = e.getY() - startY; 

     if(drawoval) 
      this.dibujaOValo(); 
     if(drawrectangle) 
      this.dibujaRect(); 
    } 

    private void dibujaOValo(){ 
     gcs[fig].setFill(colorPick.getValue()); 
     gcs[fig].setStroke(colorPick.getValue()); 

     if(strokeRB.isSelected() == true){ 

      gcs[fig].strokeOval(startX, startY, lastX, lastY); 
     }else 
      gcs[fig].fillOval(startX, startY, lastX, lastY); 
    } 

    private void dibujaRect(){ 
     gcs[fig].setStroke(colorPick.getValue()); 
     gcs[fig].setFill(colorPick.getValue()); 

     if(strokeRB.isSelected() == true){ 
      gcs[fig].clearRect(startX, startY, bufferX, bufferY); 
      gcs[fig].strokeRect(startX, startY, lastX, lastY); 
     }else{ 
      gcs[fig].clearRect(startX, startY, bufferX, bufferY); 
      gcs[fig].fillRect(startX, startY, lastX, lastY); 
     } 
     System.err.println(fig); 
     bufferX = lastX; 
     bufferY = lastY; 
    } 

    private void dibujarLinea(){ 
     gcs[fig].setFill(colorPick.getValue()); 
     gcs[fig].setStroke(colorPick.getValue()); 
     gcs[fig].setLineWidth(5); 
     gcs[fig].strokeLine(startX, startY, lastX, lastY); 
    } 

    @FXML 
    private void onMouseExitedListener(MouseEvent event){ 
     System.out.println("No puedes dibujar fuera del canvas"); 
    } 

    @FXML 
    private void setOvalAsCurrentShape(ActionEvent e){ 
     drawline = false; 
     drawoval = true; 
     drawrectangle = false; 
     freedesign = false; 
     erase = false; 

    } 

    @FXML 
    private void setLineAsCurrentShape(ActionEvent e){ 
     drawline = true; 
     drawoval = false; 
     drawrectangle = false; 
     freedesign = false; 
     erase = false; 
    } 
    @FXML 
    private void setRectangleAsCurrentShape(ActionEvent e){ 
     drawline = false; 
     drawoval = false; 
     freedesign = false; 
     erase=false; 
     drawrectangle = true; 
    } 

    @FXML 
    private void setErase(ActionEvent e){ 
     drawline = false; 
     drawoval = false; 
     drawrectangle = false;  
     erase = true; 
     freedesign= false; 
    } 

    @FXML 
    private void setFreeDesign(ActionEvent e){ 
     drawline = false; 
     drawoval = false; 
     drawrectangle = false;  
     erase = false; 
     freedesign = true; 
    } 



    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     gcs = new GraphicsContext[100]; 
     gc = TheCanvas.getGraphicsContext2D(); 
     gc.fillRect(100, 100, 100, 100); 

     ////////////////////////////////// 
     Image imageRect = new Image(getClass().getResourceAsStream("Stop-32.png")); 
     ImageView icR = new ImageView(imageRect); 
     icR.setFitWidth(32); 
     icR.setFitHeight(32); 
     rectButton.setGraphic(icR); 

     Image imageLinea = new Image(getClass().getResourceAsStream("Ruler-32.png")); 
     ImageView icLin = new ImageView(imageLinea); 
     icLin.setFitWidth(32); 
     icLin.setFitHeight(32); 
     lineButton.setGraphic(icLin); 

     Image imageOvalo = new Image(getClass().getResourceAsStream("Chart-32.png")); 
     ImageView icOval = new ImageView(imageOvalo); 
     icOval.setFitWidth(32); 
     icOval.setFitHeight(32); 
     ovlButton.setGraphic(icOval); 

     Image imageLapiz = new Image(getClass().getResourceAsStream("Pencil-32.png")); 
     ImageView icLapiz = new ImageView(imageLapiz); 
     icLapiz.setFitWidth(32); 
     icLapiz.setFitHeight(32); 
     pencButton.setGraphic(icLapiz); 
    }  

} 
+0

什么是'GraphicsContext'应该做的数组?就我所知,数组的所有元素都指向同一个对象。 –

+0

它应该是一层!但不起作用,因为你说的是​​指同一个对象。我想我可以恢复我在那里创建的数字,但不知道,一些想法? –

+0

你几乎已经将它与层的想法。我没有在javafx-8上更新,所以无法回答。在拖动开始时创建一个图像作为画布的副本,只需绘制图像即可清除画布而不是清除。这实际上给你你想要的。拖动结束时,只需绘制结果并转储图像。顺便说一句,如果你有这个图像,你可以使用它作为撤消,如果你保留它 – Blindman67

回答

2

涂料使用JavaFX 8 - JavaFXML帆布

这里我做了什么

MicroPaint.java

package micropaint; 

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


public class MicroPaint 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); 
    } 

} 

FXMLDocument.fxml

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

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.canvas.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="453.0" prefWidth="652.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="micropaint.FXMLDocumentController"> 
    <children> 
     <ToolBar orientation="VERTICAL" prefHeight="453.0" prefWidth="107.0"> 
     <items> 
      <Button fx:id="rectButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setRectangleAsCurrentShape" text="Rectangulo" /> 
      <Button fx:id="lineButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setLineAsCurrentShape" text="Linea" /> 
      <Button fx:id="ovlButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setOvalAsCurrentShape" text="Ovalo" /> 
      <Button fx:id="pencButton" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#setFreeDesign" text="Lapiz" /> 
      <MenuButton mnemonicParsing="false" prefWidth="78.0" text="Borrador"> 
       <items> 
       <MenuItem fx:id="eraser" mnemonicParsing="false" onAction="#setErase" text="Borrador" /> 
       <MenuItem fx:id="clean" mnemonicParsing="false" onAction="#clearCanvas" text="Limpiar" /> 
       </items> 
      </MenuButton> 
      <ColorPicker fx:id="colorPick" prefHeight="25.0" prefWidth="78.0" /> 
      <RadioButton fx:id="strokeRB" mnemonicParsing="false" selected="true" text="Stroke"> 
       <toggleGroup> 
        <ToggleGroup fx:id="shapes" /> 
       </toggleGroup> 
      </RadioButton> 
      <RadioButton fx:id="fillRB" mnemonicParsing="false" text="Fill" toggleGroup="$shapes" /> 
      <Slider fx:id="sizeSlider" prefHeight="14.0" prefWidth="59.0" />   
     </items> 
     </ToolBar> 
     <Canvas fx:id="TheCanvas" height="453.0" layoutX="107.0" width="546.0" /> 
     <Canvas fx:id="canvasGo" height="453.0" layoutX="107.0" onMouseDragged="#onMouseDraggedListener" onMouseExited="#onMouseExitedListener" onMousePressed="#onMousePressedListener" onMouseReleased="#onMouseReleaseListener" width="546.0" />   
    </children> 
</AnchorPane> 

FXMLDocumentController.java

package micropaint; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Button; 
import javafx.scene.control.ColorPicker; 
import javafx.scene.control.RadioButton; 
import javafx.scene.control.Slider; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.MouseEvent; 

/** 
* 
* @author CarlosA. 
*/ 
public class FXMLDocumentController implements Initializable { 
    //>>>>>>>>>>>>>>>>>>>>>>>Other variables<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    private GraphicsContext gcB,gcF; 
    private boolean drawline = false,drawoval = false,drawrectangle = false,erase = false,freedesign = true; 
    double startX, startY, lastX,lastY,oldX,oldY; 
    double hg; 
    //>>>>>>>>>>>>>>>>>>>>>>>FXML Variables<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    @FXML private RadioButton strokeRB,fillRB; 
    @FXML private ColorPicker colorPick; 
    @FXML private Canvas TheCanvas,canvasGo; 
    @FXML private Button rectButton,lineButton,ovlButton,pencButton; 
    @FXML private Slider sizeSlider; 
    ////////////////////////////////////////////////////////////////////////////// 


    @FXML 
    private void onMousePressedListener(MouseEvent e){ 
     this.startX = e.getX(); 
     this.startY = e.getY(); 
     this.oldX = e.getX(); 
     this.oldY = e.getY(); 
    } 

    @FXML 
    private void onMouseDraggedListener(MouseEvent e){ 
     this.lastX = e.getX(); 
     this.lastY = e.getY(); 

     if(drawrectangle) 
      drawRectEffect(); 
     if(drawoval) 
      drawOvalEffect(); 
     if(drawline) 
      drawLineEffect(); 
     if(freedesign) 
      freeDrawing(); 
    } 

    @FXML 
    private void onMouseReleaseListener(MouseEvent e){ 
     if(drawrectangle) 
      drawRect(); 
     if(drawoval) 
      drawOval(); 
     if(drawline) 
      drawLine(); 
    } 

    @FXML 
    private void onMouseExitedListener(MouseEvent event) 
    { 
     System.out.println("No puedes dibujar fuera del canvas"); 
    } 

    //>>>>>>>>>>>>>>>>>>>>>>>>>>>Draw methods<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

    private void drawOval() 
    { 
     double wh = lastX - startX; 
     double hg = lastY - startY; 
     gcB.setLineWidth(sizeSlider.getValue()); 

     if(fillRB.isSelected()){ 
      gcB.setFill(colorPick.getValue()); 
      gcB.fillOval(startX, startY, wh, hg); 
     }else{ 
      gcB.setStroke(colorPick.getValue()); 
      gcB.strokeOval(startX, startY, wh, hg); 
     } 
    } 

    private void drawRect() 
    { 
     double wh = lastX - startX; 
     double hg = lastY - startY; 
     gcB.setLineWidth(sizeSlider.getValue()); 

     if(fillRB.isSelected()){ 
      gcB.setFill(colorPick.getValue()); 
      gcB.fillRect(startX, startY, wh, hg); 
     }else{ 
      gcB.setStroke(colorPick.getValue()); 
      gcB.strokeRect(startX, startY, wh, hg); 
     } 
    } 

    private void drawLine() 
    { 
     gcB.setLineWidth(sizeSlider.getValue()); 
     gcB.setStroke(colorPick.getValue()); 
     gcB.strokeLine(startX, startY, lastX, lastY); 
    } 

    private void freeDrawing() 
    { 
     gcB.setLineWidth(sizeSlider.getValue()); 
     gcB.setStroke(colorPick.getValue()); 
     gcB.strokeLine(oldX, oldY, lastX, lastY); 
     oldX = lastX; 
     oldY = lastY; 
    } 

    ////////////////////////////////////////////////////////////////////// 
    //>>>>>>>>>>>>>>>>>>>>>>>>>>Draw effects methods<<<<<<<<<<<<<<<<<<<<<<< 

    private void drawOvalEffect() 
    { 
     double wh = lastX - startX; 
     double hg = lastY - startY; 
     gcF.setLineWidth(sizeSlider.getValue()); 

     if(fillRB.isSelected()){ 
      gcF.clearRect(0, 0, canvasGo.getWidth(), canvasGo.getHeight()); 
      gcF.setFill(colorPick.getValue()); 
      gcF.fillOval(startX, startY, wh, hg); 
     }else{ 
      gcF.clearRect(0, 0, canvasGo.getWidth(), canvasGo.getHeight()); 
      gcF.setStroke(colorPick.getValue()); 
      gcF.strokeOval(startX, startY, wh, hg); 
     } 
     } 

    private void drawRectEffect() 
    { 
     double wh = lastX - startX; 
     double hg = lastY - startY; 
     gcF.setLineWidth(sizeSlider.getValue()); 

     if(fillRB.isSelected()){ 
      gcF.clearRect(0, 0, canvasGo.getWidth(), canvasGo.getHeight()); 
      gcF.setFill(colorPick.getValue()); 
      gcF.fillRect(startX, startY, wh, hg); 
     }else{ 
      gcF.clearRect(0, 0, canvasGo.getWidth(), canvasGo.getHeight()); 
      gcF.setStroke(colorPick.getValue()); 
      gcF.strokeRect(startX, startY, wh, hg); 
     } 
    } 

    private void drawLineEffect() 
    { 
     gcF.setLineWidth(sizeSlider.getValue()); 
     gcF.setStroke(colorPick.getValue()); 
     gcF.clearRect(0, 0, canvasGo.getWidth() , canvasGo.getHeight()); 
     gcF.strokeLine(startX, startY, lastX, lastY); 
    } 
    /////////////////////////////////////////////////////////////////////// 

    @FXML 
    private void clearCanvas(ActionEvent e) 
    { 
     gcB.clearRect(0, 0, TheCanvas.getWidth(), TheCanvas.getHeight()); 
     gcF.clearRect(0, 0, TheCanvas.getWidth(), TheCanvas.getHeight()); 
    } 


    //>>>>>>>>>>>>>>>>>>>>>Buttons control<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    @FXML 
    private void setOvalAsCurrentShape(ActionEvent e) 
    { 
     drawline = false; 
     drawoval = true; 
     drawrectangle = false; 
     freedesign = false; 
     erase = false; 
    } 

    @FXML 
    private void setLineAsCurrentShape(ActionEvent e) 
    { 
     drawline = true; 
     drawoval = false; 
     drawrectangle = false; 
     freedesign = false; 
     erase = false; 
    } 
    @FXML 
    private void setRectangleAsCurrentShape(ActionEvent e) 
    { 
     drawline = false; 
     drawoval = false; 
     freedesign = false; 
     erase=false; 
     drawrectangle = true; 
    } 

    @FXML 
    private void setErase(ActionEvent e) 
    { 
     drawline = false; 
     drawoval = false; 
     drawrectangle = false;  
     erase = true; 
     freedesign= false; 
    } 

    @FXML 
    private void setFreeDesign(ActionEvent e) 
    { 
     drawline = false; 
     drawoval = false; 
     drawrectangle = false;  
     erase = false; 
     freedesign = true; 
    } 

    ////////////////////////////////////////////////////////////////// 


    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     gcB = TheCanvas.getGraphicsContext2D(); 
     gcF = canvasGo.getGraphicsContext2D(); 

     sizeSlider.setMin(1); 
     sizeSlider.setMax(50); 

     ////////////////////////////////// 
     Image imageRect = new Image(getClass().getResourceAsStream("Stop-32.png")); 
     ImageView icR = new ImageView(imageRect); 
     icR.setFitWidth(32); 
     icR.setFitHeight(32); 
     rectButton.setGraphic(icR); 

     Image imageLinea = new Image(getClass().getResourceAsStream("Ruler-32.png")); 
     ImageView icLin = new ImageView(imageLinea); 
     icLin.setFitWidth(32); 
     icLin.setFitHeight(32); 
     lineButton.setGraphic(icLin); 

     Image imageOvalo = new Image(getClass().getResourceAsStream("Chart-32.png")); 
     ImageView icOval = new ImageView(imageOvalo); 
     icOval.setFitWidth(32); 
     icOval.setFitHeight(32); 
     ovlButton.setGraphic(icOval); 

     Image imageLapiz = new Image(getClass().getResourceAsStream("Pencil-32.png")); 
     ImageView icLapiz = new ImageView(imageLapiz); 
     icLapiz.setFitWidth(32); 
     icLapiz.setFitHeight(32); 
     pencButton.setGraphic(icLapiz); 
    }  

} 

我用两个帆布FXML文件中,所以我用一个效果等进行最后数字。 橡皮擦不起作用,你可以改进它