2011-12-20 10 views
7

come posso restituisce correttamente XxxSize da JComponent (s) aggiunto al JLabelCome ritorna XxxSize da JComponent (s) aggiunto al JLabel

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

enter image description here

secondo. figura >>added some PreferredSize to the JLabel

enter image description here

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

enter image description here

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

enter image description here

avviso SICE si impiega Nimbus L & F, stessa uscita è lì per tutti L accessibile & F

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<Icon> iconQueue = new LinkedList<Icon>(); 

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

+1 Buona domanda, ma perché rendere 'buttonPanel' a' JLabel'? – trashgod

+1

@trashgod perché 1) non è possibile impostare Opacità o Traslucenza per tutti i Look and Feels, ad esempio utilizzando Nimbus richiesto un altro Woodoo per questo, 2) Ho visto un bel popup basato su JLabel – mKorbel

+0

mentre tecnicamente possibile, è semplicemente sbagliato usare un JLabel come contenitore ... – kleopatra

risposta

7

La taglia preferito predefinito è di utilizzare il layout gestore per determinare la dimensione preferita di un componente. Ciò significa che il gestore di layout esegue iterazioni su tutti i componenti figlio per determinare la dimensione preferita di ciascuno. Per un JPanel, che deve essere utilizzato come contenitore, viene utilizzato questo calcolo.

Tuttavia, per altri componenti Swing, il metodo getPreferredSize() viene sempre sovrascritto per fornire una dimensione ragionevole per il componente specificato.

Nel caso di una JLabel, il calcolo della dimensione preferita tiene conto del testo e dell'icona utilizzata. Dal momento che non hai fornito la dimensione preferita è zero. Ovviamente se si esegue l'override manuale di questo calcolo utilizzando il metodo setPreferredSize(), il componente avrà una dimensione preferita.

Quindi, anche se Swing consente di aggiungere componenti a qualsiasi componente e utilizzare un gestore di layout per il layout dei componenti figlio, questi componenti figlio non vengono utilizzati nel calcolo della dimensione preferita.

Questo non è solo un problema Nimbus.

+3

+1 per far luce sulla natura della dimensione preferita. – trashgod