2011-12-20 21 views
7

我怎麼能正確地從JComponent的(一個或多個)返回XxxSize加入JLabel的如何從JComponent中返回XxxSize(S)加入到JLabel的

1日。圖>>lets LayoutManager works like as for JPanel, JLabel returns Size(0, 0)

enter image description here

第二。圖>>added some PreferredSize to the JLabel

enter image description here

第三名。圖>>calculated PreferredSize from JComponent(s) added to the JLabel

enter image description here

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

enter image description here

通知SICE有用於雨雲大號&女,相同的輸出是有所有入店大號&˚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好問題,但爲什麼'buttonPanel'是'JLabel'呢? – trashgod 2011-12-20 13:01:04

+1

@trashgod因爲1)不可能設置不透明度或半透明所有知道外觀和使用感覺,例如雨雲需要另外Woodoo的是,2)我看到了基於JLabel的 – mKorbel 2011-12-20 13:04:48

+0

不錯的彈出式工廠,而技術上是可行的,這是簡單的錯誤使用JLabel作爲容器... – kleopatra 2011-12-20 14:26:19

回答

7

默認優選尺寸計算是使用佈局經理來確定組件的首選大小。這意味着佈局管理器遍歷所有子組件來確定每個子組件的首選大小。對於打算用作容器的JPanel,將使用此計算。

然而,對於其它擺動部件,所述的getPreferredSize()方法是總是重寫,以給定組件提供一個合理的規模。

在一個JLabel的情況下,優選的大小計算考慮文本和所用的圖標。由於您沒有提供首選大小爲零。當然,如果你使用setPreferredSize()方法手動覆蓋這個計算,那麼這個組件將有一個首選大小。

所以,即使搖擺允許你將組件添加到任何組件,並使用佈局管理器來佈局子組件,這些子組件沒有在首選大小計算中使用。

這不僅僅是一個Nimbus問題。

+3

+ 1爲脫穎而出的首選大小的性質。 – trashgod 2011-12-20 17:59:21