2011-12-13 91 views
9

我使用GroupLayout來管理某些動態生成的數據輸入表單中的組件。佈局或多或少像這樣:Swing GroupLayout:調整大小並限制組件大小

*-----------------------------------------------* 
| label A  | field A      | 
| label B  | field B      | 
| label C  | field C      | 
*-----------------------------------------------* 

我使用用於水平佈局2個平行組,以及用於垂直佈局的單個順序組。大多數情況下,一切都很好。

我想將標籤的最大寬度(僅爲JLabel的實例)限制爲父項的寬度的三分之一JFrame。如果JFrame是固定大小,這將是微不足道的,但我必須處理它被調整大小。

我從JFrame中挑選ComponentListener.componentResized()事件,但是我一旦遇到這樣的事件,我有點被困在做什麼。

我試過這個方法沒有任何的運氣:

public void componentResized(ComponentEvent e) { 
    int maxW = parentFrame.getWidth()/3; 
    for (JLabel l : labels) { 
     l.setMaximumSize(// have also tried setSize() and setPreferredSize() 
      new Dimension(
       Math.min(l.getSize().width, maxW), 
       l.getMaximumSize().height)); 
    } 
    groupLayout.invalidateLayout(getContentSpace()); 
} 

任何人都可以提出一個方法來限制將工作標籤的寬度是多少?

我可能每次都可以從頭重新構建佈局,但我覺得應該有一個更簡單的方法。

+0

永遠不要setXXSize:http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi – kleopatra

+0

標籤的尺寸是否大於最大標籤的首選尺寸? – trashgod

+0

@trashgod不,沒有。我想設置標籤寬度的上限,而不是最小限制。編輯了這個問題,使其更清晰。 – vaughandroid

回答

27

在此示例中,GroupLayout可以簡單地依賴於標籤的首選大小,而不必訴諸於任何setXXXSize()方法。在這種方法中,

  • 標籤的空間總是容納最大的標籤。
  • 可以用有用的方式調整文本字段的大小。
  • 跨平臺和字體的結果是正確的。
  • 「你並不需要指定大部分組件的任何東西......因爲組件本身具有所需的調整行爲的默認。」 - How to Use GroupLayout: Component Size and Resizability

採用GroupLayout.Alignment.TRAILING右對齊的標籤是個人首選項,我添加了第二個面板來顯示它如何嵌套在另一個佈局中。

enter image description here

import java.awt.EventQueue; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.GroupLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

/** @see http://stackoverflow.com/questions/8492065 */ 
public class GroupPanel extends JPanel { 

    private JLabel label1 = new JLabel("Primary:"); 
    private JTextField field1 = new JTextField(16); 
    private JLabel label2 = new JLabel("Secondary:"); 
    private JTextField field2 = new JTextField(16); 
    private JLabel label3 = new JLabel("Tertiary:"); 
    private JTextField field3 = new JTextField(16); 

    public GroupPanel(int n) { 
     this.setBorder(BorderFactory.createTitledBorder("Panel " + n)); 
     GroupLayout layout = new GroupLayout(this);   
     this.setLayout(layout); 
     layout.setAutoCreateGaps(true); 
     layout.setAutoCreateContainerGaps(true); 
     layout.setHorizontalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) 
       .addComponent(label1) 
       .addComponent(label2) 
       .addComponent(label3)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 
       .addComponent(field1) 
       .addComponent(field2) 
       .addComponent(field3)) 
     ); 
     layout.setVerticalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label1) 
       .addComponent(field1)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label2) 
       .addComponent(field2)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label3) 
       .addComponent(field3)) 
     ); 
    } 

    private static void display() { 
     JFrame f = new JFrame("GroupPanel"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS)); 
     f.add(new GroupPanel(1)); 
     f.add(new GroupPanel(2)); 
     f.add(Box.createVerticalGlue()); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       display(); 
      } 
     }); 
    } 
} 
+0

這是一個非常明確的例子,所以非常感謝。您提供的代碼與我自己已經實現的代碼幾乎完全相同,但關鍵點是「您不需要爲大多數組件指定任何內容......因爲組件本身具有默認的所需調整大小行爲。 」。我想我的標籤需要是覆蓋getPreferredSize()的自定義實現。 – vaughandroid

+0

優秀;另請參閱此(不太靈活)[示例](http://stackoverflow.com/a/3175280/230513)。 – trashgod

+1

另請參閱此(_more_ flexible)[示例](http://stackoverflow.com/a/14858272/230513)。 – trashgod

相關問題