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