Объектно-ориентированный подход к 2D-графике: делегирование кликов JPanel окрашенным объектам


Исходя из Qt, я всегда использую QGraphicsScene в сочетании с QGraphicsItem объектами для рисования таких вещей, как блок-схемы, игровые доски и т. д. Графические сцены-это виджеты, которые являются эквивалентом Qt компонентов Swing. Эти объекты QGraphicsItem имеют свои собственные обработчики кликов, поэтому клики по определенным частям графической сцены автоматически делегируются соответствующему графическому элементу.

Я ищу, чтобы повторить этот рабочий процесс в Java Swing. До сих пор я только нашел способ рисовать все вручную, который это также означало бы, что мне придется программировать логику нажатия вручную. Он включает в себя подкласс JPanel и переопределение функции paintComponent, как показано здесь:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;

    for (int row = 0; row < _numRows; ++row) {
        for (int col = 0; col < _numCols; ++col) {
            g2.drawRect(2 + _squareSize*col, 2 + _squareSize*row, _squareSize, _squareSize);
        }
    }
}

Есть ли в Java Swing подобный объектно-ориентированный способ рисования 2D-графики?

2 4

2 ответа:

Как правило, есть два способа достичь этого:

  1. Используйте один J-компонент в качестве основы и нарисуйте все ваши "элементы" непосредственно на нем (в методе paintComponent). В этом случае вам придется обрабатывать все события мыши / клавиши самостоятельно, добавляя прослушиватели мыши / клавиши к этому компоненту J и обрабатывая события в зависимости от местоположения щелчка/нажатия горячей клавиши.

  2. Другой способ заключается в использовании любого контейнера (или просто простой JPanel) в качестве базы и размещении на нем любого другого компонента с помощью макетов (например, с" нулевой " компоновкой вы можете просто поместить компоненты по абсолютным координатам внутри контейнера, также называемого границами). В этом случае различные события будут передаваться непосредственно этим компонентам в зависимости от их расположения внутри контейнера (в основном - каждый компонент имеет границы прямоугольника, в которых все события передаются этому компоненту, если ничего не лежит поверх него, но вы можете изменить эту область "попадания" на любую форму, которую вы хотите). Также в этом случае вы можете использовать любые пользовательские окрашенные компоненты в качестве Чайлдс или стандартные компоненты качания (как JButton, JCheckBox и такие).

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

Используйте Shape. Есть овалы, линии, многоугольники и т.д. формы. Вы можете использовать существующие или создать собственные, используя класс Area и комбинируя Shapes.