ошибка при назначении макета: BoxLayout нельзя поделиться


114

У меня есть JFrameкласс Java , в котором я хочу использовать boxlayout, но получаю сообщение об ошибке java.awt.AWTError: BoxLayout can't be shared. Я видел других с этой проблемой, но они решили ее, создав boxlayout на панели содержимого, но это то, что я здесь делаю. Вот мой код:

class EditDialog extends JFrame {
    JTextField title = new JTextField();
    public editDialog() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setTitle("New entity");
        getContentPane().setLayout(
            new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(title);
        pack();
        setVisible(true);
    }
}

Ответы:


173

Ваша проблема в том, что вы создаете BoxLayoutдля JFrame( this), но устанавливаете его как макет для JPanel( getContentPane()). Пытаться:

getContentPane().setLayout(
    new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)
);

5
Да, но удаление этого запутает проблему, не так ли?
Майкл Майерс

75

Я также обнаружил эту ошибку:

JPanel panel = new JPanel(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

JPanel еще не инициализирован при передаче в BoxLayout. Так что разделите эту строку так:

JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

Это сработает.


16

Я думаю, что одна важная вещь, которую следует выделить из предыдущих ответов, заключается в том, что цель BoxLayout (первый параметр) должна быть тем же контейнером, что и метод setLayout, как в следующем примере:

JPanel XXXXXXXXX = new JPanel();
XXXXXXXXX.setLayout(new BoxLayout(XXXXXXXXX, BoxLayout.Y_AXIS));

6

Если вы используете макет JFrameкак:

JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame, BoxLayout.Y_AXIS));
frame.add(new JLabel("Hello World!"));

Управления фактически добавляются к ContentPaneтак это будет выглядеть , как будто это «общее» между JFrameиContentPane

Вместо этого сделайте это:

JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
frame.add(new JLabel("Hello World!"));

Черт возьми, ты меня спас, - почему это единственный ответ, в котором упоминается getContentPane ()?
Александр МакНалти

@AlexanderMcNulty, вероятно, потому, JFrameчто обычно этого не требует (в отличие от AWT Frame). Из JFrameдокументации: As a convenience, the add, remove, and setLayout methods of this class are overridden, so that they delegate calls to the corresponding methods of the ContentPane. For example, you can add a child component to a frame as follows: frame.add(child); And the child will be added to the contentPane. The content pane will always be non-null. К frameони со ссылкой на JFrameэкземпляр.
Алиф

@AlexanderMcNulty, кроме того, в JFrame есть только одна панель содержимого, и она всегда будет там.
Алиф
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.