Каковы преимущества рисования на JPanel и JComponent?

Итак, в недавнем ответе кто-то прокомментировал это (в отношении живописи):

"Вероятно, это какая-то болезнь 90% программистов Swing: когда они создают свой собственный компонент, они всегда расширяют JPanel вместо JComponent. Почему?"

Я все еще довольно новичок в программировании, поэтому считаю, что слишком рано называть себя программистом Swing, поскольку мне еще предстоит найти свою нишу. Но переопределение JPanel - это то, как меня учили. Поэтому я решил найти ответ на вопрос "Почему?". вопрос комментатора. Вот некоторые из ответов, которые я нашел.


Фоновая картинка - основное отличие. Класс JComponent не создает свой фон, поэтому вам нужно нарисовать фон в переопределенном методе paintComponent. Напротив, JPanel имеет непрозрачный фон, который можно нарисовать, вызвав его метод paintComponennt.


Вместо расширения JComponent некоторые программисты предпочитают расширять класс JPanel. JPanel предназначен для контейнера, который может содержать другие компоненты, но также можно рисовать на нем. Есть только одно отличие. Панель непрозрачна, что означает, что она несет ответственность за покраску всех пикселей в пределах ее границ. Самый простой способ добиться этого - нарисовать панель цветом фона, вызвав super.paintComponent в методе paintComponent для каждого подкласса панели:


Если для свойства opaque установлено значение true... тогда системе рисования Swing не нужно тратить время на рисование за компонентом, следовательно, улучшает производительность.


Я думаю, что последняя цитата действительно объясняет это лучше всего. Но помимо непрозрачности существуют и другие полезные причины: "90% программистов Swing имеют эту болезнь" расширения JPanel, а не JComponent?

Ответ 1

Разница в обработке непрозрачности не является единственным фактором.

Поиск исходного кода JPanel помогает, потому что это всего ~ 100 строк.

Все конструкторы в конечном итоге называют этот конструктор. Непрозрачность и двойная буферизация по умолчанию - true. По умолчанию LayoutManager - это FlowLayout, который вы можете или не хотите.

public JPanel(LayoutManager layout, boolean isDoubleBuffered) {
        setLayout(layout);
        setDoubleBuffered(isDoubleBuffered);
        setUIProperty("opaque", Boolean.TRUE);
        updateUI();
}

Лой и др. в O'Reilly Java Swing 2-е издание рекомендуют расширять JComponent для действительно настраиваемых компонентов (стр .1333), но также упомянуть о необходимости рассмотрения делегата пользовательского интерфейса. JPanel обрабатывает его собственный конкретный AccessibleContext, тогда как класс, расширяющий JComponent, возвращает null.

Для визуального компонента, доступного только для чтения, я обычно расширяю JComponent, но, вероятно, дважды подумаю о интерактивном компоненте из-за дополнительных соображений для доступности.

Приветствия,

Ответ 2

Это правильный ум. Если вы проверите источник JPanel, он не коснется непрозрачного. Однако бывает, что большинство версий большинства PL & Fs устанавливают непрозрачное свойство. Они могут произвольно устанавливать другие свойства.

Ранние версии GTK PL & F не задавали непрозрачность для JPanel. Это было изменено, по-видимому, на производительность, хотя, возможно, нехорошие программисты Swing, использующие JPanel неуместно, возможно, были фактором.

Существует очень мало веских причин для подкласса JPanel. Не делайте этого.