Как динамически добавлять панели в другие панели во время выполнения на Java?

Я пытаюсь снова войти в java (это было несколько лет). Я никогда не делал никакого кодирования GUI в java. Я использую Netbeans, чтобы начать с этого.

При использовании winforms в С# на работе я использую usercontrols для сборки частей своего интерфейса и динамического добавления их в формы.

Я пытаюсь использовать JPanels как usercontrols в С#. Я создал форму JPanel, называемую BlurbEditor. На нем есть несколько простых элементов управления. Я пытаюсь добавить его на другую панель во время выполнения на событие кнопки.

Вот код, который, как я думал, будет работать:

mainPanel.add(new BlurbEditor());
mainPanel.revalidate();
//I've also tried all possible combinations of these too
//mainPanel.repaint();
//mainPanel.validate();

Это, к сожалению, не работает. Что я делаю неправильно?

Ответ 2

Swing/AWT компоненты обычно должны иметь макет, прежде чем добавлять к ним вещи, иначе UI не будет знать, где разместить подкомпоненты.

BFreeman предложил BorderLayout, который является одним из самых простых в использовании и позволяет вам "склеивать" вещи сверху, снизу, слева, справа или по центру родителя.

Существуют и другие, такие как FlowLayout, который похож на textarea - он добавляет компоненты слева направо вверху родителя и обертывает новую строку, когда она доходит до конца.

GridBagLayout, который всегда был известен тем, что его невозможно было понять, но дает вам почти весь контроль, который вам нужен. Немного похожие на те таблицы HTML, которые мы видели с причудливыми комбинациями атрибутов rowspan, colspan, width и height, которые никогда, казалось, не выглядели так, как вы хотели их.

Ответ 3

mainPanel.add(новый BlurbEditor());

mainPanel.validate();

mainPanel.repaint();

Ответ 4

Как и во всем коде swing, не забудьте вызвать любое обновление gui в потоке отправки событий. См. этот за то, почему вы должны делать обновления, подобные этому

// Do long running calculations and other stuff outside the event dispatch thread
while (! finished )
  calculate();
SwingUtilities.invokeLater(new Runnable(){
  public void run() {
    // update gui here
  }
}

Ответ 5

Я имел дело с подобной проблемой, я хотел изменить панель, содержащуюся в панели во время выполнения
После некоторого тестирования, повторного тестирования и много неудачного моего псевдо-алгоритма:

parentPanel: содержит панель, которую мы хотим удалить. childPanel: панель, которую мы хотим переключить
parentPanelLayout: макет parentPanel
editParentLayout(): создает parentPanel с разными дочерними элементами и NEW parentPanelLayout каждый раз, когда

parentPanel.remove(childPanel); 
editParentLayout();
parentPanel.revalidate();
parentPanel.repaint();

Ответ 6

Попробуйте mainPanel.invalidate(), а затем при необходимости mainPanel.validate(). Также может быть стоит проверить, что вы делаете все это в потоке отправки событий, иначе ваши результаты будут пятнистыми и (вообще) не детерминированными.