···71717272 public static final FlatSVGIcon REFRESH_24 = getIcon("refresh_24");
7373 public static final FlatSVGIcon REFRESH_16 = REFRESH_24.derive(16, 16);
7474+7575+ public static final FlatSVGIcon TERMINAL_24 = getIcon("terminal");
7676+ public static final FlatSVGIcon TERMINAL_16 = TERMINAL_24.derive(16, 16);
7777+7878+ public static final FlatSVGIcon FOLDER_OPEN_24 = getIcon("folder-open");
7979+ public static final FlatSVGIcon FOLDER_OPEN_16 = FOLDER_OPEN_24.derive(16, 16);
8080+8181+ public static final FlatSVGIcon PACKAGE_24 = getIcon("package");
8282+ public static final FlatSVGIcon PACKAGE_16 = PACKAGE_24.derive(16, 16);
7483}
+98
src/main/java/util/ui/WrapLayout.java
···11+package util.ui;
22+33+import java.awt.*;
44+import javax.swing.*;
55+66+/**
77+ * A FlowLayout that supports wrapping of components to new lines.
88+ * TODO: make not terrible and slow
99+ */
1010+public class WrapLayout extends FlowLayout {
1111+ public WrapLayout() {
1212+ super();
1313+ }
1414+1515+ public WrapLayout(int align) {
1616+ super(align);
1717+ }
1818+1919+ public WrapLayout(int align, int hgap, int vgap) {
2020+ super(align, hgap, vgap);
2121+ }
2222+2323+ @Override
2424+ public Dimension preferredLayoutSize(Container target) {
2525+ return layoutSize(target, true);
2626+ }
2727+2828+ @Override
2929+ public Dimension minimumLayoutSize(Container target) {
3030+ Dimension minimum = layoutSize(target, false);
3131+ minimum.width -= (getHgap() + 1);
3232+ return minimum;
3333+ }
3434+3535+ private Dimension layoutSize(Container target, boolean preferred) {
3636+ synchronized (target.getTreeLock()) {
3737+ int targetWidth = target.getSize().width;
3838+ if (targetWidth == 0) {
3939+ targetWidth = Integer.MAX_VALUE;
4040+ }
4141+4242+ int hgap = getHgap();
4343+ int vgap = getVgap();
4444+ Insets insets = target.getInsets();
4545+ int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
4646+ int maxWidth = targetWidth - horizontalInsetsAndGap;
4747+4848+ Dimension dim = new Dimension(0, 0);
4949+ int rowWidth = 0;
5050+ int rowHeight = 0;
5151+5252+ int nmembers = target.getComponentCount();
5353+5454+ for (int i = 0; i < nmembers; i++) {
5555+ Component m = target.getComponent(i);
5656+5757+ if (m.isVisible()) {
5858+ Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
5959+6060+ if (rowWidth + d.width > maxWidth && rowWidth > 0) {
6161+ addRow(dim, rowWidth, rowHeight);
6262+ rowWidth = 0;
6363+ rowHeight = 0;
6464+ }
6565+6666+ if (rowWidth != 0) {
6767+ rowWidth += hgap;
6868+ }
6969+7070+ rowWidth += d.width;
7171+ rowHeight = Math.max(rowHeight, d.height);
7272+ }
7373+ }
7474+7575+ addRow(dim, rowWidth, rowHeight);
7676+7777+ dim.width += horizontalInsetsAndGap;
7878+ dim.height += insets.top + insets.bottom + vgap * 2;
7979+8080+ Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
8181+ if (scrollPane != null && target.isValid()) {
8282+ dim.width -= (hgap + 1);
8383+ }
8484+8585+ return dim;
8686+ }
8787+ }
8888+8989+ private void addRow(Dimension dim, int rowWidth, int rowHeight) {
9090+ dim.width = Math.max(dim.width, rowWidth);
9191+9292+ if (dim.height > 0) {
9393+ dim.height += getVgap();
9494+ }
9595+9696+ dim.height += rowHeight;
9797+ }
9898+}