Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

494
LINES

< > BotCompany Repo | #2000434 // #635 converted to Java

New Tinybrain snippet

1  
import java.net.*;
2  
import java.io.*;
3  
import javax.swing.*;
4  
import java.util.regex.*;
5  
import java.util.*;
6  
7  
import java.awt.*;
8  
import java.util.List;
9  
10  
public class main {
11  
  public static void main(String[] args) {
12  
    JFrame frame = new JFrame("A JavaX Frame");
13  
    
14  
15  
    JPanel panel = new JPanel(new GridLayout(2, 1));
16  
    
17  
    final JTextArea textArea = new JTextArea();
18  
    panel.add(new JScrollPane(textArea));
19  
    
20  
    JButton btnBla = new JButton("Bla");
21  
    panel.add(new CenteredLine(btnBla));
22  
    
23  
    
24  
    frame.add(panel);
25  
    frame.setBounds(100, 100, 500, 400);
26  
    frame.setVisible(true);
27  
    exitOnFrameClose(frame);
28  
  }
29  
30  
  static void exitOnFrameClose(JFrame frame) {
31  
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
32  
  }
33  
34  
}
35  
class CenteredLine extends JPanel {
36  
  public CenteredLine(Component... components) {
37  
    setLayout(LetterLayout.centeredRow());
38  
    for (Component component : components)
39  
      add(component);
40  
  }
41  
42  
  public void add(String text) {
43  
    add(new JLabel(text));
44  
  }
45  
}
46  
class LetterLayout implements LayoutManager {
47  
  private String[] lines;
48  
  private Map<String, Component> map = new TreeMap<String, Component>();
49  
  private RC[] rows;
50  
  private RC[] cols;
51  
  private Cell[][] cells;
52  
  private int spacingX = 10, spacingY = 10;
53  
  private int insetTop, insetBottom, insetLeft, insetRight;
54  
  private int template;
55  
  private boolean formWideLeftSide, formWideRightSide;
56  
57  
  private static final int STALACTITE = 1, LEFT_ALIGNED_ROW = 2, CENTERED_ROW = 3, FORM = 4, RIGHT_ALIGNED_ROW = 5;
58  
  private boolean debug;
59  
60  
  public void setLeftBorder(int border) {
61  
    insetLeft = border;
62  
  }
63  
64  
  public void setRightBorder(int border) {
65  
    insetRight = border;
66  
  }
67  
68  
  public static JComponent withBorder(JComponent component, int border) {
69  
    JPanel panel = new JPanel(new LetterLayout("C").setBorder(border));
70  
    panel.add("C", component);
71  
    return panel;
72  
  }
73  
74  
  public static JPanel panel(String... lines) {
75  
    return new JPanel(new LetterLayout(lines));
76  
  }
77  
78  
  public static JPanel stalactitePanel() {
79  
    return new JPanel(stalactite());
80  
  }
81  
82  
  static class DummyComponent extends JComponent {
83  
  }
84  
85  
  /**
86  
   * info about one matrix cell
87  
   */
88  
  static class Cell {
89  
    boolean aux; // part of a larger cell, but not top-left corner
90  
    int minWidth, minHeight;
91  
    Component component;
92  
    int colspan, rowspan;
93  
    double weightX, weightY;
94  
  }
95  
96  
  /**
97  
   * info about one matrix row / column
98  
   */
99  
  static class RC {
100  
    int min;
101  
    double weightSum;
102  
    int start;
103  
    int minEnd;
104  
  }
105  
106  
  private LetterLayout(int template) {
107  
    this.template = template;
108  
  }
109  
110  
  public LetterLayout(String... lines) {
111  
    this.lines = lines;
112  
  }
113  
114  
  public void removeLayoutComponent(Component component) {
115  
    map.values().remove(component);
116  
  }
117  
118  
  public void layoutContainer(Container container) {
119  
    prepareLayout(container);
120  
121  
    // do layout
122  
123  
    if (debug)
124  
      System.out.println("Container size: " + container.getSize());
125  
126  
    Insets insets = getInsets(container);
127  
    for (int r = 0; r < rows.length; r++) {
128  
      for (int i = 0; i < cols.length;) {
129  
        Cell cell = cells[i][r];
130  
        if (cell.aux)
131  
          ++i;
132  
        else {
133  
          if (cell.component != null) {
134  
            int x1 = cols[i].start;
135  
            int y1 = rows[r].start;
136  
            int x2 = i + cell.colspan < cols.length ? cols[i + cell.colspan].start - spacingX : container.getWidth() - insets.right;
137  
            int y2 = r + cell.rowspan < rows.length ? rows[r + cell.rowspan].start - spacingY : container.getHeight() - insets.bottom;
138  
139  
            if (debug)
140  
              System.out.println("Layouting ("+i+", "+r+", " + cell.component.getClass().getName() + "): "+x1+" "+y1+" "+x2+" "+y2);
141  
142  
            cell.component.setBounds(x1, y1, x2 - x1, y2 - y1);
143  
          }
144  
          i += cells[i][r].colspan;
145  
        }
146  
      }
147  
    }
148  
  }
149  
150  
  private void prepareLayout(Container container) {
151  
    applyTemplate(container);
152  
153  
    int numRows = lines.length, numCols = lines[0].length();
154  
    for (int i = 1; i < numRows; i++) if (lines[i].length() != numCols)
155  
      throw new IllegalArgumentException("Lines have varying length");
156  
    cells = new Cell[numCols][numRows];
157  
    rows = new RC[numRows];
158  
    cols = new RC[numCols];
159  
160  
    for (int r = 0; r < numRows; r++) rows[r] = new RC();
161  
    for (int i = 0; i < numCols; i++) cols[i] = new RC();
162  
    for (int r = 0; r < numRows; r++) for (int i = 0; i < numCols; i++) cells[i][r] = new Cell();
163  
164  
    // define cells
165  
166  
    for (int r = 0; r < numRows; r++) {
167  
      String line = lines[r];
168  
      for (int i = 0; i < numCols;) {
169  
        Cell cell = cells[i][r];
170  
        if (cell.aux) {
171  
          ++i;
172  
          continue;
173  
        }
174  
        char ch = line.charAt(i);
175  
        int iNext = i;
176  
        do ++iNext; while (iNext < numCols && ch == line.charAt(iNext));
177  
        int rNext = r;
178  
        do ++rNext; while (rNext < numRows && ch == lines[rNext].charAt(i));
179  
180  
        cell.weightX = numCols == 1 || iNext > i + 1 ? 1.0 : 0.0;
181  
        cell.weightY = numRows == 1 || rNext > r + 1 ? 1.0 : 0.0;
182  
183  
        Component c = map.get(String.valueOf(ch));
184  
        cell.component = c;
185  
        if (c != null) {
186  
          cell.minWidth = c.getMinimumSize().width + spacingX;
187  
          cell.minHeight = getMinimumHeight(c) + spacingY;
188  
        }
189  
        cell.colspan = iNext - i;
190  
        cell.rowspan = rNext - r;
191  
192  
        if (cell.colspan == 1)
193  
          cols[i].min = Math.max(cols[i].min, cell.minWidth);
194  
        if (cell.rowspan == 1)
195  
          rows[r].min = Math.max(rows[r].min, cell.minHeight);
196  
197  
        for (int r2 = r; r2 < rNext; r2++)
198  
          for (int i2 = i; i2 < iNext; i2++)
199  
            if (r2 != r || i2 != i)
200  
              cells[i2][r2].aux = true;
201  
202  
        i = iNext;
203  
      }
204  
    }
205  
206  
    // determine minStarts, weightSums
207  
208  
    while (true) {
209  
      for (int i = 0; i < numCols; i++) {
210  
        int minStart = i == 0 ? 0 : cols[i - 1].minEnd;
211  
        double weightStart = i == 0 ? 0.0 : cols[i - 1].weightSum;
212  
        for (int r = 0; r < numRows; r++) {
213  
          Cell cell = cells[i][r];
214  
          if (!cell.aux) {
215  
            RC rc = cols[i + cell.colspan - 1];
216  
            rc.minEnd = Math.max(rc.minEnd, minStart + cell.minWidth);
217  
            rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightX);
218  
          }
219  
        }
220  
      }
221  
222  
      for (int r = 0; r < numRows; r++) {
223  
        int minStart = r == 0 ? 0 : rows[r - 1].minEnd;
224  
        double weightStart = r == 0 ? 0.0 : rows[r - 1].weightSum;
225  
        for (int i = 0; i < numCols; i++) {
226  
          Cell cell = cells[i][r];
227  
          if (!cell.aux) {
228  
            RC rc = rows[r + cell.rowspan - 1];
229  
            rc.minEnd = Math.max(rc.minEnd, minStart + cell.minHeight);
230  
            rc.weightSum = Math.max(rc.weightSum, weightStart + cell.weightY);
231  
          }
232  
        }
233  
      }
234  
235  
      if (allWeightsZero(cols)) {
236  
        for (int r = 0; r < numRows; r++)
237  
          for (int i = 0; i < numCols; i++)
238  
            cells[i][r].weightX = 1.0;
239  
        continue;
240  
      }
241  
242  
      if (allWeightsZero(rows)) {
243  
        for (int r = 0; r < numRows; r++)
244  
          for (int i = 0; i < numCols; i++)
245  
            cells[i][r].weightY = 1.0;
246  
        continue;
247  
      }
248  
249  
      break;
250  
    }
251  
252  
    // determine row, col starts
253  
254  
    Insets insets = getInsets(container);
255  
    determineStarts(cols, insets.left, container.getWidth() - insets.left - insets.right + spacingX, spacingX);
256  
    determineStarts(rows, insets.top, container.getHeight() - insets.top - insets.bottom + spacingY, spacingY);
257  
  }
