2013-04-01 20 views
2

爲什麼getPreferredSize()得到下面的示例中,只調用時pack()被調用兩次在JFrame,如:的getPreferredSize()只包()後調用兩次

public class PackTest { 
    static JFrame f = new JFrame(); 
    @SuppressWarnings("serial") 
    public static void main(String[] args) { 
     f.add(new JPanel() { 
      int i = 0; 
      @Override 
      public Dimension getPreferredSize() { 
       System.out.println("getPreferredSize() called"); 
       if(i++ >= 2) 
        return new Dimension(200, 200); // This is never returned 
       else 
        return new Dimension(100, 100); 
      } 
     }); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.setVisible(true); 
     for(int i = 0; i < 10; i++) { 
      try { 
       TimeUnit.SECONDS.sleep(1); 
      } catch(InterruptedException e) {} 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        System.out.println("Calling pack()"); 
        f.pack(); 
       } 
      }); 
     } 
    } 
} 

似乎getPreferredSize()只被稱爲長因爲它不斷返回一些不同的東西(例如,如果它每次都返回一個不同的維度,在這個例子中它會被調用10次)。爲什麼Swing會這樣做,以及如何讓pack()正確調整JFrame

回答

2

嘗試重新確認您的JPanel得到它調用它的首選大小:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class PackTest { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 

    public static void createAndShowGui() { 
     final JFrame f = new JFrame(); 
     final JPanel panel = new JPanel() { 
     int i = 0; 

     @Override 
     public Dimension getPreferredSize() { 
      System.out.println("getPreferredSize() called"); 
      if (i++ >= 2) 
       return new Dimension(200, 200); // This is never returned 
      else 
       return new Dimension(100, 100); 
     } 
     }; 
     f.add(panel); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.setVisible(true); 

     int delay = 1000; 
     new Timer(delay, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      System.out.println("Calling pack()"); 
      panel.revalidate(); 
      f.pack(); 
     } 
     }).start(); 
    } 
} 

順便說一句,你要確保你真正的代碼,你含辛茹苦地尊重Swing線程規則。

2

getPreferredSize()總是在父容器調整大小或重新驗證時調用。無論此方法返回的值是多少,它都會對組件(如果重寫)強制執行固定大小,而不管窗口和其他組件的大小如何都不應更改。

+0

'pack()'在這個例子中被調用了10次,但'getPreferredSize()'只被調用了兩次。 – user21760

相關問題