Путаница в области содержимого JPanel

#java #swing #layout-manager #jcomponent #jmenubar

#java #swing #макет-менеджер #jcomponent #jmenubar

Вопрос:

Я изучаю Java Swing и добавил строку меню к фрейму. По умолчанию это должно вызывать jframe.getContentPane().add(child) . Когда я запускал скрипт, панель меню не отображалась. Но кнопка была на самом верху «y = 0», если это имеет смысл.

Затем я понял свою ошибку, мне действительно пришлось ввести меню в панель меню. Затем появилась панель меню. Так что это меня достало thinking…is «панель меню» «contentpane» на самом деле состоит из 2 панелей? Это чертовски сбивает меня с толку. Потому что это очень похоже на панель. Но getContentPane() возвращает контейнер, а не объект JPanel, поэтому я в замешательстве.

Если это так, означает ли это, что единственное, что сбрасывается непосредственно во фрейм, — это просто объекты Jpanel? Следовательно, JButtons, JLabels не находятся непосредственно во фрейме… Означает ли это, что jpanels являются «вложенными»? Еще одна вещь, которая меня смущает. Если jpanel может управлять расположением элементов, для чего нужен LayoutManager? : S Спасибо, и, пожалуйста, ответьте, как если бы 2-летний спрашивал, почему небо голубое, ха 😉

Комментарии:

1. Похоже, JPanel расширяет контейнер. download.oracle.com/javase/6/docs/api/javax/swing/JPanel.html

2. «Если jpanel может управлять расположением элементов, для чего нужен LayoutManager?» A JPanel не может контролировать, как все расположено, это именно то, что LayoutManager делают s.

3. Правильно, я думаю, больше о том, как вещи отображаются или организованы, а не о расположении компонентов на экране

4. См. Также JRootPane , Используемый облегченный контейнер JFrame и др.

5. Нажмите, чтобы узнать, как использовать корневые панели .

Ответ №1:

Некоторые случайные мысли:

  • Да, JPanels и другие компоненты часто являются «вложенными». Именно здесь необходимо четкое понимание менеджеров компоновки Swing / AWT.
  • Хотя тип, возвращаемый JFrame getContentPane() , технически является контейнером, он также является JPanel (который в конечном итоге наследуется от контейнера).
  • Я считаю, что вы можете сделать все, что происходит от Container, ContentPane, но вам нужно позаботиться о том, чтобы оно было непрозрачным.

Комментарии:

1. Итак, существует ли на самом деле одна JPanel по умолчанию, когда не используется JMenuBar? Конечно, забывая другие явные jpanels. И если вы добавили JMenuBar, он создает 2 JPanels по умолчанию? Один для панели меню и один для содержимого. Почему менеджер компоновки отличается?

2. При запуске появляется одна JPanel. Если вы добавите JMenuBar, появится та же JPanel, а теперь JMenuBar, а не две JPanels. Я не понимаю вашего последнего вопроса — почему какой менеджер компоновки отличается.

3. Вы правы. Когда я попробовал a jframe.add(menuBar) , он фактически ничего не показывает. С setJMenuBar(menuBar) этим что-то показывает.. это означает, что по умолчанию для строки меню устанавливается значение (0,0), если она не создает другую JPanel… Я имею в виду, как получается, что JPanel отличается от макета, поскольку JPanel также может позиционировать элементы или позиционировать другие компоненты

4. @Судно на воздушной подушке, полное угрей (не уверен), может быть, CardLayout??

5. JPanel и менеджер компоновки — это два совершенно разных зверя. JPanels и все, что происходит от компонентов, используют менеджеры компоновки. JPanel — это компонент, который отображается в графическом интерфейсе, а макет — это способ, которым контейнеры (включая JPanels) упорядочивают компоненты, которые они содержат. Поэтому, если ваша JPanel содержит другие компоненты, вам лучше знать, какой менеджер компоновки он использует и как работает этот менеджер компоновки.

Ответ №2:

