source: josm/trunk/src/org/openstreetmap/josm/tools/MultiLineFlowLayout.java@ 12790

Last change on this file since 12790 was 11294, checked in by simon04, 7 years ago

Fix http://errorprone.info/bugpattern/NarrowingCompoundAssignment

File size: 3.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.awt.Component;
5import java.awt.Container;
6import java.awt.Dimension;
7import java.awt.FlowLayout;
8import java.awt.Insets;
9import java.util.function.Function;
10
11/**
12 * This is an extension of the flow layout that preferes wrapping the text instead of increasing the component width
13 * when there is not enough space.
14 * <p>
15 * This allows for a better preffered size computation.
16 * It should be used in all places where a flow layout fills the full width of the parent container.
17 * <p>
18 * This does not support baseline alignment.
19 * @author Michael Zangl
20 * @since 10622
21 */
22public class MultiLineFlowLayout extends FlowLayout {
23 /**
24 * Same as {@link FlowLayout#FlowLayout()}
25 */
26 public MultiLineFlowLayout() {
27 super();
28 }
29
30 /**
31 * Same as {@link FlowLayout#FlowLayout(int, int, int)}
32 * @param align Alignment
33 * @param hgap horizontal gap
34 * @param vgap vertical gap
35 */
36 public MultiLineFlowLayout(int align, int hgap, int vgap) {
37 super(align, hgap, vgap);
38 }
39
40 /**
41 * Same as {@link FlowLayout#FlowLayout(int)}
42 * @param align Alignment
43 */
44 public MultiLineFlowLayout(int align) {
45 super(align);
46 }
47
48 @Override
49 public Dimension preferredLayoutSize(Container target) {
50 return getLayoutSize(target, Component::getPreferredSize);
51 }
52
53 @Override
54 public Dimension minimumLayoutSize(Container target) {
55 return getLayoutSize(target, Component::getMinimumSize);
56 }
57
58 private Dimension getLayoutSize(Container target, Function<Component, Dimension> baseSize) {
59 synchronized (target.getTreeLock()) {
60 int outerWidth = getWidthOf(target);
61
62 Insets insets = target.getInsets();
63 int containerWidth = outerWidth - insets.left - insets.right - getHgap() * 2;
64
65 int x = 0;
66 int totalHeight = insets.top + insets.bottom + getVgap() * 2;
67 int rowHeight = 0;
68 for (int i = 0; i < target.getComponentCount(); i++) {
69 Component child = target.getComponent(i);
70 if (!child.isVisible()) {
71 continue;
72 }
73 Dimension size = baseSize.apply(child);
74 if (x != 0) {
75 x += getHgap();
76 }
77 x += size.width;
78 if (x > containerWidth) {
79 totalHeight += rowHeight + getVgap();
80 rowHeight = 0;
81 x = 0;
82 }
83
84 rowHeight = Math.max(rowHeight, size.height);
85 }
86 totalHeight += rowHeight;
87
88 return new Dimension(outerWidth, totalHeight);
89 }
90 }
91
92 private static int getWidthOf(Container target) {
93 Container current = target;
94 while (current.getWidth() == 0 && current.getParent() != null) {
95 current = current.getParent();
96 }
97 int width = current.getWidth();
98 if (width == 0) {
99 return Integer.MAX_VALUE;
100 } else {
101 return width;
102 }
103 }
104
105 @Override
106 public String toString() {
107 return "MultiLineFlowLayout [align=" + getAlignment() + ']';
108 }
109}
Note: See TracBrowser for help on using the repository browser.