Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8834003
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T08:55:02+00:00 2026-06-14T08:55:02+00:00

I am trying to create custom layout which allows me to specify width of

  • 0

I am trying to create custom layout which allows me to specify width of a component in percentage, and layout components based on that percentage widths. The following is the implementation I ended up with.

The problem I’ve is, one of the inner most panel’ calculated width is not sufficient to hold all of its components in one row, and the below implementation wraps them to next line, but the height of the parent [all container in the hierarchy] is fixed to some pixels [in my case I used 40px], and its not allowing the wrapped components to show.

Can you please suggest a way to fix it…

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.Rectangle;
import java.util.LinkedHashMap;
import java.util.Map.Entry;

import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;


/**
 * @author Rakesh.A
 *
 */
public class Example extends JPanel {

public Example() {
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    for (int i = 0; i < 1; i++) {
        JPanel row = new JPanel();
        row.setLayout(new PercentageWidthLayout(5, 5));

        JPanel column1 = new JPanel();
        column1.setOpaque(true);
        column1.setBackground(Color.white);

        JPanel column2 = createColumn2();

        row.add(column1, new MyConstraints(15, false)); // uses 15% of the available size
        row.add(column2, new MyConstraints(50, false, true, true)); // uses 50% of the available size and wraps its contents
        row.add(new JPanel(), new MyConstraints(25, false)); // uses 25% of the available size
        add(row);
    }
}

private JPanel createColumn2() {
    JPanel column = new JPanel();
    column.setOpaque(true);
    column.setBackground(Color.green);

    column.setLayout(new PercentageWidthLayout(3, 3, 35));
    // total percentage is 100% for all the below components
    column.add(new MyComponent(30, 28), new MyConstraints(20, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(10, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(20, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(20, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(10, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(10, true, false, true));
    column.add(new MyComponent(30, 28), new MyConstraints(10, true, false, true));
    return column;
}

public static void main(final String[] args) {
    JDialog dialog = new JDialog();
    dialog.setSize(500, 150);
    Example content = new Example();
    JScrollPane scrl = new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    dialog.getContentPane().add(scrl);
    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dialog.setVisible(true);
}

public static class MyComponent extends JPanel {
    private Dimension minSize;
    public MyComponent(final int minWidth, final int minHeight) {
        minSize = new Dimension(minWidth, minHeight);

        setOpaque(true);
        setBackground(Color.yellow);

        add(new JLabel("Block"));
    }

    @Override
    public Dimension getPreferredSize() {
        return minSize;
    }

    @Override
    public Dimension getMaximumSize() {
        return minSize;
    }
    @Override
    public Dimension getMinimumSize() {
        return minSize;
    }
}

public static class PercentageWidthLayout implements LayoutManager2 {
    private LinkedHashMap<Component, MyConstraints> components;

    private final int leftMargin;
    private final int topMargin;
    private final int rowHeight;

    // default size of the block
    public static final Dimension minimumSize = new Dimension(10, 40);
    public static final Dimension preferredSize = new Dimension(100, 40);

    // default left margin between components
    public static final int defaultLeftMargin = 5;
    // default bottom margin between components
    public static final int defaultTopMargin = 5;
    // default row height
    public static final int defaultRowHeight = 0;

    public PercentageWidthLayout() {
        this(defaultLeftMargin, defaultTopMargin);
    }

    public PercentageWidthLayout(final int leftMargin, final int topMargin) {
        this(leftMargin, topMargin, defaultRowHeight);
    }

    public PercentageWidthLayout(final int leftMargin, final int topMargin, final int rowHeight) {
        this.leftMargin = leftMargin;
        this.topMargin = topMargin;
        this.rowHeight = rowHeight;

        components = new LinkedHashMap<Component, MyConstraints>();
    }

    @Override
    public Dimension preferredLayoutSize(final Container parent) {
        int maxX = 0;
        int maxY = 0;
        for (Entry<Component, MyConstraints> compEntry : components.entrySet()) {
            Rectangle bounds = compEntry.getKey().getBounds();
            maxX = Math.max(maxX, (int) bounds.getMaxX());
            maxY = Math.max(maxY, (int) bounds.getMaxY());
        }
        if (maxX == 0 || maxY == 0) {
            return preferredSize;
        }
        return new Dimension(maxX, maxY);
    }

    @Override
    public Dimension minimumLayoutSize(final Container parent) {
        return minimumSize;
    }

    @Override
    public Dimension maximumLayoutSize(final Container target) {
        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    @Override
    public void layoutContainer(final Container parent) {
        synchronized (parent.getTreeLock()) {
            // validate total percentage
            validatePercentages();
            // calculate available width & height for the components
            Insets insets = parent.getInsets();
            // available width after removing border space
            int maxClientWidth = parent.getWidth() - insets.left - insets.right;
            // calculated available width for the components
            int clientWidth = maxClientWidth - (parent.getComponents().length * leftMargin);
            // calculated available height for the components
            int clientHeight = ((rowHeight > 0) ? rowHeight : preferredSize.height) - insets.top - insets.bottom - topMargin * 2;

            // layout the components
            int x = insets.left + leftMargin;
            int y = insets.top + topMargin;

            if (clientWidth > 0 && clientHeight > 0) {
                for (Component component : parent.getComponents()) {
                    // get the constraints to be applied
                    MyConstraints constraints = components.get(component);
                    // calculate component width according to the given percentage
                    int componentWidth = clientWidth * constraints.percentage / 100;

                    // calculate the preferred size of the component
                    int prefW = component.getPreferredSize().width;
                    if (constraints.usePreferredSize && componentWidth < prefW) {
                        // configured to use preferred size if calculated size is less than the
                        // preferred size
                        componentWidth = prefW;
                    }

                    // calculate the minimum size of the component
                    int minW = component.getMinimumSize().width;
                    if (constraints.useMinWidth && componentWidth < minW) {
                        // configured to use minimum width if calculated size is less than the
                        // minimum size
                        componentWidth = minW;
                    }
                    // check and wrap component to next row if needed
                    if (constraints.wrapComponents && x + componentWidth > parent.getWidth()) {
                        x = insets.left + leftMargin;
                        y += clientHeight + insets.top;
                        // update height of the parent component if it doesn fit
                        // if (parent.getHeight() < y + clientHeight) {
                        // parent.setSize(parent.getWidth(), parent.getHeight() + rowHeight);
                        // }
                    }
                    component.setBounds(x, y, componentWidth, clientHeight);
                    // update x coordinate
                    x += componentWidth + leftMargin;
                }
            }
        }
    }

    @Override
    public void addLayoutComponent(final String name, final Component comp) {
    }

    @Override
    public void removeLayoutComponent(final Component comp) {
        components.remove(comp); // remove component from map
    }

    @Override
    public void addLayoutComponent(final Component comp, final Object constraints) {
        if (constraints == null || !(constraints instanceof MyConstraints)) {
            throw new IllegalArgumentException("Invalid constraints object! - " + constraints);
        }
        MyConstraints myConstraints = (MyConstraints) constraints;
        if (myConstraints.percentage > 100) {
            throw new IllegalArgumentException("Invalid percentage value [" + myConstraints.percentage + "]!");
        }
        components.put(comp, myConstraints);
    }

    @Override
    public float getLayoutAlignmentX(final Container target) {
        return 0;
    }

    @Override
    public float getLayoutAlignmentY(final Container target) {
        return 0;
    }

    @Override
    public void invalidateLayout(final Container target) {
    }

    public int getLeftMargin() {
        return leftMargin;
    }

    public int getTopMargin() {
        return topMargin;
    }

    public int getRowHeight() {
        return rowHeight;
    }

    public static Integer calculatePercentage(final float value, final int total) {
        return new Integer((int) (value / total * 100));
    }

    private void validatePercentages() {
        int total = 0;
        for (Entry<Component, MyConstraints> compEntry : components.entrySet()) {
            total += compEntry.getValue().percentage;
        }
        if (total > 100) {
            throw new IllegalArgumentException("Total percentage [" + total + "] of the components in the layout is more than 100!");
        }
    }

}

/**
 * @author Rakesh.A
 *
 */
public static class MyConstraints {
    public final int percentage;
    public final boolean usePreferredSize, useMinWidth, wrapComponents;

    public MyConstraints(final int percentage, final boolean usePreferredSize) {
        this(percentage, usePreferredSize, false);
    }

    public MyConstraints(final int percentage, final boolean usePreferredSize, final boolean useMinWidth) {
        this(percentage, usePreferredSize, useMinWidth, false);
    }

    public MyConstraints(final int percentage, final boolean usePreferredSize, final boolean useMinWidth, final boolean wrapComponents) {
        this.percentage = percentage;
        this.usePreferredSize = usePreferredSize;
        this.useMinWidth = useMinWidth;
        this.wrapComponents = wrapComponents;
    }
}
}

added to this, the root panel is added to a JScrollPane and it also needs to be updated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T08:55:03+00:00Added an answer on June 14, 2026 at 8:55 am

    Thank you all for your inputs. I opted a workaround for this problem, instead of wrapping the components, I added a horizontal scroll bar 🙂

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

im trying to create a custom JPanel which i add into a card layout
I am trying to create a custom View that would replace a certain layout
I'm trying to create a layout that uses a ListBox and my custom header
I'm trying to create a custom view component which looks like this: a component
I'm trying to create a custom layout that it automatically sets it's dimensions, height
I'm trying to create a custom TabItem that is dynamically added to a TabControl
I'm trying to create a custom form input that utilizes some images, it should
I'm trying to create a custom component to extend PrimeFaces. I have a simple
I am trying to create a custom popup view that can be called from
I'm trying to create a custom usercontrol that acts like a button, but i

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.