для этого есть метод

 frame.setJMenuBar(menuBar);
  

для современного Java Swing GUI не обязательно объявлять ContentPane из Java5 и с BorderLayout по умолчанию LayoutManager

тогда frame.add(myPanel); // совпадает с frame.add(myPanel, BorderLayout.CENTER) и занимает весь контейнер

основные сведения о том, как использовать LayourManagers

Комментарии:

1. Я могу быть быстрее, но это лучший ответ, чем мой. 1

Ответ №3:

getContentPane() всегда возвращает Container экземпляр. Однако следует отметить, что JPanel объекты являются Container экземплярами, как и другие классы в среде Swing. Фактический класс возвращаемого экземпляра не имеет значения, поскольку у вас нет контроля над тем, какая реализация Container используется в качестве ContentPane (если вы не принудительно ввели определенную ContentPane), и в большинстве случаев это не должно быть проблемой.

Вы можете добавить множество виджетов GUI в JFrame , например, JButton , и т.д. JLabel Однако они будут автоматически добавлены в связанную панель содержимого.

JPanel не обрабатывает позиционирование объектов, LayoutManager связанное с вашей панелью; либо автоматически на основе собственного набора правил (например FlowLayout ), либо с использованием ограничений, которые вы указали при добавлении объекта в контейнер ( GridBagLayout хорошим примером является менеджер компоновки). JavaDoc в LayoutManagers обычно содержит достаточно информации, чтобы вы начали их использовать.

Да, у вас могут быть вложенные панели. A Container может содержать другие Container экземпляры. Хотя это кажется сложным решением, оно позволяет вам точно контролировать, как отображается ваш графический интерфейс. В зависимости от того, что LayoutManager вы используете, от потребностей, которые вы должны выполнить с помощью своего пользовательского интерфейса, и от ваших собственных предпочтений / привычек разработчика, вам может потребоваться меньше или больше вложенных панелей.

Комментарии:

1. Запутался… когда мы должны использовать setcontentpane и getContentPane()? Ссылаются ли они на поле в JFrame или что-то в этом роде?

2. setContentPane() следует использовать редко, по крайней мере, мне никогда не приходилось его использовать. getContentPane() следует использовать каждый раз, когда вы хотите добавить виджет GUI в JFrame . К чему именно они относятся, так это к деталям реализации, которые не должны влиять на вашу работу. Важно помнить, что при вызове getContentPane() вы получите Container то, что используется для отображения вашего пользовательского интерфейса.

3. Я смотрел на API. По-видимому, setContentPane возвращает ссылку на тот же объект, на который ссылается getContentPane, я так или иначе думаю. Однако я не понимаю кое-чего еще… Мне не очень нравится создавать потоки за такое короткое время, поэтому могу я спросить здесь? Почему я должен вызывать setJMenuBar для отображения фрейма? Похоже, ни один веб-сайт не отвечает на этот вопрос. И что это значит, что JFrame имеет много слоев. Это больше всего сбивает с толку.

4. @LewsTherin javadoc for setContentPane() упоминает, что возвращаемый тип равен void , поэтому ссылка на панель содержимого не возвращается ( ссылка ). И вы должны вызвать setMenuBar() метод, потому JFrame что обрабатывает отображение строки меню, так что вам не нужно беспокоиться об этом. Учебные пособия по Java содержат хорошую статью о контейнерах верхнего уровня, например JFrame ( ссылка ).

5. Я имел в виду getContentPane() и setContentPane(), я написал это наоборот: ( Хороший улов: P Спасибо за ссылки.

Ответ №4:

Вам нужно просмотреть этот документ API для JComponent .

Если вы посмотрите на иерархию наследования, вы увидите, что JComponent расширяется Component , поэтому JComponent является компонентом.

Также в разделе «Прямые известные подклассы» вы можете увидеть список всех классов, которые расширяют JComponent , включая JMenuBar и JPanel .

Итак, JMenuBar и JPanel есть две более специализированные версии JComponent (или Container ).