问题
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