Il y a un panneau dans un JFrame
appelé WatchPanel extends JPanel
qui utilise un GroupLayout
et contient un WatchListPanel extends JPanel
. Le WatchListPanel
utilise un null
LayoutManager
et contient plusieurs instances de WatchItemPanel extends JPanel
. Le WatchItemPanel
expose son contenu avec un GridBagLayout
.Pourquoi mon nouveau composant ne s'affiche-t-il pas dans un gestionnaire de disposition nul?
Lorsque je charge le cadre et instancie le WatchPanel
, je précharge le WatchListPanel
avec trois instances WatchItemPanel
avec des données. Cela fonctionne bien. Ma mise en œuvre permet de les réorganiser en les faisant glisser (d'où la disposition null
), et cela fonctionne également. Sur le WatchPanel
est un bouton pour ajouter une nouvelle montre, qui ouvre un nouveau panneau dans son propre JFrame
où une montre peut être ajouté. Lorsque le bouton "Enregistrer" est appuyé sur ce nouveau panneau, il ajoute la nouvelle montre au WatchPanel
, qui descend dans le WatchListPanel
et ferme le JFrame
pour ajouter une nouvelle montre.
Le problème est que lorsque ce nouveau WatchItemPanel
est ajouté, il ne sera pas peint sauf si je redimensionne le JFrame
contenant le WatchPanel
. Je peux interagir avec ça par drag-n-drop. Je peux même faire glisser ce panneau spécifique - mais il est vide. Au moment où je redimensionne le WatchPanel
, il apparaît et est peint correctement.
Maintenant, j'ai la méthode setBounds
substituée sur WatchListPanel
pour appeler setSize
et repaint
sur chacun des cas WatchItemPanel
dans la liste, mais je fais appel setBounds
et repaint
sur le nouveau WatchItemPanel
déjà que je l'ajoute. J'ai essayé d'ajouter repaint
et invalidate
appels dans tous les endroits imaginables pensant peut-être que j'ai raté quelque chose, mais pas de chance. J'ai absolument ajouté le WatchItemPanel
au WatchListPanel
et appelé setBounds
, setVisible(true)
, et repaint
sur le nouveau panneau.
Voici les addWatch
et updatePositions
méthodes sur le 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(); }
Et voici les setBounds
méthodes sur 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(); } }
Un autre élément d'information ici - les quatre panneaux sont en train de repeindre . Je l'emportaient sur paintComponent
dans le WatchItemPanel
et a ajouté un System.out.println
et a obtenu ce résultat:
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=]
Qu'est-ce que la colonne « invalide » supplémentaire il dans le panneau? Quand je redimensionne le WatchPanel
le "invalide" s'en va. Cela ressemble à une colonne supplémentaire, cependant. Il n'y a pas de valeur non invalide correspondante sur les autres lignes. (Ce qui est la valeur par défaut JPanel.toString()
sortie avec le nom du package enlevé.