不接收子节点JavaFX上的鼠标按下事件

时间:2018-08-09 14:09:51

标签: javafx javafx-8

我要在与图片相同的两个imageview之间绘制路径

picture.

此路径从其中一个鼠标单击图像视图开始,通过鼠标单击继续并在窗格上移动事件,并且必须通过鼠标单击在另一个图像视图中结束。这是在第一次按下鼠标未收到任何鼠标按键后的问题如果在imageviews上发生事件,则该事件仅在窗格上接收,因为该画线没有停止。我的代码有什么问题?

这是我的控制器代码:

public class DrawLine {
    @FXML
    ImageView imageView1 ;
    @FXML
    ImageView imageView2 ;
    @FXML
    AnchorPane pane ;
    private  Line currentLine ;
    private  String state ;
    private DoubleProperty mouseX = new SimpleDoubleProperty();
    private DoubleProperty mouseY = new SimpleDoubleProperty();

    @FXML
    private  void initialize(){
        state = "dfkl" ;
        imageView1.setPreserveRatio( false);
        imageView2.setPreserveRatio( false);
        imageView1.setOnMousePressed( event -> {
            imageMousePress( event);
        });
        imageView2.setOnMousePressed( event -> {
            imageMousePress( event);
        });
        pane.setOnMousePressed( event ->  {
            paneMousePress( event) ;
        });
        imageView2.setPickOnBounds(false);
        imageView1.setPickOnBounds(false);
        pane.setOnMouseMoved( event -> {
            paneMouseMove( event);
        });

    }


    public  void paneMouseMove( MouseEvent e) {
        if( this.state.equals("DRAWLINE") && this.currentLine != null) {
            makeLine( e);
        }
    }
    public void paneMousePress( MouseEvent e) {
        if( this.state.equals("DRAWLINE") && this.currentLine != null) {
            endLine(e);
            startLine(e);
        }
    }
    private  void  startLine( MouseEvent e ){
        currentLine = new Line();
        currentLine.setStyle( "-fx-stroke: #a86a6a ; -fx-stroke-width: 5");
        currentLine.setStartX( e.getSceneX());
        currentLine.setStartY(e.getSceneY());
        mouseX.set( e.getSceneX()) ;
        mouseY.set( e.getSceneY());
        currentLine.endXProperty().bind(mouseX);
        currentLine.endYProperty().bind(mouseY);
        pane.getChildren().add(currentLine);
    }
    private  void  endLine (  MouseEvent e){
        currentLine.endXProperty().unbind();
        currentLine.endYProperty().unbind();
        currentLine.setEndX(e.getX());
        currentLine.setEndY(e.getY());
        currentLine = null;
    }
    private  void makeLine( MouseEvent e){
        mouseX.set(e.getX());
        mouseY.set(e.getY());
    }

    private void imageMousePress( MouseEvent event){
        if( currentLine == null){
            startLine(event);
            state = "DRAWLINE" ;
        }else if( currentLine != null & state.equals("DRAWLINE")){
            endLine( event);
        }
    }
}

请帮助我。

1 个答案:

答案 0 :(得分:1)

在拖动直线的终点时,终点位于鼠标光标下方。这样,鼠标事件的目标是Line,而不是ImageView,并且由于没有Line消费它的事件的事件处理程序,因此事件被传递到Line的父级,即AnchorPane,而不是ImageView

要解决此问题,请将mouseTransparent的{​​{1}}属性设置为Line

true

此外,您还应该消耗private void startLine(MouseEvent e) { currentLine = new Line(); currentLine.setMouseTransparent(true); ... } 的事件,也不要触发ImageView的事件处理程序:

AnchorPane

还请注意,imageView1.setOnMousePressed(event -> { imageMousePress(event); event.consume(); }); imageView2.setOnMousePressed(event -> { imageMousePress(event); event.consume(); }); 的{​​{1}}和x属性是相对于添加处理程序的y的坐标系的。

MouseEvent

需要更改为

Node

此外,如果状态数量有限,我建议改用private void endLine(MouseEvent e) { currentLine.endXProperty().unbind(); currentLine.endYProperty().unbind(); currentLine.setEndX(e.getX()); currentLine.setEndY(e.getY()); currentLine = null; } ,因为这样可以得到拼写错误的编译时检查。为此目的使用字符串可能会意外添加错误,例如如果您不小心使用private void endLine(MouseEvent e) { currentLine.endXProperty().unbind(); currentLine.endYProperty().unbind(); currentLine = null; } 而不是enum,这可能很难发现。另外,可以使用"DRAWLlNE"比较枚举常量。

"DRAWLINE"