如何限制JavaFx8多边形三角形的鼠标事件:只在三角形本身上触发,而不是在三角形布局的矩形边界上



我已经使用Polygon对象创建了一个三角形,以及允许在屏幕上拖动三角形的onMousePressed、Dragged、Released事件。在我创建的JavaFX应用程序(用于独立笔记本电脑(游戏中运行良好。

问题是,我希望三角鼠标事件只在三角形状边界内触发,而不是在三角之外。目前,事件似乎在多边形三角形不可见矩形布局边界(即嵌入/围绕三角形的不可见矩形(内的任何地方触发。此行为允许拖动三角形:1(光标位于三角形外侧&2( 光标在多边形三角形不可见矩形边界内的任意位置。

这种行为会让用户感到困惑:1(无意中拖动三角形,2(阻止其他游戏片段的事件(被不可见的三角形矩形边界重叠(,使其无法播放,直到三角形被拖到一边。

我已经使用Ellipse对象完成了MouseEvent对形状的限制&这个"setPickOnBounds(true(;"属性。与多边形对象的工作方式似乎不同。


我在stackOverflow.com上查看过,&我能找到的最接近解决这个问题的文章如下,它没有解决MouseEvent在Shapes内部/外部触发的问题

StackOverflow.com:1.如何平滑拖动JavaFX多边形?如何平滑拖动JavaFX多边形?文章未涉及形状可点击区域。

  1. Android自定义形状按钮Android自定义形状按钮是5岁&特定于Android,是否有一种更有效的方法使用javaFX8&多边形?此外,我的三角形尺寸是动态的,经过claculated以匹配嵌入的用户格式LabelText的大小。

    因此,要使用三角形图像文件,需要数百个三角形文件,才能获得最佳拟合选项

请帮助。。。谢谢Michael

我创建三角形的代码:

public static class StrategySelfNote_Element extends Group {
public Polygon triangle;
public Label label;
public StrategySelfNote_Element(int id) {
// Triangle ********************************************************************************
triangle = new Polygon();
triangle.setId(Integer.toString(id)+";StrategySelfNote");         
triangle.setFill(Color.AQUA);
triangle.setCursor(Cursor.HAND);
triangle.setVisible(false);
triangle.setLayoutX(0);
triangle.setLayoutY(0);
triangle.setCache(true);
// NOTE: This allowed Ellipse to be Dragged by MouseEvent, else only by Label (not sure if required w/Triangle???)
triangle.setPickOnBounds(true); 

// Label **********************************************************************************
label = new Label();
label.setId(Integer.toString(id)+";StrategySelfNote");         
label.setFont(Font.font  ("Calibri", FontWeight.BOLD, IntroQuestions.sizeFont_strategySelfNotes));//28
label.setWrapText(true);
label.setMaxWidth(MAX_WIDTH_STRATEGY_SELF_NOTE); // To Prevent HUGE TextRectangle
label.setMaxHeight(MAX_HEIGHT_STRATEGY_SELF_NOTE);
label.setAlignment(Pos.TOP_LEFT);
label.setStyle("-fx-background-color: aqua;"); //  -fx-background-color: AQUA; // light-yellow
//-------------
label.setCursor(Cursor.HAND);
label.setVisible(false);
label.setLayoutX(0); //debug: TRY 0 like before---to FIX When Dragging to 3/4 Quad, FREEZES & PANs scrlPane !!!
label.setLayoutY(0);
label.setCache(true);
//-------------
getChildren().addAll(triangle, label);
//------------- paneElement
this.setLayoutX(0.0); //10-26
this.setLayoutY(0.0);
this.setId(Integer.toString(id)+";StrategySelfNote");
this.setPickOnBounds(true); // NOTE: This allows Polygon to be Dragged by MouseEvent, else only by Label
this.setVisible(false);
this.setCache(true);
//-----
this.setOnMousePressed(boardStrategySelfNote_OnMousePressedEventHandler);
this.setOnMouseDragged(boardStrategySelfNote_OnMouseDraggedEventHandler);
this.setOnMouseReleased(boardStrategySelfNote_OnMouseReleasedEventHandler);
this.addEventFilter(InputEvent.ANY, boardStrategySelfNote_OnMouseFilterEventHandler);
}
}

。。这来自另一个函数,即Calculate&设置三角形:

llStrategySelfNotes.get(strategySelfNote_id-1).groupStrategySelfNote_Element.triangle.getPoints().addAll(
triBottomLeftX, triBottomLeftY,
triBottomRightX, triBottomRightY,
triTopX, triTopY);

更正我的初始描述:我说过Ellipse对象边界矩形没有捕捉到底层/重叠对象的鼠标事件。错了。他们确实;它们呈现出与三角形相同的问题(我现在假设,所有javaFX-Shape对象的子对象也是如此。(

***********我的肮脏解决方案*************我已经找到了一个Dirty但基本可行的解决方案来解决这个问题,它显然是由所有javaFXShape对象的子对象生成的。该问题是由Shape对象边界矩形捕捉底层/重叠对象的鼠标事件引起的。。。我无法将鼠标事件触发编码为仅限制在形状上,同时仍然可以点击重叠的对象:

1( 内部三角形onMousedPressed事件处理程序:检查用户是否单击了Outside Triangle但单击了Inside TriangleectBounds:(使用Barycentric风格的算法…stackOverflow上有很多算法(

static boolean isInside(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3) {
double L1 = (x-x1)*(y3-y1) - (x3-x1)*(y-y1), 
L2 = (x-x2)*(y1-y2) - (x1-x2)*(y-y2), 
L3 = (x-x3)*(y2-y3) - (x2-x3)*(y-y3);
return (L1>0 && L2>0  && L3>0) || (L1<0 && L2<0 && L3<0);
}    
isInTriangle = isInside (t.getX(), t.getY(),
triBottomLeftX, triBottomLeftY,
triBottomRightX, triBottomRightY,
triTopX, triTopY);            

2( 如果高于TRUE,则将isClickedOutsideTangle标志设置为TRUE,然后退出/返回事件处理程序而不使用事件。

3( TEST isClickedOutsideTangle标志位于onMousedTraged事件处理程序内部的开头。如果为true,则退出/返回处理程序,不使用consume((。

4( 内部三角形onMousedReleased事件处理程序:-测试三角形边界矩形是否与任何游戏板元素相交。如果是:[为了保留用户指定的zIndex游戏碎片]-保存所有Element zIndex值。-SORT元素z索引值升序-将排序值Elements设置为Front(([这现在允许所有元素都可以点击]

5( 如果isClickedOutsideTangle标志为TRUE,则重置为FALSE。


警告:此解决方案的一个不幸副作用是:用户将永远不被允许使三角形与任何其他游戏元素重叠,但其他游戏元素可以重叠三角形!

我仍然在寻找一个使用javaFX对象属性/方法的更简单的解决方案,这将允许1(Shape对象边界矩形下的元素的完全可点击性&2( 形状的动态大小,由游戏过程中的用户格式化决定?????

最新更新