2015-05-08 13 views
6

Bunun üzerine fare hareketi algılayan bir düğüme bir olay dinleyicisi ekleyebilirDüğmeye basıldığında düğüm üzerinde fare hareketi nasıl algılanır?

Sorun. Düğümün üzerine taşınmadan önce bir fare düğmesine basıldığında bu işe yaramaz.

Soru

kimse düğmesine basıldığı anda fare hareketi algılamak için biliyor mu? Şimdiye kadar sadece MOUSE_DRAGGED olayını kullanarak bir çözüm buldum ve getPickResult() kullanarak getSource() kullanmak ve PickResult verilerini değerlendirmek yerine.

İşte Uluk'un çözümünü içeren kod.

enter image description here: ikincil fare düğmesi ile boya birincil fare düğmesi ile boyamak ve silmek gerekir Sonunda

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 
      for (int row = 0; row < rows; row++) { 
       for (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 and 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 to array and to the 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(); 
      }  

     }; 

    } 

} 

: Eski ve yeni çözüm useNewVersion (uLuK versiyonu) boolean yoluyla değiştirilebilir olmak

+1

'Button' gelen' node' farklı mıdır? Ben tam olarak soruyu anlamadım. Basıldığında aynı düğmedeki fare hareketini okumaya mı çalışıyorsunuz? – ItachiUchiha

+3

İlk DRAG_DETECTED olayını işleyen düğüm, sourceNode.startFullDrag() yöntemini çağırmalıdır, ardından hedef düğüm, MOUSE_DRAG_OVER olaylarını targetNode.setOnMouseDragOver() yöntemiyle işleyebilir. –

+1

@ItachiUchia: Fare butonunu kastettim. Ben değiştirdim ve Uluk versiyonunu da ekledim. Dün yayınladığım A * algoritması için buna ihtiyacım vardı, böylece farklı fare duvarlarını basit fare sürükle ile boyamak (birincil düğme aşağıdayken). Çalıştı, ancak PickResult kullanarak garip hissettim. – Roland

cevap

2

ilk DRAG_DETECTED olayı işler (kaynak) düğüm, hedef düğüm mümkün örneği MOUSE_DRAG_OVER için MouseDragEvent s birini veya ilgili 012 MOUSE_DRAG_ENTERED olayı işlemek üzere olacak sourceNode.startFullDrag() çağırmakyöntemi.

6

Bir çözüm, kaynağa sourceNode.startFullDrag() öğesini etkinleştiren bir olay filtresi eklemektir. Bu, farenizi tuvalin dışına sürüklemeye başladığınız halde (uygulamanızda düğüm içermeyen herhangi bir alan istiyorsanız) çalışır.

Bunun gibi

:

scene.addEventFilter(MouseEvent.DRAG_DETECTED , new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent mouseEvent) { 
     scene.startFullDrag(); 
    } 
}); 

Ve sonra olabilir:

node.setOnMouseDragEntered(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent event) { 
     led.setOn(true); 
    } 
}); 
İlgili konular