2010-07-04 81 views
10

當您不知道您將擁有多少組件,以及它們的規模有多大時,如何獲得一個體面的GUI?Swing中的可變佈局

例如,用戶輸入他們想要的文本字段的數量,以及哪些文本字段被分組到有邊框的面板中,然後程序生成這個文本字段。

我一直在使用GridLayout,但問題是,它使所有單元格具有相同的寬度和高度,當所有組件具有相同的大小時都很好,但是當我有一個文本框和一個與多個領域的邊界面板,要麼textfield伸出或面板被擠壓。

我希望所有組件具有最小尺寸,但仍然可以使用。

Example of how it is now, using GridLayout,所有字段都是正常的單行JTextFields,其中標題爲日期的面板被完全擠壓(它有三個字段),並且第一級字段是通向大的。任何人有任何指針?

回答

13

MiGLayout有很多吸引力,但BoxLayout是一種替代方案。

image

import java.awt.*; 
import java.util.List; 
import java.util.ArrayList; 
import javax.swing.*; 

public class BoxTest extends JPanel { 

    private List<JTextField> fields = new ArrayList<JTextField>(); 

    public BoxTest() { 
     this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     this.add(createPane(3, "One ", Color.red)); 
     this.add(createPane(3, "Two ", Color.green)); 
     this.add(createPane(10, "Three ", Color.blue)); 
    } 

    private JPanel createPane(int n, String s, Color c) { 
     JPanel outer = new JPanel(); 
     outer.setLayout(new BoxLayout(outer, BoxLayout.Y_AXIS)); 
     outer.setBorder(BorderFactory.createLineBorder(c, 2)); 
     for (int i = 0; i < n; i++) { 
      JPanel inner = new JPanel(); 
      inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS)); 
      JLabel label = new JLabel(s + i + ":", JLabel.RIGHT); 
      label.setPreferredSize(new Dimension(80, 32)); 
      inner.add(label); 
      JTextField tf = new JTextField("Stackoverflow!", 32); 
      inner.add(tf); 
      fields.add(tf); 
      outer.add(inner); 
     } 
     return outer; 
    } 

    private void display() { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JScrollPane jsp = new JScrollPane(this, 
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
      JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     this.validate(); 
     Dimension d = this.getPreferredSize(); 
     d.height /= 2; 
     jsp.getViewport().setPreferredSize(d); 
     jsp.getVerticalScrollBar().setUnitIncrement(
      this.getPreferredSize().height/fields.size()); 
     f.add(jsp); 
     f.pack(); 
     f.setVisible(true); 
    } 

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

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

我現在唯一的問題是,當一個框中的標籤不同時,文本框大小不同,就像http://grab.by/5gpW一樣。有沒有辦法解決這個問題,而不寫我自己的LayoutManager? – thepandaatemyface 2010-07-04 17:42:02

+0

@thepandaatemyface:我更新了示例以顯示一種方法。 – trashgod 2010-08-02 15:54:30

+0

@mKorbel使用_mot juste_:設置標籤的首選大小是一種隨意的破解。更精確的方法可能會使用[這裏]討論的技術之一找到最長的標籤(http://stackoverflow.com/questions/5979795/how-to-calculate-the-number-of-rows-and-columns-in - 每行-A-文本通吃的-AJ/5998117#5998117)。 – trashgod 2011-05-15 00:34:57

3

我會看看miglayout。它比任何內置的佈局管理器都有用得多。

3

您的總體目標 - 「可用組件大小」與「未知數」發生衝突。使數字足夠大,並且不適合任何屏幕。

如果使用JTables(單元格可以編輯)與JScrollPanel相結合,可能會更好。 如果您希望/必須保持生成組件的方法,請將包含組件的整個JPanel放入JScrollPane中,這樣組件就不會被嚴重擠壓。

1

最小尺寸在AWT和Swing通常是沒有意義的。我建議添加一個面板,將最小大小委託給原始首選大小,並且可能會添加一些到新的首選大小。在GridBagLayout添加重量,你想要額外的空間去正常大小。正如Durandal提到的那樣,在頂層窗口周圍彈出滾動條會擠壓佈局或脫離屏幕(我正在使用Netbook寫這篇文章,所以我知道窗口大於屏幕)。