Что такого особенного в CardLayout vs ручное добавление / удаление JPanels?
На StackOverflow было много раз, когда пользователь задавал подобный вопрос...
У меня есть главнаяJPanel
, которая содержит дочернююJPanel
. Когда пользователь нажимает кнопку a кнопка, ребенокJPanel
должен измениться на другойJPanel
. Как я могу это сделать? добиться этого.
Чаще всего пользователь действительно пытался реализовать эту проблему, но не может заставить ее работать.
Всякий раз, когда я отвечаю на этот вопрос, я говорю им сделать что-то вроде этого (put просто)...JPanel myFrame = new JPanel();
myFrame.remove(oldPanel);
myFrame.add(newPanel);
Я рассматриваю это как вполне законный ответ, и я лично использовал его во многих своих собственных проектах Java без проблем. Тем не менее, я всегда получаю downvotes для моего ответа, и все просто говорят: "используйте CardLayout
".
Итак, мой вопрос в том, почему все так очарованы CardLayout
, до такой степени, что мой ответ заслуживает понижения? Почему я должен использовать CardLayout
вместо добавления/удаления панелей с помощью моего кода выше?
В качестве дальнейшего вопроса, не могли бы вы все еще предлагайте CardLayout
для интерфейсов, которые имеют динамические JPanels. Например, большинство моих программ реализуют пользовательский фреймворк плагинов, где может быть много сотен JPanels
, но я загружаю и отображаю панели только так, как они действительно необходимы. При нормальном использовании программы большинство панелей никогда не загружались и не требовались. Для этого типа сценария мой подход к кодированию был бы лучшим решением, поскольку я понимаю, что CardLayout
потребует от меня фактически создать все JPanels
хотя большинство из них никогда не будут использованы?
2 ответа:
- С CardLayout легче иметь свободную муфту (хотя и не невозможно с roll your own)
- С CardLayout предпочтительным размером держателя карты является размер самой большой карты, которую он держит.
- CardLayout сложнее подделать и позволяет почти тривиальным смежным компонентам менять местами свои методы
Вы можете легко связать нужный компонент с константой - нет необходимости создаватьnext()
иprev()
.Map<String, Component>
для этой цели, поскольку он уже существует для вас. Я довольно часто использовал для этого перечисления.- нет необходимости помнить, чтобы вызвать
Он построен для и позволяет легко повторно использовать компоненты.repaint()
иrevalidate()
при замене компонентов.Я не могу объяснить причину отказа, хотя, если они не расстроены, вы не упомянули о необходимости не забыть позвонить
repaint()
иrevalidate()
при замене компонентов. Вам придется спросить у низшего избирателя, достаточно ли он храбр, чтобы ответить.
CardLayout
был тщательно протестирован и доказал свою работоспособность. Он правильно получает блокировку дерева компонентов и выполняет проверку компонентов , чтобы гарантировать, что ничего не может пойти не так. Ваше решение, хотя оно может работать большую часть времени, потерпит неудачу при определенных обстоятельствах.Все это сводится к изобретению колеса: зачем вам это нужно, когда такой проверенный временем класс уже доступен?