A continuación se muestra un ejemplo de cómo agregar dos paneles a un marco. Solo aparece un panel (el 2 °, panel rojo).
¿Por qué desaparece el primer panel?
import java.awt.*; import javax.swing.*; import javax.swing.border.EmptyBorder; public class DisappearingPanelInFrame { DisappearingPanelInFrame() { JFrame f = new JFrame(this.getClass().getSimpleName()); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.add(new ColoredPanel(Color.GREEN)); f.add(new ColoredPanel(Color.RED)); f.pack(); f.setVisible(true); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new DisappearingPanelInFrame(); } }; SwingUtilities.invokeLater(r); } } class ColoredPanel extends JPanel { ColoredPanel(Color color) { setBackground(color); setBorder(new EmptyBorder(20, 150, 20, 150)); } }
JFrame
(o más específicamente en este caso, el panel de contenido del marco) es un BorderLayout
. BordeLayout
sin restricciones, la API de Swing colocará el componente en el CENTER
. BorderLayout
puede contener exactamente un componente en cada una de las 5 restricciones de diseño. CENTER
) de un BorderLayout
, esta implementación de Java mostrará el último componente agregado. En cuanto a lo que sería un mejor enfoque depende de las necesidades específicas de la interfaz de usuario.
Cuando se agrega un segundo componente a la misma restricción (en este caso CENTER) de un BorderLayout, esta implementación de Java mostrará el último componente agregado.
No estrictamente cierto.
BorderLayout
solo reset the bounds
(es decir, tamaño y ubicación) del último componente agregado a una ubicación de restricción específica. Esto es diferente de otros administradores de disposición en que restablecerán los límites de todos los componentes en el contenedor.
En el código de ejemplo, el panel rojo era el panel “activo” en el momento en que se validó el marco utilizando el método pack () y, por lo tanto, solo se definió su límite y, por lo tanto, solo se pintó.
Para una demostración de este proceso, ejecute el siguiente ejemplo utilizando los siguientes pasos:
El código:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.EmptyBorder; public class DisappearingPanelInFrame { DisappearingPanelInFrame() { JButton button = new JButton ("Add Panel In Center"); button.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JPanel blue = new JPanel(); blue.setBackground( Color.BLUE ); blue.add( new JButton("Button 1") ); blue.add( new JButton("Button 2") ); Component c = (Component)e.getSource(); Window window = SwingUtilities.windowForComponent(c); window.add(blue ); window.revalidate(); window.repaint(); } }); JFrame f = new JFrame(this.getClass().getSimpleName()); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); f.add(new ColoredPanel(Color.GREEN)); //f.pack(); f.add(new ColoredPanel(Color.RED)); f.add(button, BorderLayout.SOUTH); f.pack(); f.setVisible(true); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new DisappearingPanelInFrame(); } }; SwingUtilities.invokeLater(r); } } class ColoredPanel extends JPanel { ColoredPanel(Color color) { setBackground(color); setBorder(new EmptyBorder(20, 150, 20, 150)); } }
Cuando el panel azul se agrega a BorderLayout y cuando se invoca la revalidate()
se establecen los límites del panel azul.
Sin embargo, debido a la forma en que Swing pinta ZOrder, el panel azul se pinta primero y luego el panel rojo se pinta sobre el panel azul. El panel verde todavía tiene un tamaño de (0, 0) ya que nunca fue el panel “activo” en BorderLayout.CENTER
cuando el marco se validó inicialmente con el método pack ().
Cuando se cambia el tamaño del recuadro, el panel azul es el panel “activo” en BorderLayout.CENTER
, se han ajustado sus límites, por lo que ahora se llenará el espacio adicional en el marco.
Ahora para otra prueba:
pack()
el marco después de agregar el panel verde al marco. En resumen, sigue siendo el mismo:
No intente agregar varios paneles a la misma restricción de un BorderLayout. Si lo hace, asegúrese de quitar el panel anterior o puede generar resultados inesperados.