ошибка при назначении макета: 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 есть только одна панель содержимого, и она всегда будет там.
Алиф