Почему мой новый компонент не отображается в null layout manager?

StackOverflow https://stackoverflow.com/questions/3701844

  •  02-10-2019
  •  | 
  •  

Вопрос

Есть панель в JFrame вызванный WatchPanel extends JPanel который использует GroupLayout и содержит WatchListPanel extends JPanel.Тот Самый WatchListPanel использует null LayoutManager и содержит несколько экземпляров WatchItemPanel extends JPanel.Тот Самый WatchItemPanel выкладывает его содержимое с помощью GridBagLayout.

Когда я загружаю фрейм и создаю экземпляр WatchPanel, я предварительно загружаю WatchListPanel с тремя WatchItemPanel экземпляры с данными.Они прекрасно работают.Моя реализация позволяет переупорядочивать их путем перетаскивания (отсюда null макет), и это тоже работает.На WatchPanel это кнопка для добавления новых часов, которая открывает новую панель в своем собственном JFrame куда можно добавить часы.Когда на этой новой панели нажимается кнопка "Сохранить", она добавляет новые часы в WatchPanel, который стекает в WatchListPanel и закрывает JFrame для добавления новых часов.

Проблема в том, что когда этот новый WatchItemPanel добавляется, он не будет окрашен, если я не изменю размер JFrame содержащий WatchPanel.Я могу взаимодействовать с ним с помощью drag-n-drop.Я даже могу перетащить эту конкретную панель, но она пуста.В тот момент, когда я изменяю размер WatchPanel, он отображается и нарисован правильно.

Теперь я переопределил setBounds способ включения WatchListPanel позвонить setSize и repaint на каждом из WatchItemPanel экземпляров в списке, но я вызываю setBounds и repaint о новом WatchItemPanel уже сейчас, когда я это добавляю.Я пробовал добавлять repaint и invalidate звонит во все мыслимые места, думая, что, может быть, я что-то пропустил, но безуспешно.Я абсолютно уверен, что добавил WatchItemPanel к тому WatchListPanel и позвал setBounds, setVisible(true), и repaint на новой панели.

Вот эти addWatch и updatePositions методы на WatchListPanel:

public void addWatch(Watch watch) {
    WatchItemPanel watchPanel = new WatchItemPanel(watch);
    synchronized (this.watches) {
        this.watches.add(watch);
    }
    this.watchPanels.put(watch, watchPanel);
    this.add(watchPanel);
    watchPanel.setOpaque(false);
    watchPanel.setForeground(this.getForeground());
    watchPanel.setBackground(this.getBackground());
    watchPanel.setVisible(true);
    watchPanel.setSize(this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    for (MouseListener l: this.mouseListeners)
        watchPanel.addMouseListener(l);
    for (MouseMotionListener l: this.mouseMotionListeners)
        watchPanel.addMouseMotionListener(l);
    this.updatePositions();
}

private void updatePositions() {
    int count = 0;
    synchronized (this.watches) {
        for (Watch watch: this.watches) {
            if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition))
                count++;
            WatchItemPanel panel = this.watchPanels.get(watch);
            if (panel == this.selectedWatchPanel)
                continue;
            panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
            count++;
        }
    }
    if (this.selectedWatchPanel != null)
        this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    this.repaint();
}

И вот эти setBounds методы по WatchListPanel:

@Override
public void setBounds(Rectangle r) {
    super.setBounds(r);
    for (WatchItemPanel panel: this.watchPanels.values()) {
        panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

@Override
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    for (WatchItemPanel panel: this.watchPanels.values()) {
        panel.setSize(width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

Еще одна информация здесь - все четыре панели окрашиваются.Я перешел все границы paintComponent в WatchItemPanel и добавил System.out.println и получил такой результат:

WatchItemPanel[,0,66,366x22,invalid,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,44,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,22,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,0,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]

Что это за дополнительный столбец "недопустимый" там, на панели?Когда я изменяю размер WatchPanel "инвалид" уходит.Хотя это выглядит как дополнительная колонка.В других строках нет соответствующего недопустимого значения.(это значение по умолчанию JPanel.toString() вывод с удаленным именем пакета.

Это было полезно?

Решение

После добавления компонента вызовите this.revalidate().Это приводит к маркировке контейнера для изменения компоновки его компонентов.Как только эта строка кода добавлена, она работает безукоризненно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top