258  
259  
  private boolean allWeightsZero(RC[] rcs) {
260  
    for (int i = 0; i < rcs.length; i++)
261  
      if (rcs[i].weightSum != 0.0)
262  
        return false;
263  
    return true;
264  
  }
265  
266  
  private static int getMinimumHeight(Component c) {
267  
    /*if (c instanceof JTextArea) {
268  
      return (int) ((JTextArea) c).getUI().getRootView((JTextArea) c).getPreferredSpan(javax.swing.text.View.Y_AXIS);
269  
    }*/
270  
    return c.getMinimumSize().height;
271  
  }
272  
273  
  private void applyTemplate(Container container) {
274  
    if (template == STALACTITE) {
275  
      Component[] components = container.getComponents();
276  
277  
      lines = new String[components.length + 2];
278  
      map.clear();
279  
      for (int i = 0; i < components.length; i++) {
280  
        String s = String.valueOf(makeIndexChar(i));
281  
        map.put(s, components[i]);
282  
        lines[i] = s;
283  
      }
284  
      lines[components.length] = lines[components.length + 1] = " ";
285  
    } else if (template == FORM) {
286  
      /* old method of calculating numRows:
287  
      int numRows = 0;
288  
      for (String key : map.keySet()) {
289  
        if (key.length() == 1)
290  
          numRows = Math.max(numRows, Character.toLowerCase(key.charAt(0))-'a');
291  
      }*/
292  
      Component[] components = container.getComponents();
293  
      int numRows = components.length/2;
294  
295  
      lines = new String[numRows+2];
296  
      map.clear();
297  
      for (int row = 0; row < numRows; row++) {
298  
        String lower = String.valueOf(makeIndexChar(row));
299  
        String upper = String.valueOf(makeAlternateIndexChar(row));
300  
        Component rightComponent = components[row * 2 + 1];
301  
        if (rightComponent instanceof DummyComponent)
302  
          upper = lower;
303  
        lines[row] = (formWideLeftSide ? lower + lower : lower) + (formWideRightSide ? upper + upper : upper);
304  
        map.put(lower, components[row*2]);
305  
        if (!(rightComponent instanceof DummyComponent))
306  
          map.put(upper, rightComponent);
307  
      }
308  
      lines[numRows] = lines[numRows+1] = (formWideLeftSide ? "  " : " ") + (formWideRightSide ? "  " : " ");
309  
    } else if (template == LEFT_ALIGNED_ROW) {
310  
      lines = new String[] { makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR };
311  
    } else if (template == CENTERED_ROW) {
312  
      lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) + RIGHT_CHAR + RIGHT_CHAR };
