将容器的布局设置为null(无LayoutManager)时,可以使用component.setBounds(x,y,w,h)分别设置组件的边界。
*在所有情况下, *固定的版式都会 导致 UI设计不良
(在99%的情况下)(例如,如果您的标签没有得到其首选的尺寸,则当您的应用程序支持多种语言时,您会遇到市长问题),所以
我的建议是写一个专业的布局经理可以满足您的特定需求 。
编写自定义布局管理器非常容易,您所要做的就是能够计算具有给定组件和布局的容器的首选大小,并通过设置组件的(计算出的)边界来进行布局。我摆脱了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条)