Question

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 de LayoutManager et contient plusieurs instances de WatchItemPanel extends JPanel. Le WatchItemPanel expose son contenu avec un GridBagLayout.

Quand je charge le châssis et instancier les WatchPanel, je précharger le WatchListPanel avec trois instances de WatchItemPanel avec des données. Ces travaux très bien. Ma mise en œuvre permet de les réordonner par glisser-déposer (d'où la mise en page de null), et qui fonctionne aussi bien. Sur le WatchPanel est un bouton pour ajouter une nouvelle montre, qui fait apparaître un nouveau panneau dans son propre JFrame où une montre peut être ajouté. Lorsque le bouton « Enregistrer » est pressé sur ce nouveau panneau, il ajoute la nouvelle montre à la WatchPanel, qui ruisselle dans le WatchListPanel et ferme la JFrame pour ajouter une nouvelle montre.

Le problème est que lorsque ce nouveau WatchItemPanel est ajouté, il ne soit pas peint à moins que je redimensionnez la JFrame contenant le WatchPanel. Je peux communiquer avec elle par glisser-déposer. Je peux même faire glisser ce panneau spécifique - mais il est vide. Au moment où je redimensionner la WatchPanel, il apparaît et est peint correctement.

Maintenant, je l'ai substituée la méthode setBounds sur WatchListPanel à l'appel setSize et repaint sur chacune des instances de WatchItemPanel dans la liste, mais je fais appel setBounds et repaint sur le nouveau WatchItemPanel déjà que je l'ajoute. Je l'ai essayé d'ajouter repaint et appels invalidate dans toutes la pensée concevable place peut-être je raté quelque chose, mais pas de chance. Je absolument ai ajouté le WatchItemPanel au WatchListPanel et appelé setBounds, setVisible(true) et repaint sur le nouveau panneau.

Voici les méthodes de addWatch et updatePositions 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 méthodes de setBounds 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 cours de peinture. 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 supplémentaire « invalide » il dans le panneau? Quand je redimensionnez la WatchPanel la « invalide » va. Il ressemble à une colonne supplémentaire, cependant. Il n'y a pas valeur non valide correspondante sur les autres lignes. (Ce qui est la sortie de JPanel.toString() par défaut avec le nom du paquet supprimé.

Était-ce utile?

La solution

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top