помилка при призначенні макета: 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екземпляр.
alife

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