313  
    } else if (template == RIGHT_ALIGNED_ROW) {
314  
      lines = new String[] { "" + LEFT_CHAR + LEFT_CHAR + makeSingleRow(container) };
315  
    }
316  
  }
317  
318  
  private String makeSingleRow(Container container) {
319  
    Component[] components = container.getComponents();
320  
    StringBuffer buf = new StringBuffer();
321  
    map.clear();
322  
    for (int i = 0; i < components.length; i++) {
323  
      String s = String.valueOf(makeAlternateIndexChar(i));
324  
      map.put(s, components[i]);
325  
      buf.append(s);
326  
    }
327  
    return buf.toString();
328  
  }
329  
330  
  private static void determineStarts(RC[] rcs, int start, int totalSize, int spacing) {
331  
    int minTotal = rcs[rcs.length - 1].minEnd;
332  
    double weightSum = rcs[rcs.length - 1].weightSum;
333  
    //System.out.println("totalSize="+totalSize+",minTotal="+minTotal+",weightSum="+weightSum);
334  
    int spare = (int) ((totalSize - minTotal) / (weightSum == 0.0 ? 1.0 : weightSum));
335  
    int x = start, minSum = 0;
336  
    double prevWeightSum = 0.0;
337  
    for (int i = 0; i < rcs.length; i++) {
338  
      int width = rcs[i].minEnd - minSum + (int) ((rcs[i].weightSum - prevWeightSum) * spare) - spacing;
339  
      //System.out.println("i="+i+",prevws="+prevWeightSum+",ws="+rcs[i].weightSum+",min="+rcs[i].min+",width="+width);
340  
      rcs[i].start = x;
341  
      x += width + spacing;
342  
      prevWeightSum = rcs[i].weightSum;
343  
      minSum = rcs[i].minEnd;
344  
    }
345  
  }
