Frage

Es ist eine Platte in einem JFrame ein WatchPanel extends JPanel genannt, die eine GroupLayout verwendet und enthält eine WatchListPanel extends JPanel. Die WatchListPanel verwendet eine null LayoutManager und enthält mehrere Instanzen von WatchItemPanel extends JPanel. Die WatchItemPanel legt seinen Inhalt mit einem GridBagLayout.

Wenn ich den Rahmen einlegen und die WatchPanel instanziiert, ich die WatchListPanel mit drei WatchItemPanel Instanzen mit Daten vorab laden. Diese arbeiten gut. Meine Implementierung ermöglicht diese durch Ziehen und Ablegen (daher das null Layouts) neu geordnet werden, und das funktioniert auch. Auf der WatchPanel ist eine Schaltfläche, um eine neue Uhr fügen, die bis eine neue Platte in ihrer eigenen JFrame erscheint, wo eine Uhr hinzugefügt werden kann. Wenn die Schaltfläche „Speichern“ auf dieser neuen Platte gedrückt wird, fügt es die neue Uhr auf die WatchPanel, die in den WatchListPanel rieselt nach unten und schließt die JFrame für eine neue Uhr hinzufügen.

Das Problem ist, dass, wenn dieser neue WatchItemPanel hinzugefügt wird, ist es nicht gemalt bekommen, wenn ich die JFrame die Größe des WatchPanel enthält. Ich kann damit durch Drag-and-Drop in Wechselwirkung treten. Ich kann sogar, dass bestimmte Panel ziehen - aber es ist leer. Der Moment, als ich die WatchPanel Größe ändern, es erscheint und korrekt gezeichnet.

Jetzt habe ich die setBounds Methode auf WatchListPanel zu Anruf setSize und repaint auf jedem der WatchItemPanel Instanzen in der Liste außer Kraft gesetzt, aber ich rufe setBounds und repaint auf den neuen WatchItemPanel schon, wie ich es hinzufügen. Ich habe repaint und invalidate Anrufe in jedem denkbaren Ort Denken versucht, das Hinzufügen vielleicht habe ich etwas verpasst, aber kein Glück. Ich habe absolut die WatchItemPanel zum WatchListPanel und rief setBounds, setVisible(true) und repaint auf das neue Panel hinzugefügt.

Hier sind die addWatch und updatePositions Methoden auf dem 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();
}

Und hier sind die setBounds Methoden auf 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();
    }
}

Ein weiteres Stück von Informationen hier - alle vier Tafeln gemalt werden. Ich overrode paintComponent im WatchItemPanel und System.out.println und bekam dieses Ergebnis hinzugefügt:

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=]

Was ist das extra „ungültig“ Spalte in der Platte dort? Als ich die WatchPanel die „ungültig“ die Größe weggeht. Es sieht aus wie eine zusätzliche Spalte, though. Es gibt keinen entsprechenden nicht ungültigen Wert auf den anderen Linien. (Dies ist die Standardeinstellung JPanel.toString() Ausgang mit dem Paketnamen entfernt.

War es hilfreich?

Lösung

Nach der Komponente Aufruf this.revalidate() hinzufügen. Dies bewirkt, dass der Behälter wieder das Layout seiner Komponenten zu kennzeichnen. Sobald diese Zeile Code hinzugefügt wird, es funktioniert perfekt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top