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)