Custom JPanel size always 0

I have been trying to understand what is happening here for a long time and I have not found the correct answer yet.

I am trying to create a JPanel from scratch; for this I have defined a group layout and then I have inserted the respective components accordingly.

the problem is that once the components are inserted, and also with their defined sizes, the JPanel keeps both sizes (width and height) with zero value. even after displaying it (without errors) on the screen.

public class PanelPelicula extends JPanel {

Pelicula pelicula;
JTextArea titulo;
JTextArea descripcion;
JLabel imagen;
int escalado = 40;
int escaladoX = escalado * 5;
int escaladoY = escalado * 7;

public PanelPelicula(Pelicula pelicula) {
    super();
    this.pelicula = pelicula;
    inicializar();
}

private void inicializar() {

    titulo = new JTextArea();
    descripcion = new JTextArea();
    imagen = new JLabel();

    titulo.setLineWrap(true);
    titulo.setWrapStyleWord(true);
    titulo.setOpaque(false);
    titulo.setEditable(false);
    titulo.setFont(new Font("Malgun Gothic", 1, 14));
    titulo.setForeground(new Color(255, 255, 255));
    titulo.setText(pelicula.getTitulo());

    descripcion.setLineWrap(true);
    descripcion.setWrapStyleWord(true);
    descripcion.setOpaque(false);
    descripcion.setEditable(false);
    descripcion.setFont(new Font("Malgun Gothic", 0, 14));
    descripcion.setForeground(new Color(150, 150, 150));
    String generos = "(";
    for (String genero : pelicula.getGeneros()) {
        generos += genero + ", ";
    }
    generos = generos.substring(0, generos.length() - 2) + ")";
    descripcion.setText(generos);

    imagen.setPreferredSize(new Dimension(escaladoX, escaladoY));
    imagen.setOpaque(true);
    imagen.setBackground(new Color(33, 33, 33));
    try {
        String poster = pelicula.getPoster();
        if (!poster.equals("")) {
            URL urlPoster = new URL(poster);
            ImageIcon icono = new ImageIcon(ImageIO.read(urlPoster).getScaledInstance(escaladoX, escaladoY, 2));
            imagen.setIcon(icono);
        }
    } catch (MalformedURLException ex) {
        Logger.getLogger(PanelPelicula.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(PanelPelicula.class.getName()).log(Level.SEVERE, null, ex);
    }

    this.setOpaque(false);
    GroupLayout layout = new GroupLayout(this);
    this.setLayout(layout);

    layout.setHorizontalGroup(
            layout.createParallelGroup()
                    .addComponent(imagen, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(titulo, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(descripcion, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    layout.setVerticalGroup(
            layout.createSequentialGroup()
                    .addComponent(imagen, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGap(10, 10, 10)
                    .addComponent(titulo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGap(4, 4, 4)
                    .addComponent(descripcion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addGap(10, 10, Short.MAX_VALUE)
    );

    System.out.println(getSize());
}

}

Upvotes: 0

Views: 57

Answers (1)

camickr
camickr

Reputation: 324118

once the panel is visible, it does not define its size.

Swing components are visible by default, except for top level containers.

As I stated in my comment, a panel is given a size by the layout manager.

If you are dynamically adding panels to the panel in the viewport then the basic logic is:

panel.add(...);
panel.revalidate(); // to invoke the layout manager

SwingUtilities.invokeLater( () -> 
{
    JScrollBar horizontal = scrollPane.getHorizontalScrollBar();
    horizontal.setValue( horizontal.getMaximum() );
});

The invokeLater() adds the code to the end of the EDT so it can execute AFTER the layout has been done and all size values have been calculated.

Upvotes: 1

Related Questions