javafx - How to detect mouse movement over node while button is pressed? -


problem

you can add event listener node detects mouse movement on it. doesn't work if mouse button pressed before moved on node.

question

does know how detect mouse movement while button pressed? far i've found solution using mouse_dragged event , instead of using getsource() using getpickresult() , evaluating pickresult data.

here's code including uluk's solution. old , new solution switchable via usenewversion (uluk's version) boolean:

import javafx.application.application; import javafx.event.eventhandler; import javafx.scene.node; import javafx.scene.scene; import javafx.scene.control.label; import javafx.scene.input.mouseevent; import javafx.scene.input.pickresult; import javafx.scene.layout.borderpane; import javafx.scene.layout.pane; import javafx.scene.layout.stackpane; import javafx.stage.stage;  public class main extends application {      boolean usenewversion= true;      int rows = 10;     int columns = 20;     double width = 1024;     double height = 768;      @override     public void start(stage primarystage) {         try {             borderpane root = new borderpane();              // create grid             grid grid = new grid( columns, rows, width, height);              mousegestures mg = new mousegestures();              // fill grid             (int row = 0; row < rows; row++) {                 (int column = 0; column < columns; column++) {                      cell cell = new cell(column, row);                      mg.makepaintable(cell);                      grid.add(cell, column, row);                 }             }              root.setcenter(grid);              // create scene , stage             scene scene = new scene(root, width, height);             scene.getstylesheets().add(getclass().getresource("application.css").toexternalform());             primarystage.setscene(scene);             primarystage.show();            } catch (exception e) {             e.printstacktrace();         }     }      public static void main(string[] args) {         launch(args);     }      private class grid extends pane {          int rows;         int columns;          double width;         double height;          cell[][] cells;          public grid( int columns, int rows, double width, double height) {              this.columns = columns;             this.rows = rows;             this.width = width;             this.height = height;              cells = new cell[rows][columns];          }          /**          * add cell array , ui.          */         public void add(cell cell, int column, int row) {              cells[row][column] = cell;              double w = width / columns;             double h = height / rows;             double x = w * column;             double y = h * row;              cell.setlayoutx(x);             cell.setlayouty(y);             cell.setprefwidth(w);             cell.setprefheight(h);              getchildren().add(cell);          }      }      private class cell extends stackpane {          int column;         int row;          public cell(int column, int row) {              this.column = column;             this.row = row;              getstyleclass().add("cell");              label label = new label(this.tostring());              getchildren().add(label);         }          public void highlight() {             getstyleclass().add("cell-highlight");         }          public void unhighlight() {             getstyleclass().remove("cell-highlight");         }          public string tostring() {             return this.column + "/" + this.row;         }     }      public class mousegestures {          public void makepaintable( node node) {              if( usenewversion) {                  node.setonmousepressed( onmousepressedeventhandler);                 node.setondragdetected( ondragdetectedeventhandler);                 node.setonmousedragentered( onmousedragenteredeventhandler);              } else {                  node.setonmousepressed( onmousepressedeventhandler);                 node.setonmousedragged( onmousedraggedeventhandler);                 node.setonmousereleased( onmousereleasedeventhandler);              }          }          /* old version */          eventhandler<mouseevent> onmousepressedeventhandler = event -> {              cell cell = (cell) event.getsource();              if( event.isprimarybuttondown()) {                 cell.highlight();             } else if( event.issecondarybuttondown()) {                 cell.unhighlight();             }         };          eventhandler<mouseevent> onmousedraggedeventhandler = event -> {              pickresult pickresult = event.getpickresult();             node node = pickresult.getintersectednode();              if( node instanceof cell) {                  cell cell = (cell) node;                  if( event.isprimarybuttondown()) {                     cell.highlight();                 } else if( event.issecondarybuttondown()) {                     cell.unhighlight();                 }                     }          };          eventhandler<mouseevent> onmousereleasedeventhandler = event -> {         };          eventhandler<mouseevent> ondragdetectedeventhandler = event -> {              cell cell = (cell) event.getsource();             cell.startfulldrag();          };          eventhandler<mouseevent> onmousedragenteredeventhandler = event -> {              cell cell = (cell) event.getsource();              if( event.isprimarybuttondown()) {                 cell.highlight();             } else if( event.issecondarybuttondown()) {                 cell.unhighlight();             }                 };      }  } 

in end should able paint via primary mouse button , erase paint via secondary mouse button:

enter image description here

the (source) node handles initial drag_detected event should invoke sourcenode.startfulldrag(), target node able handle 1 of mousedragevents, instance mouse_drag_over or mouse_drag_entered event respective targetnode.seton<mousedragevent>() method.


Comments