JLayeredPane не учитывает слои

У меня есть JLayeredPane. Моя программа работает примерно так:

JPanel p1 = new JPanel(new BoxLayout(p1, BoxLayout.X_AXIS));
JPanel p2 = new JPanel(new BoxLayout(p2, BoxLayout.Y_AXIS));
JLayeredPane lp = new JLayeredPane();
lp.add(p1, 1);
lp.add(p2, 0);

И p1, и p2 имеют такие компоненты, как кнопки и т. д.

Проблема в том, что когда я добавляю обе панели JPanel в JLayeredPane, НИЧЕГО не появляется.

Я попытался изменить макет JLayeredPane().

Например, я сделал:

lp.setLayout(new BoxLayout(lp, BoxLayout.X_AXIS));

Затем отображаются панели JPanel, но они отображаются рядом, без учета слоев JLayeredPane.

Я вынужден использовать нулевой макет?

Как я могу заставить свой JLayeredPane уважать слои и правильно отображать два JPanels BoxLayout?

Когда я даю свой JLayeredPane макет, он показывает панели, но совершенно не учитывает слои.


person ThePrince    schedule 15.04.2013    source источник
comment
НИКОГДА не используйте макет null.   -  person syb0rg    schedule 16.04.2013
comment
Это проблема: docs.oracle.com/javase/tutorial /uiswing/components/ -- Второй аргумент add() должен быть Integer, а не int, так как int версия метода отличается.   -  person Lee Meador    schedule 16.04.2013
comment
Когда я не устанавливаю макет, НИЧЕГО не появляется. Когда я добавляю какой-либо макет, он просто ведет себя так, как будто это не многоуровневая панель, и добавляет компоненты, визуально примыкающие друг к другу, а не один поверх другого.   -  person ThePrince    schedule 16.04.2013
comment
Спасибо за проблему с целым числом. Однако, когда я использую Integer, он по-прежнему действует как обычный макет. Он добавляет панели рядом друг с другом, даже если они должны быть в разных слоях.   -  person ThePrince    schedule 16.04.2013
comment
JLayeredPane действует так, как если бы он использовал нулевой макет. Вы должны указать размер и положение панели JPanel при ее добавлении в JLayeredPane.   -  person Hovercraft Full Of Eels    schedule 16.04.2013


Ответы (3)


Вам нужен менеджер компоновки, который понимает ось Z. Менеджеры компоновки по умолчанию не понимают ось Z JLayeredPane.

Если вы просто хотите накладывать элементы друг на друга, вы можете использовать LayoutManager следующим образом:

JLayeredPane layeredFooPane = new JLayeredPane();
// The magic!
layeredFooPane.setLayout(new LayeredPaneLayout(layeredPane));
// Add components:
layeredFooPane.add(fooComponent, new Integer(JLayeredPane.DEFAULT_LAYER + 10));
layeredFooPane.add(barComponent, JLayeredPane.DEFAULT_LAYER);

Класс LayoutManager:

public class LayeredPaneLayout implements LayoutManager {

    private final Container target;
    private static final Dimension preferredSize = new Dimension(500, 500);

    public LayeredPaneLayout(final Container target) {
            this.target = target;
    }

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

    @Override
    public void layoutContainer(final Container container) {
            for (final Component component : container.getComponents()) {
                    component.setBounds(new Rectangle(0, 0, target.getWidth(), target.getHeight()));
            }
    }

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

    @Override
    public Dimension preferredLayoutSize(final Container parent) {
            return preferredSize;
    }

    @Override
    public void removeLayoutComponent(final Component comp) {
    }
}
person Jasper Siepkes    schedule 15.04.2013
comment
Это работает хорошо, хотя единственная проблема, с которой я сталкиваюсь, заключается в том, что когда у меня есть компоненты на каждом из этих слоев, некоторые компоненты из нижних слоев пытаются выскочить вверх (когда я наводил на них курсор). Я могу устранить это поведение, просто отключив все компоненты нижнего слоя (‹code› setEnabled(false) ‹/code›), потому что, в конце концов, им нечего включать, если они в данный момент скрыты — это просто добавляет один дополнительный бит накладных расходов. - person Michael Plautz; 15.10.2013

JLayeredPane действует так, как если бы он использовал нулевой макет. Вы должны указать размер и положение панели JPanel при ее добавлении в JLayeredPane. Один из немногих раз, когда я рекомендую это:

JPanel p1 = new JPanel(new BoxLayout(p1, BoxLayout.X_AXIS));
JPanel p2 = new JPanel(new BoxLayout(p2, BoxLayout.Y_AXIS));
JLayeredPane lp = new JLayeredPane();
lp.add(p1, 1);
lp.add(p2, 0);

p1.setSize(lp.getPreferredSize());
p2.setSize(lp.getPreferredSize());
person Hovercraft Full Of Eels    schedule 15.04.2013

У меня была аналогичная проблема. Вместо того, чтобы передавать слой при добавлении панелей, попробуйте сделать это отдельно:

lp.setLayer(p1, 1);
lp.setLayer(p2, 0);
lp.add(p1);
lp.add(p2);

Слои должны быть определены перед добавлением компонентов. Вы также можете попробовать использовать JLayeredPane.DEFAULT_LAYER вместо 0.

В моем случае у моего JLayeredPane был GridBagLayout, я не знаю, работает ли он с макетом по умолчанию.

person Rafael Rodrigues dos Santos    schedule 07.03.2018