自定义 JPanel 大小始终为 0

Custom JPanel size always 0

长期以来我一直试图了解这里发生的事情,但我还没有找到正确的答案。

我正在尝试从头开始创建 JPanel;为此,我定义了一个组布局,然后相应地插入了相应的组件。

问题是,一旦组件被插入,以及它们定义的尺寸,JPanel 将两个尺寸(宽度和高度)都保持为零值。即使在屏幕上显示(没有错误)。

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

}

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

Swing 组件默认可见,顶级容器除外。

正如我在评论中所述,面板由布局管理器指定大小。

如果您要动态地将面板添加到视口中的面板,那么基本逻辑是:

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

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

invokeLater() 将代码添加到 EDT 的末尾,以便它可以在完成布局并计算所有尺寸值后执行。