Проблема с добавлением GridBagLayout внутри ActionListener

У меня есть JMenuItem с ActionListener, в этом ActionListener я хочу добавить GridBagLayout в мой frame (который может иметь или не иметь панель содержимого, но еще добавленную - для целей тестирования она не), а затем добавьте components к этому frame. Дизайн frame works на нем собственный, но я хочу trigger его из ActionListener на JMenuItem, и вот где я столкнулся с проблемой. Он не будет отображаться внутри ActionListener. Я попытался запустить тот же код из другого метода в классе из AL, и это тоже не сработало.

Когда я полностью комментирую ActionListener, JLabel, я хочу проверить добавление в GBL в правильном месте, а система prints my debug строк здесь и здесь2. compiler нет синтаксических ошибок. Это дает желаемый результат, и этикетка печатается. (Ниже приведено изображение того, что происходит, когда я полностью комментирую AL). Ниже приведен фрагмент кода (в кадре которого находится мой JFrame):

enter image description here

// (frame created, menus added, etc.) ...
JMenuItem vPoke1Item = new JMenuItem("Pokemon 1");
vPoke1Item.setActionCommand("poke1");
viewMenu.add(vPoke1Item);

//Setup GBL to view stats for Pokemon 1
  vPoke1Item.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e)
      {
//        debug output
          System.out.println("here");

//        Set up the content pane
          frame.getContentPane().removeAll();
          GridBagLayout gbl = new GridBagLayout();
          GridBagConstraints gbc = new GridBagConstraints();
          Container pane = frame.getContentPane();
          pane.setLayout(gbl);

//        Make a StatCalcObject (all my labels/fields are already initialized)
          StatCalc1 sc1 = new StatCalc1();

//        Add it to pane
          gbc.gridx = 0;gbc.gridy = 0;gbl.setConstraints(sc1.speciesL, gbc);
          pane.add(sc1.speciesL);
          frame.revalidate();
          frame.repaint();

//        debug output
          System.out.println("here2");
      }
  });
// (etc.)

Теперь, когда я запускаю этот код, я все еще получаю строки отладки "здесь" и "here2" для печати, поэтому он сообщает мне, что ActionListener работает нормально. Но ярлык не появляется. Все еще нет синтаксических ошибок, собранных компилятором. Поэтому я почесываю голову. Что я делаю не так? Я надеюсь, что этого фрагмента кода достаточно, чтобы понять проблему, но если вы хотите получить полный код, я могу его предоставить.

Ответ 1

Если вы используете окно с фиксированным размером, все будет работать, если вы замените

frame.revalidate();
frame.repaint();

с

pane.invalidate();
pane.validate();

или

pack();

если у вас нет рамки фиксированного размера. Обратите внимание, что проверка подлинности не поддерживается JFrame или Container. Также лучше заменить

gbl.setConstraints(sc1.speciesL, gbc);
pane.add(sc1.speciesL);

с

pane.add(sc1, gbc);

для лучшего стиля кода.

Ответ 2

Посмотрите, что происходит, когда вы вызываете метод pane.add(sc1.speciesL);

Container.add(sc1.speciesL, null, -1) вызывается следующий

Затем Container.addImpl(Component comp, Object constraints, int index)

Затем ограничения, которые вы задали ранее, gbl.setConstraints(sc1.speciesL, gbc); заменен нулевым.

  if (layoutMgr instanceof LayoutManager2) {
    ((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);
  }

Затем панель не показывала ваши новые добавленные компоненты, потому что GridBagConstraints теперь имеет значение null

И вам действительно не нужно принудительно

  frame.revalidate();
  frame.repaint();
  frame.pack();

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

pane.add(sc1.speciesL, gbc);

И удалите uselsess

gbl.setConstraints(sc1.speciesL, gbc);