1 | !7 |
2 | |
3 | sclass GriddishLayout implements LayoutManager { |
4 | int rows, cols; |
5 | private Map<String, Component> map = new TreeMap<String, Component>(); |
6 | private int spacingX = 10, spacingY = 10; |
7 | private int insetTop, insetBottom, insetLeft, insetRight; |
8 | |
9 | boolean debug; |
10 | |
11 | *() {} |
12 | *(int *rows, int *cols) {} |
13 | |
14 | public void removeLayoutComponent(Component component) { |
15 | map.values().remove(component); |
16 | } |
17 | |
18 | public void layoutContainer(Container container) { |
19 | prepareLayout(container); |
20 | |
21 | // do layout |
22 | |
23 | if (debug) |
24 | System.out.println("Container size: " + container.getSize()); |
25 | |
26 | Insets insets = getInsets(container); |
27 | for (int r = 0; r < rows.length; r++) { |
28 | for (int i = 0; i < cols.length;) { |
29 | Cell cell = cells[i][r]; |
30 | if (cell.aux) |
31 | ++i; |
32 | else { |
33 | if (cell.component != null) { |
34 | int x1 = cols[i].start; |
35 | int y1 = rows[r].start; |
36 | int x2 = i + cell.colspan < cols.length ? cols[i + cell.colspan].start - spacingX : container.getWidth() - insets.right; |
37 | int y2 = r + cell.rowspan < rows.length ? rows[r + cell.rowspan].start - spacingY : container.getHeight() - insets.bottom; |
38 | |
39 | if (debug) |
40 | System.out.println("Layouting ("+i+", "+r+", " + cell.component.getClass().getName() + "): "+x1+" "+y1+" "+x2+" "+y2); |
41 | |
42 | cell.component.setBounds(x1, y1, x2 - x1, y2 - y1); |
43 | } |
44 | i += cells[i][r].colspan; |
45 | } |
46 | } |
47 | } |
48 | } |
49 | |
50 | private void prepareLayout(Container container) { |
51 | int numRows = lines.length, numCols = lines[0].length(); |
52 | for (int i = 1; i < numRows; i++) if (lines[i].length() != numCols) |
53 | throw new IllegalArgumentException("Lines have varying length"); |
54 | cells = new Cell[numCols][numRows]; |
55 | rows = new RC[numRows]; |
56 | cols = new RC[numCols]; |
57 | |
58 | for (int r = 0; r < numRows; r++) rows[r] = new RC(); |
59 | for (int i = 0; i < numCols; i++) cols[i] = new RC(); |
60 | for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r] = new Cell(); |
61 | |
62 | // define cells |
63 | |
64 | for (int r = 0; r < numRows; r++) { |
65 | String line = lines[r]; |
66 | for (int i = 0; i < numCols;) { |
67 | Cell cell = cells[i][r]; |
68 | if (cell.aux) { |
69 | ++i; |
70 | continue; |
71 | } |
72 | char ch = line.charAt(i); |
73 | int iNext = i; |
74 | do ++iNext; while (iNext < numCols && ch == line.charAt(iNext)); |
75 | int rNext = r; |
76 | do ++rNext; while (rNext < numRows && ch == lines[rNext].charAt(i)); |
77 | |
78 | cell.weightX = numCols == 1 || iNext > i + 1 ? 1.0 : 0.0; |
79 | cell.weightY = numRows == 1 || rNext > r + 1 ? 1.0 : 0.0; |
80 | |
81 | Component c = map.get(String.valueOf(ch)); |
82 | cell.component = c; |
83 | if (c != null) { |
84 | cell.minWidth = c.getMinimumSize().width + spacingX; |
85 | cell.minHeight = getMinimumHeight(c) + spacingY; |
86 | } |
87 | cell.colspan = iNext - i; |
88 | cell.rowspan = rNext - r; |
89 | |
90 | if (cell.colspan == 1) |
91 | cols[i].min = Math.max(cols[i].min, cell.minWidth); |
92 | if (cell.rowspan == 1) |
93 | rows[r].min = Math.max(rows[r].min, cell.minHeight); |
94 | |
95 | for (int r2 = r; r2 < rNext; r2++) |
96 | for (int i2 = i; i2 < iNext; i2++) |
97 | if (r2 != r || i2 != i) |
98 | cells[i2][r2].aux = true; |
99 | |
100 | i = iNext; |
101 | } |
102 | } |
103 | |
104 | // determine minStarts, weightSums |
105 | |
106 | while (true) { |
107 | for (int i = 0; i < numCols; i++) { |
108 | int minStart = i == 0 ? 0 : cols[i - 1].minEnd; |
109 | double weightStart = i == 0 ? 0.0 : cols[i - 1].weightSum; |
110 | for (int r = 0; r < numRows; r++) { |
111 | Cell cell = cells[i][r]; |
112 | if (!cell.aux) { |
113 | RC rc = cols[i + cell.colspan - 1]; |
114 | rc.minEnd = Math.max(rc.minEnd, minStart + cell.minWidth); |
115 | rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightX); |
116 | } |
117 | } |
118 | } |
119 | |
120 | for (int r = 0; r < numRows; r++) { |
121 | int minStart = r == 0 ? 0 : rows[r - 1].minEnd; |
122 | double weightStart = r == 0 ? 0.0 : rows[r - 1].weightSum; |
123 | for (int i = 0; i < numCols; i++) { |
124 | Cell cell = cells[i][r]; |
125 | if (!cell.aux) { |
126 | RC rc = rows[r + cell.rowspan - 1]; |
127 | rc.minEnd = Math.max(rc.minEnd, minStart + cell.minHeight); |
128 | rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightY); |
129 | } |
130 | } |
131 | } |
132 | |
133 | if (allWeightsZero(cols)) { |
134 | for (int r = 0; r < numRows; r++) |
135 | for (int i = 0; i < numCols; i++) |
136 | cells[i][r].weightX = 1.0; |
137 | continue; |
138 | } |
139 | |
140 | if (allWeightsZero(rows)) { |
141 | for (int r = 0; r < numRows; r++) |
142 | for (int i = 0; i < numCols; i++) |
143 | cells[i][r].weightY = 1.0; |
144 | continue; |
145 | } |
146 | |
147 | break; |
148 | } |
149 | |
150 | // determine row, col starts |
151 | |
152 | Insets insets = getInsets(container); |
153 | determineStarts(cols, insets.left, container.getWidth() - insets.left - insets.right + spacingX, spacingX); |
154 | determineStarts(rows, insets.top, container.getHeight() - insets.top - insets.bottom + spacingY, spacingY); |
155 | } |
156 | |
157 | private static int getMinimumHeight(Component c) { |
158 | /*if (c instanceof JTextArea) { |
159 | return (int) ((JTextArea) c).getUI().getRootView((JTextArea) c).getPreferredSpan(javax.swing.text.View.Y_AXIS); |
160 | }*/ |
161 | return c.getMinimumSize().height; |
162 | } |
163 | |
164 | private void applyTemplate(Container container) { |
165 | if (template == STALACTITE) { |
166 | Component[] components = container.getComponents(); |
167 | |
168 | lines = new String[components.length + 2]; |
169 | map.clear(); |
170 | for (int i = 0; i < components.length; i++) { |
171 | String s = String.valueOf(makeIndexChar(i)); |
172 | map.put(s, components[i]); |
173 | lines[i] = s; |
174 | } |
175 | lines[components.length] = lines[components.length + 1] = " "; |
176 | } else if (template == FORM) { |
177 | /* old method of calculating numRows: |
178 | int numRows = 0; |
179 | for (String key : map.keySet()) { |
180 | if (key.length() == 1) |
181 | numRows = Math.max(numRows, Character.toLowerCase(key.charAt(0))-'a'); |
182 | }*/ |
183 | Component[] components = container.getComponents(); |
184 | int numRows = components.length/2; |
185 | |
186 | lines = new String[numRows+2]; |
187 | map.clear(); |
188 | for (int row = 0; row < numRows; row++) { |
189 | String lower = String.valueOf(makeIndexChar(row)); |
190 | String upper = String.valueOf(makeAlternateIndexChar(row)); |
191 | Component rightComponent = components[row * 2 + 1]; |
192 | if (rightComponent instanceof DummyComponent) |
193 | upper = lower; |
194 | lines[row] = (formWideLeftSide ? lower + lower : lower) + (formWideRightSide ? upper + upper : upper); |
195 | map.put(lower, components[row*2]); |
196 | if (!(rightComponent instanceof DummyComponent)) |
197 | map.put(upper, rightComponent); |
198 | } |
199 | lines[numRows] = lines[numRows+1] = (formWideLeftSide ? " " : " ") + (formWideRightSide ? " " : " "); |
200 | } else if (template == LEFT_ALIGNED_ROW) { |
201 | lines = new String[] { makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; |
202 | } else if (template == CENTERED_ROW) { |
203 | lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR }; |
204 | } else if (template == RIGHT_ALIGNED_ROW) { |
205 | lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) }; |
206 | } |
207 | } |
208 | |
209 | private String makeSingleRow(Container container) { |
210 | Component[] components = container.getComponents(); |
211 | StringBuffer buf = new StringBuffer(); |
212 | map.clear(); |
213 | for (int i = 0; i < components.length; i++) { |
214 | String s = String.valueOf(makeAlternateIndexChar(i)); |
215 | map.put(s, components[i]); |
216 | buf.append(s); |
217 | } |
218 | return buf.toString(); |
219 | } |
220 | |
221 | private static void determineStarts(RC[] rcs, int start, int totalSize, int spacing) { |
222 | int minTotal = rcs[rcs.length - 1].minEnd; |
223 | double weightSum = rcs[rcs.length - 1].weightSum; |
224 | //System.out.println("totalSize="+totalSize+",minTotal="+minTotal+",weightSum="+weightSum); |
225 | int spare = (int) ((totalSize - minTotal) / (weightSum == 0.0 ? 1.0 : weightSum)); |
226 | int x = start, minSum = 0; |
227 | double prevWeightSum = 0.0; |
228 | for (int i = 0; i < rcs.length; i++) { |
229 | int width = rcs[i].minEnd - minSum + (int) ((rcs[i].weightSum - prevWeightSum) * spare) - spacing; |
230 | //System.out.println("i="+i+",prevws="+prevWeightSum+",ws="+rcs[i].weightSum+",min="+rcs[i].min+",width="+width); |
231 | rcs[i].start = x; |
232 | x += width + spacing; |
233 | prevWeightSum = rcs[i].weightSum; |
234 | minSum = rcs[i].minEnd; |
235 | } |
236 | } |
237 | |
238 | public void addLayoutComponent(String s, Component component) { |
239 | map.put(s, component); |
240 | } |
241 | |
242 | public Dimension minimumLayoutSize(Container container) { |
243 | prepareLayout(container); |
244 | Insets insets = getInsets(container); |
245 | Dimension result = new Dimension( |
246 | insets.left + cols[cols.length - 1].minEnd + insets.right - spacingX, |
247 | insets.top + rows[rows.length - 1].minEnd + insets.bottom - spacingY); |
248 | return result; |
249 | } |
250 | |
251 | private Insets getInsets(Container container) { |
252 | Insets insets = container.getInsets(); |
253 | return new Insets(insets.top + insetTop, |
254 | insets.left + insetLeft, |
255 | insets.bottom + insetBottom, |
256 | insets.right + insetRight); |
257 | } |
258 | |
259 | public Dimension preferredLayoutSize(Container container) { |
260 | return minimumLayoutSize(container); |
261 | } |
262 | |
263 | public LetterLayout setSpacing(int x, int y) { |
264 | spacingX = x; |
265 | spacingY = y; |
266 | return this; |
267 | } |
268 | |
269 | public LetterLayout setSpacing(int spacing) { |
270 | return setSpacing(spacing, spacing); |
271 | } |
272 | |
273 | public LetterLayout setBorder(int top, int left, int bottom, int right) { |
274 | insetTop = top; |
275 | insetLeft = left; |
276 | insetBottom = bottom; |
277 | insetRight = right; |
278 | return this; |
279 | } |
280 | |
281 | public LetterLayout setBorder(int inset) { |
282 | return setBorder(inset, inset, inset, inset); |
283 | } |
284 | |
285 | public LetterLayout setTopBorder(int inset) { |
286 | insetTop = inset; |
287 | return this; |
288 | } |
289 | |
290 | public static Component getDummyComponent() { |
291 | return new DummyComponent(); |
292 | } |
293 | |
294 | public static JPanel newPanel(String... lines) { |
295 | return new JPanel(new LetterLayout(lines)); |
296 | } |
297 | } |
Began life as a copy of #1004152
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1008584 |
Snippet name: | GriddishLayout [dev.] |
Eternal ID of this version: | #1008584/1 |
Text MD5: | 3906e6f7264e5b0804212384f274a194 |
Author: | stefan |
Category: | javax / gui |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2017-05-24 18:08:43 |
Source code size: | 10419 bytes / 297 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 466 / 479 |
Referenced in: | [show references] |