您的位置:首页 > 编程语言 > Java开发

java swing 垂直流布局管理器实现

2016-04-05 21:34 381 查看
最近写一个java UI,需要用到垂直流布局管理器,要求该管理器能够实现内部组件的宽度自适应。看了swing提供的5个布局管理器,尝试的实现效果都不理想,看来只能自己搞一个了,好在网上已有实现,其测试效果如下图:

图一 垂直流布局管理器实现效果



具体代码如下:

清单一:

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;

/**
* VerticalFlowLayout is similar to FlowLayout except it lays out components
* vertically. Extends FlowLayout because it mimics much of the behavior of the
* FlowLayout class, except vertically. An additional feature is that you can
* specify a fill to edge flag, which causes the VerticalFlowLayout manager to
* resize all components to expand to the column width Warning: This causes
* problems when the main panel has less space that it needs and it seems to
* prohibit multi-column output. Additionally there is a vertical fill flag,
* which fills the last component to the remaining height of the container.
*/
public class VFlowLayout extends FlowLayout
{
/**
*
*/
private static final long serialVersionUID = 1L;

/**
* Specify alignment top.
*/
public static final int TOP = 0;

/**
* Specify a middle alignment.
*/
public static final int MIDDLE = 1;

/**
* Specify the alignment to be bottom.
*/
public static final int BOTTOM = 2;

int hgap;
int vgap;
boolean hfill;
boolean vfill;

public static void main(String[] args)
{
System.out.println("Just for test ...");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 600, 600);
frame.setLayout(new VFlowLayout());

int i = 0;
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));
frame.add(new JButton(String.valueOf(i++)));

frame.setVisible(true);
}

/**
* Construct a new VerticalFlowLayout with a middle alignment, and the fill
* to edge flag set.
*/
public VFlowLayout()
{
this(TOP, 5, 5, true, false);
}

/**
* Construct a new VerticalFlowLayout with a middle alignment.
*
* @param hfill
*            the fill to edge flag
* @param vfill
*            the vertical fill in pixels.
*/
public VFlowLayout(boolean hfill, boolean vfill)
{
this(TOP, 5, 5, hfill, vfill);
}

/**
* Construct a new VerticalFlowLayout with a middle alignment.
*
* @param align
*            the alignment value
*/
public VFlowLayout(int align)
{
this(align, 5, 5, true, false);
}

/**
* Construct a new VerticalFlowLayout.
*
* @param align
*            the alignment value
* @param hfill
*            the horizontalfill in pixels.
* @param vfill
*            the vertical fill in pixels.
*/
public VFlowLayout(int align, boolean hfill, boolean vfill)
{
this(align, 5, 5, hfill, vfill);
}

/**
* Construct a new VerticalFlowLayout.
*
* @param align
*            the alignment value
* @param hgap
*            the horizontal gap variable
* @param vgap
*            the vertical gap variable
* @param hfill
*            the fill to edge flag
* @param vfill
*            true if the panel should vertically fill.
*/
public VFlowLayout(int align, int hgap, int vgap, boolean hfill, boolean vfill)
{
setAlignment(align);
this.hgap = hgap;
this.vgap = vgap;
this.hfill = hfill;
this.vfill = vfill;
}

/**
* Returns the preferred dimensions given the components in the target
* container.
*
* @param target
*            the component to lay out
*/
public Dimension preferredLayoutSize(Container target)
{
Dimension tarsiz = new Dimension(0, 0);

for (int i = 0; i < target.getComponentCount(); i++)
{
Component m = target.getComponent(i);

if (m.isVisible())
{
Dimension d = m.getPreferredSize();
tarsiz.width = Math.max(tarsiz.width, d.width);

if (i > 0)
{
tarsiz.height += hgap;
}

tarsiz.height += d.height;
}
}

Insets insets = target.getInsets();
tarsiz.width += insets.left + insets.right + hgap * 2;
tarsiz.height += insets.top + insets.bottom + vgap * 2;

return tarsiz;
}

