2009-02-06 69 views
2

是否有任何類型的Java到XY佈局?XY佈局JAVA

所以我可以在X和Y座標上設置一個按鈕,並且假設它是那個大等......因爲這個邊界佈局和網格和麪板的東西讓我瘋狂。 :)

他們流淌着每一個人,並得到強化。而爲了讓他們少你必須把面板面板在面板^^面板,

回答

6

將容器佈局設置爲null(無LayoutManager)時,可以使用component.setBounds(x,y,w,h)單獨設置組件的邊界。

固定佈局在所有情況下,99%壞UI設計(如果你的標籤,例如,沒有得到他們的首選大小您遇到的問題市長時,你的應用程序支持多國語言),所以我對你的建議是爲你的特定需求寫一個專門的佈局管理器。

編寫自定義佈局管理器非常簡單,您只需要計算具有給定組件和佈局的容器的首選大小,並通過設置(計算的)你的組件。 我擺脫了GridBagLayout,並開始編寫我自己的佈局很久以前,佈局從未如此簡單。

這裏有一個自定義佈局,該佈局對鍵和值組件的一個例子:

public class KeyValueLayout implements LayoutManager { 

    public static enum KeyAlignment { 
     LEFT, RIGHT; 
    } 

    private KeyAlignment keyAlignment = KeyAlignment.LEFT; 

    private int hgap; 

    private int vgap; 

    public KeyValueLayout() { 
     this(KeyAlignment.LEFT); 
    } 

    public KeyValueLayout (KeyAlignment keyAlignment) { 
     this(keyAlignment, 5, 5); 
    } 

    public KeyValueLayout (int hgap, int vgap) { 
     this(KeyAlignment.LEFT, hgap, vgap); 
    } 

    public KeyValueLayout (KeyAlignment keyAlignment, int hgap, int vgap) { 

     this.keyAlignment = keyAlignment != null ? keyAlignment : KeyAlignment.LEFT; 
     this.hgap = hgap; 
     this.vgap = vgap; 
    } 

    public void addLayoutComponent (String name, Component comp) { 
    } 

    public void addLayoutComponent (Component comp, Object constraints) { 
    } 

    public void removeLayoutComponent (Component comp) { 
    } 

    public void layoutContainer (Container parent) { 
     Rectangle canvas = getLayoutCanvas(parent); 
     int ypos = canvas.y; 
     int preferredKeyWidth = getPreferredKeyWidth(parent); 

     for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) { 
      Component key = (Component) iter.next(); 
      Component value = iter.hasNext() ? (Component) iter.next() : null; 
      int xpos = canvas.x; 
      int preferredHeight = Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0); 

      if (keyAlignment == KeyAlignment.LEFT) 
       key.setBounds(xpos, ypos, key.getPreferredSize().width, key.getPreferredSize().height); 
      else 
       key.setBounds(xpos + preferredKeyWidth - key.getPreferredSize().width, ypos, key.getPreferredSize().width, 
        key.getPreferredSize().height); 

