在两个重叠的节点上处理鼠标事件 - Javafx

时间:2013-12-05 15:44:59

标签: java canvas javafx mouseevent

我正在构建一个Java应用程序。这个应用程序作为一个类型的“油漆”应用程序,您可以选择一种颜色,并在画布上绘制。除了......我将在画布上分布一系列圆圈。我希望这些圆圈立即改变颜色,如果用户正在绘制并且鼠标位于圆的X(10)像素内(其中X是绘制的线的宽度除以2)。

在下面的图片示例中,用户开始使用RED绘图。这是红色触及圆圈的那一刻,我需要圆圈的填充才能变成红色 Painting Circles

这是我的代码。我有一个画布,是一个组的一部分。我还创建了一个圆形节点,并成为该组的一部分。我想我需要以某种方式创建一个鼠标事件,当用户在每个圆圈附近绘制时将触发该事件。我最终会在画布上有很多圈子,但我开始时只有1个用于测试目的。

package paintingcircles;

import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ColorPicker;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;


public class LayerController {

    private ColorPicker colorPicker;
    private Group root;
    private Group canvasGroup;
    private Canvas canvas1;
    private GraphicsContext gc1;


    // Reference to the main application
    private MainApp mainApp;

     /**
      * Is called by the main application to give a reference back to itself.
      * 
      * @param mainApp
      */
      public void setMainApp(MainApp mainApp) {
          this.mainApp = mainApp;

          //get data from main app if necessary
      }

    public void initialize(){

        createLayers();
        handleLayers();
        createCircles();

    }

    private void createLayers(){

        canvas1 = new Canvas(400, 400);

        // Obtain Graphics Context
        gc1 = canvas1.getGraphicsContext2D();
        initDraw(gc1);

        //create root group
        Group root = new Group();

        canvasGroup = new Group(); 
        canvasGroup.getChildren().add(canvas1);


        //add nodes to the root group
        VBox vBox = new VBox(); //lays out children in a vertical box
        vBox.getChildren().addAll(colorPicker, canvasGroup);
        root.getChildren().add(vBox);
        Scene scene = new Scene(root, 400, 425);
        mainApp.getPrimaryStage().setTitle("Painting Circles");
        mainApp.getPrimaryStage().setScene(scene);
        mainApp.getPrimaryStage().show();

    }

    private void initDraw(GraphicsContext gc){

        colorPicker = new ColorPicker();

        double canvasWidth = gc.getCanvas().getWidth();
        double canvasHeight = gc.getCanvas().getHeight();

        gc.setFill(Color.LIGHTGRAY);
        gc.setStroke(Color.BLACK);
        gc.setLineWidth(10);

        gc.fill();
        gc.strokeRect(
                0,              //x of the upper left corner
                0,              //y of the upper left corner
                canvasWidth,    //width of the rectangle
                canvasHeight);  //height of the rectangle

        gc.setFill(colorPicker.getValue());
        gc.setStroke(colorPicker.getValue());
        gc.setLineWidth(1);
    }

    private void handleLayers(){

           canvas1.addEventHandler(MouseEvent.MOUSE_PRESSED, 
                   new EventHandler<MouseEvent>(){

               @Override
               public void handle(MouseEvent event) {
                   gc1.beginPath();
                   gc1.setLineWidth(20);
                   gc1.moveTo(event.getX(), event.getY());
                   gc1.setStroke(colorPicker.getValue());
                   gc1.strokeRoundRect(event.getX(), event.getY(), 10, 10, 10, 10);
               }
           });

           canvas1.addEventHandler(MouseEvent.MOUSE_DRAGGED, 
                   new EventHandler<MouseEvent>(){

               @Override
               public void handle(MouseEvent event) {

                //TODO: Smooth out the mouse_dragged drawing
                gc1.lineTo(event.getX(), event.getY());
                   gc1.setLineWidth(20);
                   gc1.setStroke(colorPicker.getValue());
                   gc1.stroke();

               }
           });

           canvas1.addEventHandler(MouseEvent.MOUSE_RELEASED, 
                   new EventHandler<MouseEvent>(){

               @Override
               public void handle(MouseEvent event) {

               }
           });

       }

    private void createCircles(){

        Circle c = new Circle();
        c.setCenterX(100.0f);
        c.setCenterY(100.0f);
        c.setRadius(25);
        c.setStrokeWidth(5);
        c.setStroke(Color.BLUE);
        c.setFill(Color.TRANSPARENT);
        canvasGroup.getChildren().add(c);

            /*This is my attempt at creating a mouse event that will trigger when 
             *the user drags the mouse near the circle with the idea that it will
             *eventually color the circle. This didn't work...
             */
        c.addEventHandler(MouseEvent.ANY, new EventHandler<MouseEvent>(){

               @Override
               public void handle(MouseEvent event) {
                   gc1.setLineWidth(20);
                   gc1.setStroke(Color.GREEN);
                   gc1.strokeRoundRect(event.getX(), event.getY(), 10, 10, 10, 10);
               }

           });

    }

} 

1 个答案:

答案 0 :(得分:0)

我想我明白了......我需要在调用“startFullDrag()”之后捕获“Mouse_Drag_Over”事件。

canvas1.addEventHandler(MouseEvent.DRAG_DETECTED, 
           new EventHandler<MouseEvent>(){

       @Override
       public void handle(MouseEvent event) {
           canvas1.startFullDrag();       
       }
   });

c.addEventHandler(MouseDragEvent.MOUSE_DRAG_OVER, new EventHandler<MouseDragEvent>(){

       @Override
       public void handle(MouseDragEvent event) {
           c.setFill(colorPicker.getValue());   
       }
   });