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

191
LINES

< > BotCompany Repo | #1033556 // WrapLayout

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (219L/2K).

// FlowLayout subclass that fully supports wrapping of components
// (showing in multiple lines)

// from https://tips4java.wordpress.com/2008/11/06/wrap-layout/

sclass WrapLayout extends FlowLayout {
  private Dimension preferredLayoutSize;
  
  bool preferredAsMinimum = false;

  /**
  * Constructs a new <code>WrapLayout</code> with a left
  * alignment and a default 5-unit horizontal and vertical gap.
  */
  *() {}

  /**
  * Constructs a new <code>FlowLayout</code> with the specified
  * alignment and a default 5-unit horizontal and vertical gap.
  * The value of the alignment argument must be one of
  * <code>WrapLayout</code>, <code>WrapLayout</code>,
  * or <code>WrapLayout</code>.
  * @param align the alignment value
  */
  public WrapLayout(int align)
  {
    super(align);
  }

  /**
  * Creates a new flow layout manager with the indicated alignment
  * and the indicated horizontal and vertical gaps.
  * <p>
  * The value of the alignment argument must be one of
  * <code>WrapLayout</code>, <code>WrapLayout</code>,
  * or <code>WrapLayout</code>.
  * @param align the alignment value
  * @param hgap the horizontal gap between components
  * @param vgap the vertical gap between components
  */
  public WrapLayout(int align, int hgap, int vgap)
  {
    super(align, hgap, vgap);
  }

  /**
  * Returns the preferred dimensions for this layout given the
  * <i>visible</i> components in the specified target container.
  * @param target the component which needs to be laid out
  * @return the preferred dimensions to lay out the
  * subcomponents of the specified container
  */
  @Override
  public Dimension preferredLayoutSize(Container target)
  {
    return layoutSize(target, true);
  }

  /**
  * Returns the minimum dimensions needed to layout the <i>visible</i>
  * components contained in the specified target container.
  * @param target the component which needs to be laid out
  * @return the minimum dimensions to lay out the
  * subcomponents of the specified container
  */
  @Override
  public Dimension minimumLayoutSize(Container target)
  {
    Dimension minimum = layoutSize(target, preferredAsMinimum);
    minimum.width -= (getHgap() + 1);
    return minimum;
  }

  /**
  * Returns the minimum or preferred dimension needed to layout the target
  * container.
  *
  * @param target target to get layout size for
  * @param preferred should preferred size be calculated
  * @return the dimension to layout the target container
  */
  private Dimension layoutSize(Container target, boolean preferred)
  {
  synchronized (target.getTreeLock())
  {
    //  Each row must fit with the width allocated to the containter.
    //  When the container width = 0, the preferred width of the container
    //  has not yet been calculated so lets ask for the maximum.

    int targetWidth = target.getSize().width;
    print ifdef WrapLayout_debug(+targetWidth);
    Container container = target;

    while (container.getSize().width == 0 && container.getParent() != null)
    {
      container = container.getParent();
    }

    targetWidth = container.getSize().width;

    if (targetWidth == 0)
      targetWidth = Integer.MAX_VALUE;

    int hgap = getHgap();
    int vgap = getVgap();
    Insets insets = target.getInsets();
    int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
    int maxWidth = targetWidth - horizontalInsetsAndGap;

    //  Fit components into the allowed width

    Dimension dim = new Dimension(0, 0);
    int rowWidth = 0;
    int rowHeight = 0;

    int nmembers = target.getComponentCount();

    for (int i = 0; i < nmembers; i++)
    {
      Component m = target.getComponent(i);

      if (m.isVisible())
      {
        Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();

        //  Can't add the component to current row. Start a new row.

        if (rowWidth + d.width > maxWidth)
        {
          addRow(dim, rowWidth, rowHeight);
          rowWidth = 0;
          rowHeight = 0;
        }

        //  Add a horizontal gap for all components after the first

        if (rowWidth != 0)
        {
          rowWidth += hgap;
        }

        rowWidth += d.width;
        rowHeight = Math.max(rowHeight, d.height);
      }
    }

    addRow(dim, rowWidth, rowHeight);

    dim.width += horizontalInsetsAndGap;
    dim.height += insets.top + insets.bottom + vgap * 2;

    //  When using a scroll pane or the DecoratedLookAndFeel we need to
    //  make sure the preferred size is less than the size of the
    //  target containter so shrinking the container size works
    //  correctly. Removing the horizontal gap is an easy way to do this.

    Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);

    if (scrollPane != null && target.isValid())
    {
      dim.width -= (hgap + 1);
    }
    
    ifdef WrapLayout_debug
    print(renderVars("WrapLayout layoutSize", +preferred, +targetWidth, +dim));
    endifdef

    return dim;
  }
  }

  /*
   *  A new row has been completed. Use the dimensions of this row
   *  to update the preferred size for the container.
   *
   *  @param dim update the width and height when appropriate
   *  @param rowWidth the width of the row to add
   *  @param rowHeight the height of the row to add
   */
  private void addRow(Dimension dim, int rowWidth, int rowHeight)
  {
    dim.width = Math.max(dim.width, rowWidth);

    if (dim.height > 0)
    {
      dim.height += getVgap();
    }

    dim.height += rowHeight;
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033556
Snippet name: WrapLayout
Eternal ID of this version: #1033556/10
Text MD5: aa364120020ee5926a035aa355ad2d17
Transpilation MD5: eda2f1c104a9da5bdc04c93166f1f813
Author: stefan
Category: javax / gui
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-08-17 16:29:47
Source code size: 5710 bytes / 191 lines
Pitched / IR pitched: No / No
Views / Downloads: 181 / 295
Version history: 9 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)