Как ограничить MouseEvents из JavaFx8 Polygon-Triangle: запускать ТОЛЬКО сам треугольник, а не границы прямоугольника макета треугольника? - PullRequest
0 голосов
/ 07 ноября 2018

Я создал треугольник, используя объект Polygon, наряду с событиями onMousePressed, Dragged, Released, которые позволяют перемещать мышь по экрану с помощью MouseDragged. Прекрасно работает в созданной мной игре JavaFX Application (для автономного ноутбука).

Проблема в том, что я хочу, чтобы события мыши-треугольника запускались только внутри границы формы треугольника, а НЕ снаружи треугольника. В настоящее время события, кажется, запускаются в любом месте в пределах невидимых границ макета RECTANGLE полигона-треугольника (то есть невидимого прямоугольника, который встраивает / окружает треугольник). Такое поведение позволяет перетаскивать треугольник с помощью: 1) курсора вне треугольника и 2) курсора в любом месте в пределах невидимых границ многоугольника-треугольника.

Это поведение сбивает с толку Пользователя: 1) непреднамеренным перетаскиванием Треугольника, 2) блокированием событий других игровых фигур (которые перекрываются невидимыми границами прямоугольника Треугольника), делающими их неиграемыми до тех пор, пока Треугольник не вытащен из способ.

Я выполнил это ограничение MouseEvent для формы, используя объект Ellipse и свойство setPickOnBounds (true); Похоже, что не работает то же самое с объектами Polygon.


Я проверил на stackOverflow.com, и ближайшая статья, посвященная этой проблеме, которую я смог найти, заключается в следующем: она не затрагивает запуск MouseEvent внутри / снаружи Shapes.

StackOverflow.com: 1. Как плавно перетащить полигон JavaFX? Как плавно перетащить полигон JavaFX? В статье не указана область «Форма кликабельна».

  1. Кнопка Android с пользовательской формой Кнопка Android с пользовательской формой Является ли 5 ​​лет для Android и конкретных, Есть ли более эффективный способ с javaFX8 & Polygons? Кроме того, размеры моего Треугольника являются динамическими и рассчитаны так, чтобы соответствовать размеру внедренного пользователем форматированного 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);
    }
}

. , , Это из другой функции, чтобы рассчитать и установить треугольник:

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

1 Ответ

0 голосов
/ 11 ноября 2018

ИСПРАВЛЕНИЕ К МОЕМУ НАЧАЛЬНОМУ ОПИСАНИЮ: Я сказал, что прямоугольник границ объектов эллипса не улавливает события мыши нижележащих / перекрывающихся объектов. НЕПРАВИЛЬНО. Они ДЕЛАЮТ и представляют ту же проблему, что и Треугольники (я полагаю сейчас, как и все дочерние объекты javaFX Shape).

*********** Мое грязное решение ************* Я нашел грязное, но в основном работоспособное решение этой проблемы, по-видимому, созданное всеми дочерними объектами javaFX Shape. Эта проблема вызвана тем, что прямоугольник границ объекта Shape перехватывает события мыши нижележащих / перекрывающихся объектов ... Я не могу запустить событие мыши Code для ограничения ТОЛЬКО фигуры, хотя перекрывающиеся объекты по-прежнему должны быть кликабельными:

1) Внутри треугольника обработчик события onMousedPressed: ПРОВЕРЬТЕ, если пользователь нажал на кнопку OutsideTriangle-but-InsideTriangleRectBounds: (используйте алгоритм барицентрического стиля ... многие из них доступны в 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, установите для флага isClickedOutsideTriangle значение TRUE, затем обработчик события выхода / возврата БЕЗ потребляющего события.

3) Флаг TEST isClickedOutsideTriangle в начале внутреннего обработчика события onMousedDragged. Если это правда, выход / возврат из обработчика, без потребления ().

4) Внутри треугольника обработчик события onMousedReleased: -TEST если треугольник bounds-rectangle пересекает любые элементы игрового поля. Если да: [чтобы сохранить указанный пользователем zIndex игровых фигур] -Сохранить все значения элемента zIndex. -SORT Элемент zIndex значения по возрастанию -SET отсортированное значение Elements toFront () [теперь это позволяет всем элементам быть активными]

5) Если флаг isClickedOutsideTriangle имеет значение ИСТИНА, сбросьте его на ЛОЖЬ.


ПРЕДУПРЕЖДЕНИЕ: К сожалению, побочным эффектом этого решения является: Пользователям никогда не разрешат перекрывать треугольники другими игровыми элементами, но другие элементы игры могут перекрывать треугольники!

Я все еще ищу более простое решение, использующее свойства / методы объекта javaFX, это позволит: 1) полную кликабельность элементов, лежащих в основе Shape-object bounds-rectangle & 2) динамическое изменение размеров Shapes, определяемое форматированием пользователем во время игры ?????

...