Como retorna o XxxSize do JComponent (s) adicionado ao JLabel

Como posso devolver corretamente XxxSize de JComponent (s) adicionados ao JLabel

1º figura >> lets LayoutManager works like as for JPanel, JLabel returns Size(0, 0)

insira a descrição da imagem aqui

2º figura >> added some PreferredSize to the JLabel

insira a descrição da imagem aqui

3ª figura >> calculated PreferredSize from JComponent(s) added to the JLabel

insira a descrição da imagem aqui

4º figura >> lets LayoutManager works changed JLabel to JPanel, now LayoutManager correctly calculated Dimension without using any XxxSize

insira a descrição da imagem aqui

aviso sice lá é usado Nimbus L & F, mesma saída está lá para todos os L & F acessível

 import java.awt.*; import java.awt.event.*; import java.util.LinkedList; import java.util.Queue; import javax.swing.*; public class NimbusBorderPainterDemo extends JFrame { private static final long serialVersionUID = 1L; private JFrame frame = new JFrame(); private JPanel fatherPanel = new JPanel(), titlePanel = new JPanel(); private JLabel buttonPanel = new JLabel(); //figure ---> 4th. switch JLabel with JPanel //private JPanel buttonPanel = new JPanel(); private Queue iconQueue = new LinkedList(); public NimbusBorderPainterDemo() { iconQueue.add(UIManager.getIcon("OptionPane.errorIcon")); iconQueue.add(UIManager.getIcon("OptionPane.informationIcon")); iconQueue.add(UIManager.getIcon("OptionPane.warningIcon")); JButton button0 = createButton(); JButton button1 = createButton(); JButton button2 = createButton(); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(1); } }); int gap = 5; buttonPanel.setLayout(new GridLayout(0, 3, gap, 0)); buttonPanel.add(button0); buttonPanel.add(button1); buttonPanel.add(button2); // figure 1st. ---> without PreferredSize // figure 2nd. ---> //buttonPanel.setPreferredSize(new Dimension(160, 30)); // figure 3rd. ---> /*Dimension dim = button0.getPreferredSize(); int w = dim.width; int h = dim.height; w = (w + 5) * 3; h += 4; dim = new Dimension(w, h); buttonPanel.setPreferredSize(dim);*/ titlePanel.setLayout(new BorderLayout()); titlePanel.add(new JLabel(nextIcon()), BorderLayout.WEST); titlePanel.add(new JLabel("My Frame"), BorderLayout.CENTER); titlePanel.setBorder(BorderFactory.createLineBorder(Color.GRAY)); titlePanel.add(buttonPanel, BorderLayout.EAST); fatherPanel.setLayout(new BorderLayout()); fatherPanel.add(titlePanel, BorderLayout.CENTER); frame.setUndecorated(true); frame.add(fatherPanel); frame.setLocation(50, 50); frame.pack(); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.setVisible(true); } private JButton createButton() { JButton button = new JButton(); button.setBorderPainted(false); button.setBorder(null); button.setFocusable(false); button.setMargin(new Insets(0, 0, 0, 0)); button.setContentAreaFilled(false); button.setIcon(nextIcon()); //button.setRolloverIcon(nextIcon()); //button.setPressedIcon(nextIcon()); //button.setDisabledIcon(nextIcon()); nextIcon(); return button; } private Icon nextIcon() { Icon icon = iconQueue.peek(); iconQueue.add(iconQueue.remove()); return icon; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception fail) { } UIManager.getLookAndFeelDefaults().put("nimbusFocus", Color.RED); NimbusBorderPainterDemo nimbusBorderPainterDemo = new NimbusBorderPainterDemo(); } }); } } 

O cálculo padrão de tamanho preferido é usar o gerenciador de layout para determinar o tamanho preferido de um componente. Isso significa que o gerenciador de layout repete todos os componentes filhos para determinar o tamanho preferencial de cada um. Para um JPanel, que deve ser usado como um contêiner, esse cálculo é usado.

No entanto, para outros componentes Swing, o método getPreferredSize () é sempre substituído para fornecer um tamanho razoável para o componente fornecido.

No caso de um JLabel, o cálculo de tamanho preferido leva em consideração o texto e o ícone usado. Desde que você não forneceu o tamanho preferido é zero. É claro que, se você replace manualmente esse cálculo usando o método setPreferredSize (), o componente terá um tamanho preferencial.

Portanto, embora o Swing permita adicionar componentes a qualquer componente e usar um gerenciador de layout para o layout dos componentes filhos, esses componentes filhos não são usados ​​no cálculo de tamanho preferencial.

Este não é apenas um problema do Nimbus.