2010-09-13 4 views
0

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 nullLayoutManager 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é.

Répondre

0

Après avoir ajouté le composant, appelez this.revalidate(). Cela provoque le récipient à marquer à nouveau la présentation de ses composants. Une fois que cette ligne de code est ajouté, il fonctionne parfaitement

Questions connexes