歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java Swing 垂直流布局管理器實現

Java Swing 垂直流布局管理器實現

日期:2017/3/1 10:15:18   编辑:Linux編程

最近寫一個java UI,需要用到垂直流布局管理器,要求該管理器能夠實現內部組件的寬度自適應。看了swing提供的5個布局管理器,嘗試的實現效果都不理想,看來只能自己搞一個了,好在網上已有實現,其測試效果如下圖:

圖一 垂直流布局管理器實現效果

具體代碼如下:

清單一:

  1. import java.awt.Component;
  2. import java.awt.Container;
  3. import java.awt.Dimension;
  4. import java.awt.FlowLayout;
  5. import java.awt.Insets;
  6. import javax.swing.JButton;
  7. import javax.swing.JFrame;
  8. /**
  9. * VerticalFlowLayout is similar to FlowLayout except it lays out components
  10. * vertically. Extends FlowLayout because it mimics much of the behavior of the
  11. * FlowLayout class, except vertically. An additional feature is that you can
  12. * specify a fill to edge flag, which causes the VerticalFlowLayout manager to
  13. * resize all components to expand to the column width Warning: This causes
  14. * problems when the main panel has less space that it needs and it seems to
  15. * prohibit multi-column output. Additionally there is a vertical fill flag,
  16. * which fills the last component to the remaining height of the container.
  17. */
  18. public class VFlowLayout extends FlowLayout
  19. {
  20. /**
  21. *
  22. */
  23. private static final long serialVersionUID = 1L;
  24. /**
  25. * Specify alignment top.
  26. */
  27. public static final int TOP = 0;
  28. /**
  29. * Specify a middle alignment.
  30. */
  31. public static final int MIDDLE = 1;
  32. /**
  33. * Specify the alignment to be bottom.
  34. */
  35. public static final int BOTTOM = 2;
  36. int hgap;
  37. int vgap;
  38. boolean hfill;
  39. boolean vfill;
  40. public static void main(String[] args)
  41. {
  42. System.out.println("Just for test ...");
  43. JFrame frame = new JFrame();
  44. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  45. frame.setBounds(0, 0, 600, 600);
  46. frame.setLayout(new VFlowLayout());
  47. int i = 0;
  48. frame.add(new JButton(String.valueOf(i++)));
  49. frame.add(new JButton(String.valueOf(i++)));
  50. frame.add(new JButton(String.valueOf(i++)));
  51. frame.add(new JButton(String.valueOf(i++)));
  52. frame.add(new JButton(String.valueOf(i++)));
  53. frame.add(new JButton(String.valueOf(i++)));
  54. frame.add(new JButton(String.valueOf(i++)));
  55. frame.add(new JButton(String.valueOf(i++)));
  56. frame.add(new JButton(String.valueOf(i++)));
  57. frame.add(new JButton(String.valueOf(i++)));
  58. frame.add(new JButton(String.valueOf(i++)));
  59. frame.setVisible(true);
  60. }
  61. /**
  62. * Construct a new VerticalFlowLayout with a middle alignment, and the fill
  63. * to edge flag set.
  64. */
  65. public VFlowLayout()
  66. {
  67. this(TOP, 5, 5, true, false);
  68. }
  69. /**
  70. * Construct a new VerticalFlowLayout with a middle alignment.
  71. *
  72. * @param hfill
  73. * the fill to edge flag
  74. * @param vfill
  75. * the vertical fill in pixels.
  76. */
  77. public VFlowLayout(boolean hfill, boolean vfill)
  78. {
  79. this(TOP, 5, 5, hfill, vfill);
  80. }
  81. /**
  82. * Construct a new VerticalFlowLayout with a middle alignment.
  83. *
  84. * @param align
  85. * the alignment value
  86. */
  87. public VFlowLayout(int align)
  88. {
  89. this(align, 5, 5, true, false);
  90. }
  91. /**
  92. * Construct a new VerticalFlowLayout.
  93. *
  94. * @param align
  95. * the alignment value
  96. * @param hfill
  97. * the horizontalfill in pixels.
  98. * @param vfill
  99. * the vertical fill in pixels.
  100. */
  101. public VFlowLayout(int align, boolean hfill, boolean vfill)
  102. {
  103. this(align, 5, 5, hfill, vfill);
  104. }
  105. /**
  106. * Construct a new VerticalFlowLayout.
  107. *
  108. * @param align
  109. * the alignment value
  110. * @param hgap
  111. * the horizontal gap variable
  112. * @param vgap
  113. * the vertical gap variable
  114. * @param hfill
  115. * the fill to edge flag
  116. * @param vfill
  117. * true if the panel should vertically fill.
  118. */
  119. public VFlowLayout(int align, int hgap, int vgap, boolean hfill, boolean vfill)
  120. {
  121. setAlignment(align);
  122. this.hgap = hgap;
  123. this.vgap = vgap;
  124. this.hfill = hfill;
  125. this.vfill = vfill;
  126. }
  127. /**
  128. * Returns the preferred dimensions given the components in the target
  129. * container.
  130. *
  131. * @param target
  132. * the component to lay out
  133. */
  134. public Dimension preferredLayoutSize(Container target)
  135. {
  136. Dimension tarsiz = new Dimension(0, 0);
  137. for (int i = 0; i < target.getComponentCount(); i++)
  138. {
  139. Component m = target.getComponent(i);
  140. if (m.isVisible())
  141. {
  142. Dimension d = m.getPreferredSize();
  143. tarsiz.width = Math.max(tarsiz.width, d.width);
  144. if (i > 0)
  145. {
  146. tarsiz.height += hgap;
  147. }
  148. tarsiz.height += d.height;
  149. }
  150. }
  151. Insets insets = target.getInsets();
  152. tarsiz.width += insets.left + insets.right + hgap * 2;
  153. tarsiz.height += insets.top + insets.bottom + vgap * 2;
  154. return tarsiz;
  155. }
  156. /**
  157. * Returns the minimum size needed to layout the target container.
  158. *
  159. * @param target
  160. * the component to lay out.
  161. * @return the minimum layout dimension.
  162. */
  163. public Dimension minimumLayoutSize(Container target)
  164. {
  165. Dimension tarsiz = new Dimension(0, 0);
  166. for (int i = 0; i < target.getComponentCount(); i++)
  167. {
  168. Component m = target.getComponent(i);
  169. if (m.isVisible())
  170. {
  171. Dimension d = m.getMinimumSize();
  172. tarsiz.width = Math.max(tarsiz.width, d.width);
  173. if (i > 0)
  174. {
  175. tarsiz.height += vgap;
  176. }
  177. tarsiz.height += d.height;
  178. }
  179. }
  180. Insets insets = target.getInsets();
  181. tarsiz.width += insets.left + insets.right + hgap * 2;
  182. tarsiz.height += insets.top + insets.bottom + vgap * 2;
  183. return tarsiz;
  184. }
  185. /**
  186. * Set true to fill vertically.
  187. *
  188. * @param vfill
  189. * true to fill vertically.
  190. */
  191. public void setVerticalFill(boolean vfill)
  192. {
  193. this.vfill = vfill;
  194. }
  195. /**
  196. * Returns true if the layout vertically fills.
  197. *
  198. * @return true if vertically fills the layout using the specified.
  199. */
  200. public boolean getVerticalFill()
  201. {
  202. return vfill;
  203. }
  204. /**
  205. * Set to true to enable horizontally fill.
  206. *
  207. * @param hfill
  208. * true to fill horizontally.
  209. */
  210. public void setHorizontalFill(boolean hfill)
  211. {
  212. this.hfill = hfill;
  213. }
  214. /**
  215. * Returns true if the layout horizontally fills.
  216. *
  217. * @return true if horizontally fills.
  218. */
  219. public boolean getHorizontalFill()
  220. {
  221. return hfill;
  222. }
  223. /**
  224. * places the components defined by first to last within the target
  225. * container using the bounds box defined.
  226. *
  227. * @param target
  228. * the container.
  229. * @param x
  230. * the x coordinate of the area.
  231. * @param y
  232. * the y coordinate of the area.
  233. * @param width
  234. * the width of the area.
  235. * @param height
  236. * the height of the area.
  237. * @param first
  238. * the first component of the container to place.
  239. * @param last
  240. * the last component of the container to place.
  241. */
  242. private void placethem(Container target, int x, int y, int width, int height, int first, int last)
  243. {
  244. int align = getAlignment();
  245. if (align == MIDDLE)
  246. {
  247. y += height / 2;
  248. }
  249. if (align == BOTTOM)
  250. {
  251. y += height;
  252. }
  253. for (int i = first; i < last; i++)
  254. {
  255. Component m = target.getComponent(i);
  256. Dimension md = m.getSize();
  257. if (m.isVisible())
  258. {
  259. int px = x + (width - md.width) / 2;
  260. m.setLocation(px, y);
  261. y += vgap + md.height;
  262. }
  263. }
  264. }
  265. /**
  266. * Lays out the container.
  267. *
  268. * @param target
  269. * the container to lay out.
  270. */
  271. public void layoutContainer(Container target)
  272. {
  273. Insets insets = target.getInsets();
  274. int maxheight = target.getSize().height - (insets.top + insets.bottom + vgap * 2);
  275. int maxwidth = target.getSize().width - (insets.left + insets.right + hgap * 2);
  276. int numcomp = target.getComponentCount();
  277. int x = insets.left + hgap, y = 0;
  278. int colw = 0, start = 0;
  279. for (int i = 0; i < numcomp; i++)
  280. {
  281. Component m = target.getComponent(i);
  282. if (m.isVisible())
  283. {
  284. Dimension d = m.getPreferredSize();
  285. // fit last component to remaining height
  286. if ((this.vfill) && (i == (numcomp - 1)))
  287. {
  288. d.height = Math.max((maxheight - y), m.getPreferredSize().height);
  289. }
  290. // fit component size to container width
  291. if (this.hfill)
  292. {
  293. m.setSize(maxwidth, d.height);
  294. d.width = maxwidth;
  295. }
  296. else
  297. {
  298. m.setSize(d.width, d.height);
  299. }
  300. if (y + d.height > maxheight)
  301. {
  302. placethem(target, x, insets.top + vgap, colw, maxheight - y, start, i);
  303. y = d.height;
  304. x += hgap + colw;
  305. colw = d.width;
  306. start = i;
  307. }
  308. else
  309. {
  310. if (y > 0)
  311. {
  312. y += vgap;
  313. }
  314. y += d.height;
  315. colw = Math.max(colw, d.width);
  316. }
  317. }
  318. }
  319. placethem(target, x, insets.top + vgap, colw, maxheight - y, start, numcomp);
  320. }
  321. }
Copyright © Linux教程網 All Rights Reserved