346  
347  
  public void addLayoutComponent(String s, Component component) {
348  
    map.put(s, component);
349  
  }
350  
351  
  public Dimension minimumLayoutSize(Container container) {
352  
    prepareLayout(container);
353  
    Insets insets = getInsets(container);
354  
    Dimension result = new Dimension(
355  
      insets.left + cols[cols.length - 1].minEnd + insets.right - spacingX,
356  
      insets.top + rows[rows.length - 1].minEnd + insets.bottom - spacingY);
357  
    return result;
358  
  }
359  
360  
  private Insets getInsets(Container container) {
361  
    Insets insets = container.getInsets();
362  
    return new Insets(insets.top + insetTop,
363  
      insets.left + insetLeft,
364  
      insets.bottom + insetBottom,
365  
      insets.right + insetRight);
366  
  }
367  
368  
  public Dimension preferredLayoutSize(Container container) {
369  
    return minimumLayoutSize(container);
370  
  }
371  
372  
  public LetterLayout setSpacing(int x, int y) {
373  
    spacingX = x;
374  
    spacingY = y;
375  
    return this;
376  
  }
377  
378  
  public LetterLayout setSpacing(int spacing) {
379  
    return setSpacing(spacing, spacing);
380  
  }
381  
382  
  public LetterLayout setBorder(int top, int left, int bottom, int right) {
383  
    insetTop = top;
384  
    insetLeft = left;
385  
    insetBottom = bottom;
386  
    insetRight = right;
387  
    return this;
388  
  }
389  
390  
  public LetterLayout setBorder(int inset) {
391  
    return setBorder(inset, inset, inset, inset);
392  
  }
393  
394  
  public LetterLayout setTopBorder(int inset) {
395  
    insetTop = inset;
396  
    return this;
397  
  }
