¿Por qué desaparece el primer panel agregado a un marco?

A continuación se muestra un ejemplo de cómo agregar dos paneles a un marco. Solo aparece un panel (el 2 °, panel rojo).

Panel que desaparece en el marco

¿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)); } } 

  • El diseño predeterminado de un JFrame (o más específicamente en este caso, el panel de contenido del marco) es un BorderLayout .
  • Al agregar un componente a BordeLayout sin restricciones, la API de Swing colocará el componente en el CENTER .
  • Un BorderLayout puede contener exactamente un componente en cada una de las 5 restricciones de diseño.
  • 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.

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:

  1. Haga clic en el botón “Agregar panel en el centro”, nada parece suceder a pesar de que el panel azul se agregó al centro.
  2. Mueva el mouse sobre el panel rojo y los botones aparecerán porque la lógica del rollover del mouse hará que los botones sean repintados.
  3. Ahora aumente el ancho del cuadro y aparecerá el panel azul debajo del panel rojo.

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:

  1. pack() el marco después de agregar el panel verde al marco.
  2. ejecutar el código y boost el ancho del marco y el marco rojo y verde aparecerá
  3. luego haga clic en el botón y aumente el ancho y ahora aparecerán los 3 paneles

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.

Intereting Posts