How to stick to top of container in BoxLayout

别说谁变了你拦得住时间么 提交于 2019-12-11 00:25:46

问题


I have a parent JPanel with a Y_AXIS layout. The children of this container are all JPanels as well. The components are stacking fine, and are all alligned, but i want them to stick to the top of the parent JPanel so all excess space is in the bottom, and there is no extra space between the components. I have tried using glue, but i might be doing something wrong. I have also set the AllignmentX and AllignmentY to left and top respectively on all children.

So, what i want is a stack of children in the parent panel, that is not stretched in height, and sticks to the top (and left, if possible) of the parent container, with all excess space placed in the bottom, as such:

EDIT:

protected void initContent(JPanel panel) {
    id = new JTextField();
    typename = new JTextField();
    currentstep = new JComboBox();
    currentowner = new JComboBox();
    organization = new JTextField();
    area = new JTextField();
    active = new JLabel();
    finished = new JLabel();
    fields = new JList();
    linkedassignments = new JList();
    jobs = new JList();
    JPanel infopanel = new JPanel();
    JPanel listpanel = new JPanel();
    infopanel.setLayout(new BoxLayout(infopanel, BoxLayout.Y_AXIS));
    infopanel.add(Box.createVerticalGlue());
    infopanel.add(makeInfoContainer("Id", id, 50, 100));
    infopanel.add(makeInfoContainer("Type", typename, 50, 100));
    infopanel.add(makeInfoContainer("Organization", organization, 50, 100));
    infopanel.add(makeInfoContainer("Area", area, 50, 100));
    infopanel.add(makeInfoContainer("Active", active, 50, 100));
    infopanel.add(makeInfoContainer("Finished", finished, 50, 100));
    infopanel.add(makeInfoContainer("Step", currentstep, 50, 100));
    infopanel.add(makeInfoContainer("Owner", currentowner, 50, 100));
    listpanel.setLayout(new GridLayout(0,1,5,5));
    listpanel.add(makeJListContainer("Fields", fields, 200, 200));
    listpanel.add(makeJListContainer("Assignments", linkedassignments, 200, 200));
    listpanel.add(makeJListContainer("Jobs", jobs, 200, 200));
    panel.add(infopanel);
    panel.add(listpanel);
}


private Container makeInfoContainer(String name, Component comp, int labelwidth, int compwidth){
    JPanel cont = new JPanel();
    cont.setAlignmentY(Container.TOP_ALIGNMENT);
    cont.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
    JLabel lbl = new JLabel(name);
    lbl.setPreferredSize(new Dimension(labelwidth, 25));
    cont.add(lbl);
    comp.setPreferredSize(new Dimension(compwidth, 25));
    cont.add(comp);
    return cont;
}

private Container makeJListContainer(String name, JList list, int areawidth, int areaheight){
    Box cont = new Box(BoxLayout.Y_AXIS);
    cont.setPreferredSize(new Dimension(areawidth, areaheight));
    JLabel label = new JLabel(name);
    cont.add(Box.createHorizontalGlue());
    cont.add(label);
    JScrollPane pane = new JScrollPane();
    pane.setAlignmentY(Component.TOP_ALIGNMENT);
    pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    pane.add(jobs);
    cont.add(pane);
    return cont;
}


回答1:


Assuming that the layoutManager of the containing panel (that is the one passed into the initContent) has a horizontalBoxLayout

  • remove all the glue stuff
  • set the alignmentY of both info/listPanel to top
  • implement the getMaximum of the infoPanel to return its pref

Something like (borders are just to visualize which container is where, often hard to decide with so much nesting :)

JComponent panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
initContent(panel);

// in initContent
JPanel infopanel = new JPanel() {

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


};
infopanel.setBorder(BorderFactory.createLineBorder(Color.RED));
infopanel.setAlignmentY(0f);
infopanel.setLayout(new BoxLayout(infopanel, BoxLayout.Y_AXIS));
JPanel listpanel = new JPanel();
listpanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
listpanel.setAlignmentY(0f);
listpanel.setLayout(new GridLayout(0,1,5,5));

While you are at it: remove all setXXSize - hard-coding sizes is wrong, some reasons.




回答2:


Try removing the glue at the top of the container and add it to the bottom instead.

Changed code:

protected void initContent(JPanel panel) {
       [...]
       JPanel infopanel = new JPanel();
       JPanel listpanel = new JPanel();
       infopanel.setLayout(new BoxLayout(infopanel, BoxLayout.Y_AXIS));
       infopanel.add(Box.createVerticalGlue());
       infopanel.add(makeInfoContainer("Id", id, 50, 100));
       [...]
       infopanel.add(makeInfoContainer("Owner", currentowner, 50, 100));
       infopanel.add(Box.createVerticalGlue());
       listpanel.setLayout(new GridLayout(0,1,5,5));
       [...]
}


来源:https://stackoverflow.com/questions/11699311/how-to-stick-to-top-of-container-in-boxlayout

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