#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
).