/**
* Returns the minimum size needed to layout the target container.
*
* @param target
*            the component to lay out.
* @return the minimum layout dimension.
*/
public Dimension minimumLayoutSize(Container target)
{
Dimension tarsiz = new Dimension(0, 0);

for (int i = 0; i < target.getComponentCount(); i++)
{
Component m = target.getComponent(i);

if (m.isVisible())
{
Dimension d = m.getMinimumSize();
tarsiz.width = Math.max(tarsiz.width, d.width);

if (i > 0)
{
tarsiz.height += vgap;
}

tarsiz.height += d.height;
}
}

Insets insets = target.getInsets();
tarsiz.width += insets.left + insets.right + hgap * 2;
tarsiz.height += insets.top + insets.bottom + vgap * 2;

return tarsiz;
}

/**
* Set true to fill vertically.
*
* @param vfill
*            true to fill vertically.
*/
public void setVerticalFill(boolean vfill)
{
this.vfill = vfill;
}

/**
* Returns true if the layout vertically fills.
*
* @return true if vertically fills the layout using the specified.
*/
public boolean getVerticalFill()
{
return vfill;
}

/**
* Set to true to enable horizontally fill.
*
* @param hfill
*            true to fill horizontally.
*/
public void setHorizontalFill(boolean hfill)
{
this.hfill = hfill;
}

/**
* Returns true if the layout horizontally fills.
*
* @return true if horizontally fills.
*/
public boolean getHorizontalFill()
{
return hfill;
}

/**
* places the components defined by first to last within the target
* container using the bounds box defined.
*
* @param target
*            the container.
* @param x
*            the x coordinate of the area.
* @param y
*            the y coordinate of the area.
* @param width
*            the width of the area.
* @param height
*            the height of the area.
* @param first
*            the first component of the container to place.
* @param last
*            the last component of the container to place.
*/
private void placethem(Container target, int x, int y, int width, int height, int first, int last)
{
int align = getAlignment();

if (align == MIDDLE)
{
y += height / 2;
}

if (align == BOTTOM)
{
y += height;
}

for (int i = first; i < last; i++)
{
Component m = target.getComponent(i);
Dimension md = m.getSize();

if (m.isVisible())
{
int px = x + (width - md.width) / 2;
m.setLocation(px, y);
y += vgap + md.height;
}
}
}

/**
* Lays out the container.
*
* @param target
*            the container to lay out.
*/
public void layoutContainer(Container target)
{
Insets insets = target.getInsets();
int maxheight = target.getSize().height	- (insets.top + insets.bottom + vgap * 2);
int maxwidth = target.getSize().width - (insets.left + insets.right + hgap * 2);
int numcomp = target.getComponentCount();
int x = insets.left + hgap, y = 0;
int colw = 0, start = 0;

for (int i = 0; i < numcomp; i++)
{
Component m = target.getComponent(i);

if (m.isVisible())
{
Dimension d = m.getPreferredSize();

// fit last component to remaining height
if ((this.vfill) && (i == (numcomp - 1)))
{
d.height = Math.max((maxheight - y), m.getPreferredSize().height);
}

// fit component size to container width
if (this.hfill)
{
m.setSize(maxwidth, d.height);
d.width = maxwidth;
}
else
{
m.setSize(d.width, d.height);
}

if (y + d.height > maxheight)
{
placethem(target, x, insets.top + vgap, colw, maxheight - y, start, i);
y = d.height;
x += hgap + colw;
colw = d.width;
start = i;
}
else
{
if (y > 0)
{
y += vgap;
}

y += d.height;
colw = Math.max(colw, d.width);
}
}
}

placethem(target, x, insets.top + vgap, colw, maxheight - y, start,	numcomp);
}
}
文章转自:http://blog.csdn.net/dancen/article/details/7581971
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: