Содержимое моего JComponent обновляется только после изменения размера вручную - PullRequest
3 голосов
/ 30 августа 2010

Я пытаюсь выяснить, почему мой JComponent обновляется, когда я вручную перетаскиваю свое окно, но не обновляется, когда я вызываю repaint или revalidate.Данные готовы к отображению, но они не будут отображаться, пока я не изменю размер вручную.Кто-нибудь может дать несколько советов о том, что я могу сделать, или это звучит так, как будто это не проблема Swing, так как я пытался перерисовать и заново подтвердить?

sp.setSize(sp.getSize().width, sp.getSize().height+1);
sp.setSize(sp.getSize().width, sp.getSize().height-1);

Если используется первая строка, JComponent обновится сам.Если я не использую ни одну, или обе эти строки, это не так, что мне кажется странным.

Я просто помещаю JPanel в JInternalFrame в JDesktopPane.Есть две основные функции для того, что я пытаюсь сделать.Один добавляет новый JPanel, а другой пытается обновить его, чтобы отобразились новые данные:

public void addNewSP()
 {
sp = new JInternalFrame("SP");
  sp.setClosable(true);
  sp.setLocation(700, 400); //this should be changed to something based on screen size
  sp.setResizable(true);
  sp.add(popUp);
  this.parentContainer.add(sp, JLayeredPane.DRAG_LAYER);
  sp.pack();
  sp.show();
  sp.setSize(500, 500);
  sp.setPreferredSize(new Dimension(500, 500));
}

public void refreshSP()
 {

  sp.repaint();
  sp.validate();
  sp.repaint();

  sp.validate();
  parentContainer.validate();
  parentContainer.repaint();

  sp.setSize(sp.getSize().width, sp.getSize().height+1);
  sp.setSize(sp.getSize().width, sp.getSize().height-1);
  }
 }

BTW parentContainer - это JDesktopPane

Ответы [ 4 ]

7 голосов
/ 31 августа 2010

При изменении содержимого контейнера вы должны вызвать оба:

  • revalidate(), чтобы заставить его пересчитать макет для его содержимого
  • repaint(), чтобы запросить перерисовку дляэтот контейнер
1 голос
/ 31 августа 2010

, но он не будет отображаться, пока я не изменю размер вручную.

Мы не знаем контекста вашего вопроса, поэтому SSCCE всегда следует публиковать, как предлагалось ранее.

Обычно JComponent не имеет предпочтительного размера, поэтому я предполагаю, что Swing не считает, что ему нужно рисовать компонент. Когда вы изменяете размер фрейма, скорее всего, компонент был добавлен в центр BorderLayout, поэтому его размер автоматически изменяется, чтобы заполнить все пространство фрейма.

Решение состоит в том, чтобы дать вашему компоненту «предпочтительный размер», чтобы любой менеджер компоновки мог использовать эту информацию для правильного отображения компонента.

0 голосов
/ 31 августа 2010

Я полагаю, parentContainer является JDesktopPane?
Какие изменения вы вносите в sp, которые не отображаются?

Изменение размера sp приведет к перерисовке Swingс нуля.Вот почему setSize() исправляет отображение.

Скорее всего, изменения, которые вы делаете, либо не происходят в EDT, либо не делают недействительным нужный контейнер.Например, если вы измените видимость компонента в sp, вам потребуется вызвать sp.invalidate(), чтобы перезапустить менеджер макета.

Вы проверили, что вы только меняете компоненты (или ихмодели) на EDT?

Быстрый тест для этого - запуск с Веществом LAF , так как он будет жаловаться, если вы измените что-либо в другом потоке.

0 голосов
/ 30 августа 2010

если вы изменяете подкомпоненты контейнера, вам следует вызвать jcomponent.validate ();

...