19 package org.sleuthkit.autopsy.guiutils;
21 import java.awt.Component;
22 import java.awt.Container;
23 import java.awt.Dimension;
24 import java.awt.Insets;
25 import java.awt.LayoutManager;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.List;
33 import java.util.stream.Collectors;
34 import javax.swing.JScrollPane;
35 import javax.swing.SwingUtilities;
48 public class WrapLayout implements LayoutManager, java.io.Serializable {
116 this.oppositeAlignedItems.clear();
117 this.oppositeAlignedItems.addAll(oppAlignedComponents);
128 return Collections.unmodifiableCollection(oppositeAlignedItems);
239 ? rowY + rowHeight - itemHeight
256 int componentWidth) {
257 return ltr ? leftX + xPos : rightX - xPos - componentWidth;
278 boolean ltr,
int rowY,
int rowHeight,
int leftX,
int rightX,
281 Dimension d = comp.getPreferredSize();
285 int y =
getComponentY(rowY, alignBaseline, rowHeight, d.height);
286 comp.setLocation(x, y);
294 List<Component> components = Arrays.asList(target.getComponents());
295 List<WrapLayoutRow> rows =
getAllRows(components,
true, targetDims.getInnerWidth());
297 boolean ltr = target.getComponentOrientation().isLeftToRight();
302 int rightX = targetDims.getOuterWidth() - targetDims.getInsets().right -
getHorizontalGap();
305 int rowHeight = row.getHeight();
308 if (row.getComponents() != null) {
309 for (Component origComp : row.getComponents()) {
314 if (row.getOppositeAligned() != null) {
317 Collections.reverse(row.getOppositeAligned());
318 for (Component oppAlignedComp : row.getOppositeAligned()) {
334 Dimension minimum =
layoutSize(target,
false);
366 int getOuterWidth() {
376 int getInnerWidth() {
399 Container container = target;
401 while (container.getSize().width == 0 && container.getParent() != null) {
402 container = container.getParent();
405 int targetWidth = container.getSize().width;
407 if (targetWidth == 0) {
408 targetWidth = Integer.MAX_VALUE;
411 Insets insets = container.getInsets();
412 int horizontalInsetsAndGap = insets.left + insets.right + (
getHorizontalGap() * 2);
413 int maxWidth = targetWidth - horizontalInsetsAndGap;
427 private Dimension
layoutSize(Container target,
boolean preferred) {
429 List<Component> components = Arrays.asList(target.getComponents());
430 List<WrapLayoutRow> rows =
getAllRows(components, preferred, targetDims.getInnerWidth());
432 Integer containerHeight = rows.stream().map((r) -> r.getHeight()).reduce(0, Integer::sum);
434 if (rows.size() > 1) {
438 containerHeight += targetDims.getInsets().top + targetDims.getInsets().bottom;
440 Integer containerWidth = rows.stream().map((r) -> r.getWidth()).reduce(0, Math::max);
441 containerWidth += targetDims.getInsets().left + targetDims.getInsets().right + (
getHorizontalGap() * 2);
447 Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
449 if (scrollPane != null && target.isValid()) {
453 return new Dimension(containerWidth, containerHeight);
477 WrapLayoutRow(List<Component> components, List<Component> oppositeAligned,
478 int height,
int width) {
492 List<Component> getComponents() {
503 List<Component> getOppositeAligned() {
541 private List<WrapLayoutRow>
getAllRows(List<Component> components,
542 boolean preferred,
int maxWidth) {
543 List<Component> originalComp
546 .filter((comp) -> !this.oppositeAlignedItems.contains(comp))
547 .collect(Collectors.toList());
549 List<WrapLayoutRow> originalRowSet =
getRowSet(originalComp, preferred, maxWidth);
551 List<Component> oppositeAlignedComp
554 .filter((comp) -> this.oppositeAlignedItems.contains(comp))
555 .collect(Collectors.toList());
558 Collections.reverse(oppositeAlignedComp);
559 List<WrapLayoutRow> oppositeRowSet =
getRowSet(oppositeAlignedComp, preferred, maxWidth)
562 Collections.reverse(row.getComponents());
563 return new WrapLayoutRow(null, row.getComponents(), row.getHeight(), row.getWidth());
565 .collect(Collectors.toList());
566 Collections.reverse(oppositeRowSet);
568 List<WrapLayoutRow> toReturn =
new ArrayList<>();
572 if (!originalRowSet.isEmpty() && !oppositeRowSet.isEmpty()) {
573 WrapLayoutRow lastOrig = originalRowSet.get(originalRowSet.size() - 1);
576 int proposedRowWidth = lastOrig.getWidth() + firstOpp.getWidth() +
getHorizontalGap();
577 if (proposedRowWidth <= maxWidth) {
579 Math.max(lastOrig.getHeight(), firstOpp.getHeight()), proposedRowWidth);
581 toReturn.addAll(originalRowSet.subList(0, originalRowSet.size() - 1));
582 toReturn.add(middleRow);
583 toReturn.addAll(oppositeRowSet.subList(1, oppositeRowSet.size()));
588 toReturn.addAll(originalRowSet);
589 toReturn.addAll(oppositeRowSet);
605 private List<WrapLayoutRow>
getRowSet(List<Component> components,
606 boolean preferred,
int maxWidth) {
607 List<WrapLayoutRow> rows =
new ArrayList<>();
609 List<Component> rowComponents =
new ArrayList<>();
613 for (Component m : components) {
615 Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
618 if (rowWidth + d.width > maxWidth) {
619 rows.add(
new WrapLayoutRow(rowComponents, null, rowHeight, rowWidth));
620 rowComponents =
new ArrayList<>();
630 rowComponents.add(m);
632 rowHeight = Math.max(rowHeight, d.height);
636 if (!rowComponents.isEmpty()) {
637 rows.add(
new WrapLayoutRow(rowComponents, null, rowHeight, rowWidth));
void layoutContainer(Container target)
int getComponentX(int leftX, int rightX, boolean ltr, int xPos, int componentWidth)
int setComponentDims(Component comp, boolean alignBaseline, boolean ltr, int rowY, int rowHeight, int leftX, int rightX, int xPos)
Dimension layoutSize(Container target, boolean preferred)
boolean isAlignOnBaseline()
ParentDimensions getTargetDimensions(Container target)
WrapLayout(int verticalGap, int horizontalGap)
void setAlignOnBaseline(boolean alignOnBaseline)
List< WrapLayoutRow > getAllRows(List< Component > components, boolean preferred, int maxWidth)
Dimension minimumLayoutSize(Container target)
Dimension preferredLayoutSize(Container target)
final List< Component > oppositeAligned
Collection< Component > getOppositeAlignedItems()
List< WrapLayoutRow > getRowSet(List< Component > components, boolean preferred, int maxWidth)
final Set< Component > oppositeAlignedItems
void setVerticalGap(int verticalGap)
void setHorizontalGap(int horizontalGap)
void addLayoutComponent(String name, Component comp)
void setOppositeAligned(Collection< Component > oppAlignedComponents)
void removeLayoutComponent(Component comp)
final List< Component > components
static final long serialVersionUID
int getComponentY(int rowY, boolean alignBaseline, int rowHeight, int itemHeight)