Графический интерфейс Java: предотвращение перекрытия компонентов Swing с динамическим изменением размера

Отказ от ответственности: я новичок в свинге.

TLDR: я динамически добавляю панели JPanel к «окружающей» панели JPanel с помощью кнопки. Все панели используют MiGLayout. Внешняя панель содержит только одну ячейку, и по мере добавления внутренних панелей создается больше строк сверху вниз (ограничение «плавность»). Внутренние панели состоят из двух рядов, но второй раскрывается динамически (ограничение макета «hidemode 3» с setVisible(false) до тех пор, пока не будет выполнено условие).

Что происходит, так это то, что при добавлении внутренней панели и отображении ее второй строки она перекрывается с панелью под ней. Я пытался вызвать перепроверку и перерисовку везде, где это возможно. Мне кажется, что внешняя/окружающая панель просто должна перепроверить свои дочерние компоненты, но, похоже, этого не происходит.

Задний план

Я использую MiGLayout и Swing для создания графического интерфейса для импорта в мою базу данных. Пользователи должны иметь возможность нажать кнопку, которая добавляет панели к закрывающей панели. В частности, [рассматриваемая часть] графического интерфейса состоит из...

  1. объемлющий JPanel (черный), содержащий:
  2. JToolbar(синий) и
  3. JScrollPane(красный), у которого есть Viewport
  4. другой JPanel(зеленый)

этот последний JPanel, #4, является контейнером для динамически добавляемых панелей с помощью кнопки (см. второе изображение ниже).

из оконного конструктора/eclipse

Самая нижняя панель JPanel, №4, использует MiGLayout. Сама панель и содержащая ее область прокрутки скрыты от просмотра до тех пор, пока пользователь не нажмет кнопку рядом с выпадающим списком «Файл». (не показано на рисунке выше, так как это не было во время выполнения).

После нажатия на эту панель добавляется подкласс JPanel: (скриншот во время выполнения)

панель добавлена

Панели укладываются друг на друга по мере добавления новых.

Эта внутренняя панель состоит из двух рядов, но второй ряд невидим и не влияет на макет, пока не станет видимым. Он становится видимым через слушателей, когда в текстовом поле выполняется условие.

Проблема

Если второй ряд внутренней панели становится видимым, он перекрывает панель в ряду под ним. Вот что я имею в виду....

Пользователь добавляет три панели: 3 источника в порядке

Вторая панель вызывает setVisible(true), так что теперь состоит из двух строк, но скрывает третью панель:

перекрытие

Для драматического эффекта (то же время выполнения): очевидное перекрытие

Проблема очевидна. Как предотвратить это совпадение?

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

Скажем, я добавляю одну панель, затем запускаю скрытую строку, ЗАТЕМ добавляю другую панель --- все еще есть перекрытие. Насколько я понял, revalidate() должен позаботиться об этих вещах, но я звонил везде, где только можно (возможно, слишком часто, если возможно??), но безрезультатно..

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

Я могу придумать некоторые обходные пути, но это кажется возможным!

Мой самый длинный вопрос, извините за это. Любая помощь приветствуется. Спасибо.


person tenwest    schedule 05.03.2015    source источник
comment
Рассмотрите возможность предоставления запускаемого примера, демонстрирующего вашу проблему. Это не дамп кода, а пример того, что вы делаете, который подчеркивает проблему, с которой вы столкнулись. Это приведет к меньшей путанице и лучшим ответам.   -  person MadProgrammer    schedule 05.03.2015
comment
действительно, думал аналогично. я соберу это вместе   -  person tenwest    schedule 05.03.2015
comment
хаха. конечно, пример программы, которую я собрал, чтобы продемонстрировать, на самом деле ведет себя так, как предполагалось! так что, возможно, есть более серьезная проблема в общем графическом интерфейсе.   -  person tenwest    schedule 06.03.2015
comment
и .... Кажется, я решил это, лол. Я опубликую ответ и обновлю пример кода.   -  person tenwest    schedule 06.03.2015


Ответы (1)


Оказывается, проблема заключалась в установке ограничений строк на (зеленой) внешней панели.

Я установил минимальный/предпочтительный размер строки на 30 пикселей с максимальным размером 60 пикселей (60 — это размер двухстрочной внутренней панели). Очевидно, это не сделало того, что я думал, что должно.

Я слышал, что нужно с осторожностью использовать границы pref/max/min в свингах --- но я проигнорировал это, и вот что произошло!

Полностью удаляя ограничения строк, внешняя (зеленая) панель сдвигает строки и что-то не так.

person tenwest    schedule 05.03.2015
comment
Вы не должны явно устанавливать границы pref/max/min; это работа для менеджера компоновки, и MigLayout делает это правильно. Вы уверены в пикселях? Одним из важнейших преимуществ менеджера MigLayout является то, что он позволяет использовать логические значения вместо пикселей. - person Jan Bodnar; 07.03.2015
comment
Я установил эти границы в рамках ограничений менеджера MigLayout и да, используя пиксели, обозначенные как «px». - person tenwest; 09.03.2015