      xpos += preferredKeyWidth + hgap; 
      if (value != null) 
       value.setBounds(xpos, ypos, canvas.x + canvas.width - xpos, preferredHeight); 
      ypos += preferredHeight + vgap; 
     } 
    } 

    public Dimension minimumLayoutSize (Container parent) { 
     int preferredKeyWidth = getPreferredKeyWidth(parent); 
     int minimumValueWidth = 0; 
     int minimumHeight = 0; 
     int lines = 0; 
     for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) { 
      lines++; 
      Component key = (Component) iter.next(); 
      Component value = iter.hasNext() ? (Component) iter.next() : null; 
      minimumHeight += Math.max(key.getPreferredSize().height, value != null ? value.getMinimumSize().height : 0); 
      minimumValueWidth = Math.max(minimumValueWidth, value != null ? value.getMinimumSize().width : 0); 
     } 

     Insets insets = parent.getInsets(); 
     int minimumWidth = insets.left + preferredKeyWidth + hgap + minimumValueWidth + insets.right; 
     minimumHeight += insets.top + insets.bottom; 
     if (lines > 0) 
      minimumHeight += (lines - 1) * vgap; 

     return new Dimension(minimumWidth, minimumHeight); 
    } 

    public Dimension preferredLayoutSize (Container parent) { 
     int preferredKeyWidth = getPreferredKeyWidth(parent); 
     int preferredValueWidth = 0; 
     int preferredHeight = 0; 
     int lines = 0; 
     for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) { 
      lines++; 
      Component key = (Component) iter.next(); 
      Component value = iter.hasNext() ? (Component) iter.next() : null; 

      preferredHeight += Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0); 
      preferredValueWidth = Math.max(preferredValueWidth, value != null ? value.getPreferredSize().width : 0); 
     } 

     Insets insets = parent.getInsets(); 
     int preferredWidth = insets.left + preferredKeyWidth + hgap + preferredValueWidth + insets.right; 
     preferredHeight += insets.top + insets.bottom; 
     if (lines > 0) 
      preferredHeight += (lines - 1) * vgap; 

     return new Dimension(preferredWidth, preferredHeight); 
    } 

    public Dimension maximumLayoutSize (Container target) { 
     return preferredLayoutSize(target); 
    } 

    private int getPreferredKeyWidth (Container parent) { 
     int preferredWidth = 0; 
     for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) { 
      Component key = (Component) iter.next(); 
      if (iter.hasNext()) 
       iter.next(); 

      preferredWidth = Math.max(preferredWidth, key.getPreferredSize().width); 
     } 

     return preferredWidth; 
    } 

    private Rectangle getLayoutCanvas (Container parent) { 
     Insets insets = parent.getInsets(); 
     int x = insets.left; 
     int y = insets.top; 

     int width = parent.getSize().width - insets.left - insets.right; 
     int height = parent.getSize().height - insets.top - insets.bottom; 

     return new Rectangle(x, y, width, height); 
    } 

    private class ComponentIterator implements Iterator<Component> { 

     private Container container; 

     private int index = 0; 

     public ComponentIterator (Container container) { 
      this.container = container; 
     } 

     public boolean hasNext() { 
      return index < container.getComponentCount(); 
     } 

     public Component next() { 
      return container.getComponent(index++); 
     } 

     public void remove() { 
     } 
    } 
} 

剛剛成立的佈局,並添加交替標籤和值部件。它很容易使用,特別是與GridBagLayout或具有自定義佈局的嵌套面板相比。

+0

你的答案很好,但我認爲這與實際問題無關(關於XYLayout)。 – SaadBen 2013-08-05 22:59:45

2

如果你真的想這樣做,你把東西放到組件上使用

setLayout(null); 

,然後使用

setBounds(x, y, width, height); 

設置元素的絕對座標。例如:

setLayout(null); 
JButton myButton = new JButton("Do Stuff"); 
add(myButton); 
myButton.setBounds(30, 30, 100, 30); 

然而,由此產生GUI會顯得不規範,將不會調整大小,如果它是任何複雜的,將是一個痛苦的維持。

我知道佈局是件令人沮喪的事情,但最終你會更好地使用BorderLayouts和FlowLayouts或者GridBagLayout的組合 - 或者像Eclipse或Netbeans這樣的IDE接口構建器。

3

組件調整大小的原因是,無論窗口的大小如何,東西看起來都很漂亮,所以Swing不鼓勵直的X-Y位置。您可能需要查看爲GUI構建器設計的GroupLayout http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html,並且上面提到的頁面描述了使用不可見組件來吸收拉伸。例如:layout.setAutoCreateGaps(true);

SpringLayout中也可能是有用的 - 看到visual guide

如果你真的想要的X和Y然後設置佈局管理器爲null,並使用setLocation()或的setBounds()。我真的真的不會推薦這個,但它確實有效。閱讀this tutorial

1

這並不回答你的具體問題,但同意其他意見,看看MiG Layout。作爲一個Swing新手,我也同樣對佈局感到沮喪,但這對我有很大的幫助。