java swing jframe layout-manager border-layout

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



swing jframe (2)

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 es estrictamente cierto.

BorderLayout solo reset the bounds (es decir, el tamaño y la ubicación) del último componente agregado a una ubicación de restricción específica. Esto es diferente de otros administradores de diseño 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 el marco fue validado utilizando el método pack () y, por lo tanto, solo se estableció 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", parece que no sucede nada a pesar de que el panel azul se agregó al centro.
  2. Mueva el mouse sobre el panel rojo y aparecerán los botones porque la lógica de desplazamiento del mouse hará que los botones se vuelvan a pintar.
  3. Ahora aumente el ancho del marco y el panel azul aparecerá 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 el 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 encima del 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 marco, el panel azul es el panel "activo" en BorderLayout.CENTER , tiene sus límites ajustados, por lo que ahora ocupará el espacio adicional en el marco.

Ahora para otra prueba:

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

La conclusión es la misma:

No intente agregar varios paneles a la misma restricción de un BorderLayout. Si lo hace, asegúrese de eliminar el panel anterior o tiene el potencial de obtener resultados inesperados.

A continuación se muestra un ejemplo de agregar dos paneles a un marco. Solo aparece un panel (el segundo 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)); } }


  • 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 un BordeLayout sin restricción, la API 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.