Почему мой новый компонент не отображается в нулевом менеджере макета? - PullRequest
0 голосов
/ 13 сентября 2010

В 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() с удаленным именем пакета.

1 Ответ

0 голосов
/ 13 сентября 2010

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

...