Что такого особенного в 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 14

2 ответа:

  • С CardLayout легче иметь свободную муфту (хотя и не невозможно с roll your own)
  • С CardLayout предпочтительным размером держателя карты является размер самой большой карты, которую он держит.
  • CardLayout сложнее подделать и позволяет почти тривиальным смежным компонентам менять местами свои методы next() и prev().
  • Вы можете легко связать нужный компонент с константой - нет необходимости создавать Map<String, Component> для этой цели, поскольку он уже существует для вас. Я довольно часто использовал для этого перечисления.
  • нет необходимости помнить, чтобы вызвать repaint() и revalidate() при замене компонентов.
  • Он построен для и позволяет легко повторно использовать компоненты.

Я не могу объяснить причину отказа, хотя, если они не расстроены, вы не упомянули о необходимости не забыть позвонить repaint() и revalidate() при замене компонентов. Вам придется спросить у низшего избирателя, достаточно ли он храбр, чтобы ответить.

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

Все это сводится к изобретению колеса: зачем вам это нужно, когда такой проверенный временем класс уже доступен?