398  
399  
  /**
400  
   * layout components from top to bottom; add components without letters!
401  
   */
402  
  public static LetterLayout stalactite() {
403  
    return new LetterLayout(STALACTITE);
404  
  }
405  
406  
  /**
407  
   * layout components from left to right; add components without letters!
408  
   */
409  
  public static LetterLayout leftAlignedRow() {
410  
    return new LetterLayout(LEFT_ALIGNED_ROW);
411  
  }
412  
413  
  public static LetterLayout leftAlignedRow(int spacing) {
414  
    return leftAlignedRow().setSpacing(spacing);
415  
  }
416  
417  
  /**
418  
   * layout components from left to right, center in container; add components without letters!
419  
   */
420  
  public static LetterLayout centeredRow() {
421  
    return new LetterLayout(CENTERED_ROW);
422  
  }
423  
424  
  public static LetterLayout rightAlignedRow() {
425  
    return new LetterLayout(RIGHT_ALIGNED_ROW);
426  
  }
427  
428  
  public static JPanel rightAlignedRowPanel(JComponent... components) {
429  
    return makePanel(new LetterLayout(RIGHT_ALIGNED_ROW), components);
430  
  }
431  
432  
  private static JPanel makePanel(LetterLayout letterLayout, JComponent[] components) {
433  
    JPanel panel = new JPanel(letterLayout);
434  
    for (JComponent component : components) {
435  
      panel.add(component);
436  
    }
437  
    return panel;
438  
  }
439  
440  
  /**
441  
   * layout components from top to bottom; two components per row
442  
   */
443  
  public static LetterLayout form() {
444  
    LetterLayout letterLayout = new LetterLayout(FORM);
445  
    letterLayout.formWideLeftSide = true;
446  
    letterLayout.formWideRightSide = true;
447  
    return letterLayout;
448  
  }
449  
450  
  /**
451  
   * layout components from top to bottom; two components per row
452  
   * left column is small, right column is wide
453  
   */
454  
  public static LetterLayout formWideRightSide() {
455  
    LetterLayout letterLayout = new LetterLayout(FORM);
456  
    letterLayout.formWideRightSide = true;
457  
    return letterLayout;
458  
  }
459  
460  
  public static Component getDummyComponent() {
461  
    return new DummyComponent();
462  
  }
463  
464  
  public static JPanel newPanel(String... lines) {
465  
    return new JPanel(new LetterLayout(lines));
466  
  }
467  
468  
  public boolean isDebug() {
469  
    return debug;
470  
  }
471  
472  
  public void setDebug(boolean debug) {
473  
    this.debug = debug;
474  
  }
475  
476  
  public static char makeIndexChar(int idx) {
477  
    return (char) ('a' + idx*2);
478  
  }
479  
480  
  public static char makeAlternateIndexChar(int idx) {
481  
    return (char) ('b' + idx*2);
482  
  }
483  
484  
  public static char LEFT_CHAR = ',', RIGHT_CHAR = '.';
485  
486  
  public static void main(String[] args) {
487  
    System.out.println((int) makeIndexChar(0));
488  
    System.out.println((int) makeAlternateIndexChar(0));
489  
    System.out.println((int) makeIndexChar(32000));
490  
    System.out.println((int) makeAlternateIndexChar(32000));
491  
    System.out.println((int) LEFT_CHAR);
492  
    System.out.println((int) RIGHT_CHAR);
493  
  }
494  
}

Author comment

Began life as a copy of #2000433

download  show line numbers   

Snippet is not live.

Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

Comments [hide]

ID Author/Program Comment Date
904 #1000604 (pitcher) 2015-08-20 15:28:24
898 #1000610 (pitcher) 2015-08-18 00:07:07

add comment

Snippet ID: #2000434
Snippet name: #635 converted to Java
Eternal ID of this version: #2000434/1
Text MD5: ce68a58fe0490d509ae666c4b08ff61d
Author: stefan
Category:
Type: New Tinybrain snippet
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-07-05 13:24:53
Source code size: 15634 bytes / 494 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 926 / 188
Referenced in: [show references]