Get preferred size of multi-line flowlayout

独自空忆成欢 提交于 2019-12-12 10:38:26

问题


I can't figure out a way to resize some components in a swing GUI. Some custom labels are being added to a FlowLayout which doesn't behave how they should when resizing the dialog. The panel is being built using the jgoodies forms framework.

If using this, where the FlowLayout is being added to xy(3, y)

FormLayout layout = new FormLayout("r:d, 5px, f:d:g", // columns
            "p, p, 5px, p, 5px, p") // rows

The FlowLayout expands and a scroll bar shows up

If using

FormLayout layout = new FormLayout("r:d, 5px, f:10:g", // columns
            "p, p, 5px, p, 5px, p") // rows

The FlowLayout uses the available space and the items on the second line disappear

I'd like to expand the height of each row containing a FlowLayout to the current height of the component. Unfortunately the preferred size always corresponds to the hight for a single row.
Would another layout be more appropriate? The bold text on the left should be aligned right, followed by the FlowLayout.

Sources

[edit] After having tried to figure out how to do this for weeks, the actual question can be resumed to this:
A set of labels is being added to a JPanel. This JPanel should use all available space horizontally (dialogue size minus width of tag name label) and expand as needed vertically. If the height of the JPanel gets bigger then the dialogue, a vertical scroll bar should show up (the horizontal scroll bar is never visible). The dialogue can show multiple JPanels which will be shown one after the other (vertically).

Here's an attempt using GridBagLayout and WrapLayout:

public class GridBagLayoutTagPanel extends JPanel {
private static final long serialVersionUID = -441746014057882848L;
private final int NB_TAGS = 5;

public GridBagLayoutTagPanel() {
    setLayout(new GridLayout());

    JPanel pTags = new JPanel(new GridBagLayout());
    pTags.setBackground(Color.ORANGE);
    GridBagConstraints c = new GridBagConstraints();
    c.ipadx = 5;
    c.ipady = 5;

    int rowIndex = 0;
    for (int i = 0; i < NB_TAGS; i++) {
        //add tag name
        JLabel lTagName = new JLabel(String.format("Tag %s:", i));
        lTagName.setFont(lTagName.getFont().deriveFont(Font.BOLD));
        c.fill = GridBagConstraints.NONE;
        c.gridx = 0;
        c.gridy = rowIndex++;
        pTags.add(lTagName, c);

        //add tag values
        JPanel pTag = new JPanel(new BorderLayout());
        pTag.add(new JLabel("+"), BorderLayout.LINE_START); //label used to add new tags
        pTag.add(getWrapPanel(), BorderLayout.CENTER); //the list of tag values
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        pTags.add(pTag, c);
    }

    //JScrollPane sp = new JScrollPane(pTags);
    //sp.setBorder(BorderFactory.createEmptyBorder());

    add(pTags);
    }

private static JPanel getWrapPanel() {
   JPanel p = new JPanel(new WrapLayout(FlowLayout.LEFT, 5, 0));

   for (int i = 0; i < 50; i++) {
           p.add(new JLabel("t" + i));
   }
   return p;
}

public static void main(String[] args) {
    JFrame f = new JFrame();
    f.getContentPane().add(new GridBagLayoutTagPanel());
    f.setSize(new Dimension(500, 300));
    f.setVisible(true);
}
}

回答1:


I'd like to expand the height of each row containing a FlowLayout to the current height of the component. Unfortunately the preferred size always corresponds to the hight for a single row.

Wrap Layout handles this.




回答2:


With Rob's help and using his WrapPanel and ScrollablePanel it now works exactly as it should

public class GridBagLayoutTagPanel extends JPanel {
  private final int NB_TAGS = 5;
  private final int NB_TAGVALUES = 50;

  public GridBagLayoutTagPanel() {
    setLayout(new GridLayout());

    ScrollablePanel pTags = new ScrollablePanel(new GridBagLayout());
    pTags.setScrollableWidth(ScrollablePanel.ScrollableSizeHint.FIT);
    pTags.setBackground(Color.ORANGE);
    GridBagConstraints c = new GridBagConstraints();
    c.ipadx = 5;
    c.ipady = 5;

    int rowIndex = 0;
    for (int i = 0; i < NB_TAGS; i++) {
      // add tag name
      JLabel lTagName = new JLabel(String.format("Tag %s:", i));
      lTagName.setFont(lTagName.getFont().deriveFont(Font.BOLD));
      c.fill = GridBagConstraints.NONE;
      c.gridx = 0;
      c.gridy = rowIndex++;
      c.weightx = 0; // keep minimum size of the cell containing the label when resizing
      c.weighty = 0;
      pTags.add(lTagName, c);

      // add tag values
      JPanel pTag = new JPanel(new BorderLayout());
      pTag.add(new JLabel("+"), BorderLayout.LINE_START); // label used to add new tags
      pTag.add(getWrapPanel(), BorderLayout.CENTER); // the list of tag values
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.weightx = 1; // fill horizontally
      c.weighty = 1;
      pTags.add(pTag, c);
   }

   JScrollPane sp = new JScrollPane(pTags);
   sp.setBorder(BorderFactory.createEmptyBorder());

   add(sp);
  }

  private JPanel getWrapPanel() {
    JPanel p = new JPanel(new WrapLayout(FlowLayout.LEFT, 5, 0));

    for (int i = 0; i < NB_TAGVALUES; i++) {
      p.add(new JLabel("t" + i));
    }

    p.setSize(400, 1);
    return p;
  }

  public static void main(String[] args) {
    JFrame f = new JFrame();
    f.getContentPane().add(new GridBagLayoutTagPanel());
    f.setSize(new Dimension(500, 300));
    f.setVisible(true);
  }
}



回答3:


Have you tried MigLayout? It's the only layout manager that I use, and I've never found a layout I couldn't get it to do.



来源:https://stackoverflow.com/questions/8840299/get-preferred-size-of-multi-line-flowlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!