Pregunta

Hay un panel en un JFrame llamado WatchPanel extends JPanel que utiliza un GroupLayout y contiene una WatchListPanel extends JPanel. El WatchListPanel utiliza un null LayoutManager y contiene varios casos de WatchItemPanel extends JPanel. El WatchItemPanel expone su contenido con un GridBagLayout.

Cuando cargo hasta el bastidor y una instancia de la WatchPanel, I pre-cargar el WatchListPanel con tres casos WatchItemPanel con datos. Estos funcionan bien. Mi aplicación permite que éstos se vuelvan a ordenar arrastrando y soltando (de ahí el diseño null), y que funciona tan bien. Por WatchPanel es un botón para añadir un nuevo reloj, lo que abrirá un nuevo panel en su propia JFrame donde se puede añadir un reloj. Cuando se pulsa el botón "Guardar" en este nuevo panel, se añade el nuevo reloj de la WatchPanel, que se escurre hacia abajo en el WatchListPanel y cierra la JFrame para añadir un nuevo reloj.

El problema es que cuando se añade este nuevo WatchItemPanel, que no consigue pintado a menos puedo cambiar el tamaño de la JFrame que contiene el WatchPanel. Puedo interactuar con él a través de arrastrar y soltar. Incluso puedo arrastrar ese panel específico - pero es en blanco. En el momento que cambie el tamaño del WatchPanel, lo que parece y se pinta correctamente.

Ahora, he anulado el método setBounds en WatchListPanel a setSize llamada y repaint en cada uno de los casos WatchItemPanel en la lista, pero estoy llamando setBounds y repaint en el nuevo WatchItemPanel como ya lo añado. He intentado agregar repaint y invalidate llamadas en cada lugar concebible pensar que tal vez haya perdido algo, pero no hubo suerte. Absolutamente añadido el WatchItemPanel a la llamada y WatchListPanel setBounds, setVisible(true) y repaint en el nuevo panel.

Aquí son los métodos addWatch y updatePositions en la 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();
}

Y aquí están los métodos setBounds en 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();
    }
}

Otra pieza de información aquí - los cuatro paneles están siendo pintado. Me hizo caso omiso de paintComponent en el WatchItemPanel y añadí un System.out.println y obtuve este resultado:

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é es esa columna extra "no válido" existe en el panel? Cuando cambio el tamaño de la WatchPanel el "no válido" desaparece. Se ve como una columna adicional, sin embargo. No hay valor no válido correspondiente en las otras líneas. (Esta es la salida JPanel.toString() defecto con el nombre del paquete eliminado.

¿Fue útil?

Solución

Después de añadir el componente, this.revalidate() llamada. Esto hace que el recipiente sea marcada para componentes re-diseño de su. Una vez que se añade esta línea de código, funciona perfectamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top