Как приклеить к верхней части контейнера в BoxLayout

У меня есть родительский JPanel с макетом Y_AXIS. Все дочерние элементы этого контейнера также являются JPanel. Компоненты укладываются нормально и все выровнены, но я хочу, чтобы они оставались наверху родительской панели JPanel, чтобы все лишнее пространство находилось внизу, и между компонентами не было лишнего пространства. Я пробовал использовать клей, но, возможно, что-то делаю не так. Я также установил AllignmentX и AllignmentY влево и вверх соответственно для всех дочерних элементов.

Итак, мне нужен стек дочерних элементов на родительской панели, который не растягивается по высоте и прилипает к верху (и, если возможно, слева) родительского контейнера, со всем лишним пространством, размещенным внизу, как таковое. :

РЕДАКТИРОВАТЬ:

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;
}

Окно, полученное из кода


person Martin Nielsen    schedule 28.07.2012    source источник
comment
Вы можете загрузить изображения и / или образец кода, который действительно поможет. Я бы посмотрел на некоторые другие менеджеры компоновки, я не думаю, что они будут делать то, что вы хотите   -  person MadProgrammer    schedule 28.07.2012
comment
убедитесь, что все дети реализуют getMaximumSize () с чем-то разумно разумным: BoxLayout никогда не будет их размер больше, чем это   -  person kleopatra    schedule 28.07.2012


Ответы (2)


Предполагая, что layoutManager содержащей панели (которая передана в initContent) имеет horizontalBoxLayout

  • удалить весь клей
  • установите alignmentY обоих info / listPanel вверх
  • реализовать getMaximum infoPanel, чтобы вернуть его pref

Что-то вроде (границы нужны только для того, чтобы визуализировать, какой контейнер где находится, часто трудно решить с таким количеством вложений :)

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));

Пока вы на нем: удалите все setXXSize - размеры жесткого кодирования неверны, по некоторым причинам.

person kleopatra    schedule 28.07.2012
comment
Гениальная идея. Границы показали, что проблема не во внутренней панели. Но внешняя панель передается в метод. - person Martin Nielsen; 28.07.2012

Попробуйте удалить клей из верхней части контейнера и вместо этого добавить его в нижнюю часть.

Измененный код:

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));
       [...]
}
person Kasper van den Berg    schedule 28.07.2012
comment
Это не имело значения. Выглядит точно так же - person Martin Nielsen; 28.07.2012