Что такого особенного в CardLayout против ручного добавления/удаления JPanels?

В StackOverflow было много раз, когда пользователь задает такой вопрос...

У меня есть основной JPanel, содержащий дочерний элемент JPanel. Когда пользователь нажимает кнопку, дочерний элемент JPanel должен измениться на другой JPanel. Как я могу достичь этого.

Чаще всего пользователь действительно пытался реализовать эту проблему, но не может заставить ее работать.

Всякий раз, когда я отвечаю на этот вопрос, я говорю им делать что-то вроде этого (просто)...

JPanel myFrame = new JPanel();
myFrame.remove(oldPanel);
myFrame.add(newPanel);

Я рассматриваю это как вполне законный ответ, и я лично использовал это во многих своих проектах Java без проблем. Тем не менее, я всегда получаю downvotes для моего ответа, и все просто говорят "Использовать CardLayout".

Итак, мой вопрос: почему все так очарованы CardLayout, до того момента, когда мой ответ заслуживает понижения? Почему я должен использовать CardLayout вместо добавления/удаления панелей, используя мой код выше?

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

Ответы

Ответ 1

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

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

Ответ 2

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

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