Несколько раз меня критиковали за то, что я предложил использовать следующие методы:
- setPreferredSize
- setMinimumSize
- setMaximumSize
на Swing
комплектующие. Я не вижу альтернативы их использованию, когда я хочу определить пропорции между отображаемыми компонентами. Мне сказали это:
С раскладками ответ всегда один и тот же: используйте подходящий LayoutManager
Я немного искал в Интернете, но я не нашел всестороннего анализа предмета. Итак, у меня есть следующие вопросы:
- Должен ли я полностью избегать использования этих методов?
- Методы были определены по причине. Так, когда я должен использовать их? В каком контексте? Для каких целей?
- Каковы конкретно негативные последствия использования этих методов? (Я могу только подумать о добавлении переносимости между системами с разным разрешением экрана).
- Я не думаю, что любой LayoutManager может точно удовлетворить все желаемые потребности макета. Действительно ли мне нужно реализовывать новый LayoutManager для каждого небольшого изменения моего макета?
- Если ответ на 4 «да», не приведет ли это к увеличению числа классов LayoutManager, которые будет трудно поддерживать?
- В ситуации, когда мне нужно определить пропорции между дочерними элементами компонента (например, child1 должен использовать 10% пространства, child2 40%, child3 50%), возможно ли достичь этого без реализации пользовательского LayoutManager?
источник
JEditorPane
с HTML, который сам по себе не предлагает ширину. ОТО Я не уверен, что я что-то пропустил. Я внимательно рассмотрю ответы в ветке, но мне было интересно, есть ли у вас какие-либо комментарии, особенно по поводу последнего случая.Несколько эвристик:
Не используйте,
set[Preferred|Maximum|Minimum]Size()
когда вы действительно хотите переопределитьget[Preferred|Maximum|Minimum]Size()
, как это может быть сделано при создании собственного компонента, показанного здесь .Не используйте,
set[Preferred|Maximum|Minimum]Size()
когда вы можете положиться на тщательно переопределенный компонентgetPreferred|Maximum|Minimum]Size
, как показано здесь и ниже.Используйте
set[Preferred|Maximum|Minimum]Size()
для получения пост-validate()
геометрии, как показано ниже и здесь .Если у компонента нет предпочтительного размера, например
JDesktopPane
, вам может потребоваться определить размер контейнера, но любой такой выбор является произвольным. Комментарий может помочь уточнить намерения.Рассмотрите альтернативные или пользовательские макеты, когда вы обнаружите, что вам придется пройтись по многим компонентам, чтобы получить производные размеры, как упомянуто в этих комментариях .
источник
setPreferredSize()
всегда заменяет вычисление компонента произвольным выбором.Нет, нет никаких официальных доказательств того, что использование или переопределение этих методов не допускается. Фактически, Oracle говорит, что эти методы используются для предоставления подсказок по размеру: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment .
Они также могут быть переопределены (что является наилучшей практикой для Swing) при расширении компонента Swing (вместо вызова метода в экземпляре пользовательского компонента)
Самое главное, независимо от того, как вы указываете размер вашего компонента, убедитесь, что контейнер вашего компонента использует менеджер компоновки, который учитывает запрошенный размер компонента.
Когда вам нужно предоставить настраиваемые подсказки по размеру для диспетчера макетов контейнеров, чтобы компонент был хорошо размечен
Многие менеджеры компоновки не обращают внимание на максимальный размер запрошенного компонента. Впрочем,
BoxLayout
иSpringLayout
делай. Кроме того,GroupLayout
предоставляет возможность явно задавать минимальный, предпочтительный или максимальный размер, не касаясь компонента.Убедитесь, что вам действительно нужно установить точный размер компонента. Каждый компонент Swing имеет свой предпочтительный размер в зависимости от используемого шрифта и внешнего вида. Таким образом, наличие установленного размера может привести к различному внешнему виду пользовательского интерфейса в разных системах.
иногда могут возникать проблемы с
GridBagLayout
текстовыми полями, причем, если размер контейнера меньше предпочтительного размера, используется минимальный размер, что может привести к значительному сокращению текстовых полей.JFrame
не применяет переопределение,getMinimumSize()
только вызываяsetMinimumSize(..)
его работыЕсли под реализацией вы подразумеваете использование, то да. Не каждый
LayoutManger
может справиться со всем, у каждогоLayoutManager
есть свои плюсы и минусы, поэтому каждый может быть использован вместе для создания окончательного макета.Ссылка:
источник
setXxxSize
методы как красный флаг, который я могу поставить здесь , даже когда это предложат документы. Я почти всегда должен был переопределитьgetXxxSize
, где каждый имеет доступ к необходимой геометрии; и даже короткие примеры перерабатываются больше, чем я хочу думать. +1 за упоминание вариаций среди менеджеров по макету и цитирование учебника.Здесь есть много хороших ответов, но я хочу добавить немного больше о причинах, по которым вам следует избегать их (вопрос только что снова возник в дублирующей теме):
За некоторыми исключениями, если вы используете эти методы, вы, вероятно, настраиваете свой графический интерфейс, чтобы он хорошо выглядел под конкретный внешний вид (и с вашими системными настройками, например, предпочитаемым шрифтом рабочего стола и т. Д.). Сами методы не являются по своей природе зол, но типичные причины для их использования являются . Как только вы начинаете настраивать положения и размеры пикселей в макете, вы рискуете сломать графический интерфейс (или, как минимум, выглядеть плохо) на других платформах.
Как пример этого, попробуйте изменить внешний вид вашего приложения по умолчанию. Даже с опциями, доступными на вашей платформе, вы можете быть удивлены тем, насколько плохо могут быть получены результаты.
Таким образом, во имя поддержания функциональности и привлекательности графического интерфейса пользователя на всех платформах (помните, одним из основных преимуществ Java является его кроссплатформенность), вам следует полагаться на менеджеры компоновки и т. Д., Чтобы автоматически настраивать размеры ваши компоненты, чтобы он правильно отображался за пределами вашей конкретной среды разработки.
Все это говорит о том, что вы, конечно, можете представить себе ситуации, когда эти методы оправданы. Опять же, они по сути не злые, но их использование обычно представляет собой большой красный флаг, указывающий на потенциальные проблемы с графическим интерфейсом. Просто убедитесь, что вы знаете о высокой вероятности возникновения осложнений, если / когда вы их используете, и всегда старайтесь думать о том, есть ли другое решение ваших проблем, не зависящее от внешнего вида - чаще всего вы обнаружите, что это методы не нужны.
Кстати, если вы разочаровались в стандартных менеджерах компоновки, есть много хороших бесплатных сторонних разработчиков с открытым исходным кодом, например, JGoodies '
FormLayout
, илиMigLayout
. Некоторые сборщики GUI даже имеют встроенную поддержку сторонних менеджеров компоновки - например, редактор GUI Windowclipder от Eclipse поставляется с поддержкойFormLayout
иMigLayout
.источник
JTextField.setColumns
для установки количества столбцов, которое соответственно изменяет предпочтительный размер. Если вы это сделаете,setPreferredSize
то вы жестко закодируете размер, который нарушит ваши макеты в зависимости от размера шрифта платформы. Вот некоторые текстовые поля в макете мешка сетки сsetColumns
соответствующим названием . Для ваших кнопок используйте соответствующие макеты / веса сетки для контроля размеров.Если у вас возникли проблемы с раскладками в Java Swing, то я очень рекомендую JGoodies
FormLayout
предоставляемое свободно в рамках форм бесплатной библиотеки Карстен Lentzsch здесь .Этот очень популярный менеджер макетов чрезвычайно гибок, что позволяет разрабатывать очень отлаженные пользовательские интерфейсы Java.
Вы найдете документацию Karsten здесь , и некоторые довольно хорошие документы от затмения здесь .
источник
Эти методы плохо поняты большинству людей. Вы не должны абсолютно игнорировать эти методы. Это зависит от менеджера макета, если они соблюдают эти методы. На этой странице есть таблица, показывающая, какие менеджеры по компоновке соблюдают какой из этих методов:
http://thebadprogrammer.com/swing-layout-manager-sizing/
Я пишу код Swing уже более 8 лет, и менеджеры по компоновке, включенные в JDK, всегда удовлетворяли мои потребности. Я никогда не нуждался в стороннем менеджере по расположению, чтобы достигнуть моих расположений.
Я скажу, что вы не должны пытаться давать подсказки менеджера компоновки с этими методами, пока вы не уверены, что они вам нужны. Сделайте макет, не давая никаких подсказок по размеру (т.е. позвольте менеджеру макета делать свою работу), и тогда вы можете внести незначительные исправления, если вам нужно.
источник
Может быть
GridBagLayout
, удовлетворит ваши потребности. Кроме того, в сети есть куча менеджеров компоновки, и я уверен, что есть тот, который соответствует вашим требованиям.источник
Я вижу это иначе, чем принятый ответ.
1) Должен ли я полностью избегать использования этих методов?
Никогда не избегай! Они там, чтобы выразить ограничения размера ваших компонентов в менеджере макета. Вы можете избежать их использования, если вы не используете какой-либо менеджер макетов и попробуйте самостоятельно управлять визуальным макетом.
К сожалению, Swing не поставляется с разумными размерами по умолчанию. Однако вместо того, чтобы устанавливать размеры компонента, лучше ООП спускать свой собственный компонент с разумными значениями по умолчанию. (В этом случае вы вызываете setXXX в своем классе-потомке.) Кроме того, вы можете переопределить методы getXXX для того же эффекта.
2) Методы были определены по причине. Так, когда я должен использовать их? В каком контексте? Для каких целей?
Всегда. При создании компонента установите его реалистичный минимальный / предпочтительный / максимальный размер в соответствии с использованием этого компонента. Например, если у вас есть JTextField для ввода символов страны, таких как Великобритания, его предпочтительный размер должен быть таким же широким, чтобы соответствовать двум символам (с текущим шрифтом и т. Д.), Но, вероятно, не имеет смысла позволять ему расти еще больше. Ведь символы страны - это две буквы. Напротив, если у вас есть JTextField для ввода, например, имени клиента, он может иметь предпочтительный размер, например размер пикселя для 20 символов, но может увеличиваться до большего при изменении размера макета, поэтому установите максимальный размер больше. В то же время иметь JTextField шириной 0px бессмысленно, поэтому установите реалистичный минимальный размер (я бы сказал, размер пикселя 2 символа).
3) Каковы конкретно негативные последствия использования этих методов?
(Я могу только подумать о добавлении переносимости между системами с разным разрешением экрана).
Никаких негативных последствий. Это подсказки для менеджера макета.
4) Я не думаю, что любой LayoutManager может точно удовлетворить все желаемые потребности макета.
Действительно ли мне нужно реализовывать новый LayoutManager для каждого небольшого изменения моего макета?
Нет, определенно нет. Обычный подход состоит в том, чтобы каскадировать различные базовые менеджеры компоновки, такие как горизонтальная и вертикальная компоновка.
Например, макет ниже:
имеет две части. Левая и правая части представляют собой горизонтальное расположение. Правая часть представляет собой JPanel, добавленный к горизонтальной компоновке, и эта JPanel имеет вертикальную компоновку, которая размещает кнопки вертикально.
Конечно, это может быть сложно с реальным макетом жизни. Поэтому менеджеры компоновки на основе сетки, такие как MigLayout, намного лучше, если вы собираетесь разрабатывать что-то серьезное.
5) Если ответ на вопрос «4» - «да», не приведет ли это к увеличению числа классов LayoutManager, которое будет трудно поддерживать?
Нет, вы определенно не будете разрабатывать менеджеры по расположению, если вам не нужно что-то очень особенное.
6) В ситуации, когда мне нужно определить пропорции ...
между дочерними компонентами (например, child1 должен использовать 10% пространства, child2 40%, child3 50%), возможно ли достичь этого без реализации пользовательского LayoutManager?
Как правило, после того, как предпочтительные размеры установлены правильно, вы можете не захотеть ничего делать в процентах. Просто потому, что проценты не имеют смысла (например, бессмысленно иметь JTextField в 10% размера окна - поскольку можно уменьшить окно, чтобы JTextField стал шириной 0px, или можно расширить окно, чтобы JTextField находился на двух дисплеях на экране. настройка нескольких дисплеев).
Но иногда вы можете использовать проценты для управления размерами больших строительных блоков вашего графического интерфейса (например, панелей).
Вы можете использовать JSplitPane, где вы можете предварительно установить соотношение двух сторон. Или вы можете использовать MigLayout, который позволяет вам устанавливать такие ограничения в процентах, пикселях и других единицах.
источник
btnBar.setPreferredSize( dimTouchBtn );
это лучший способ сделать это. Просто, нет необходимости в настраиваемом менеджере компоновки. Я использую в основномGridBagLayout
с некоторымиBorderLayout
иBoxLayout
, когда это удобно. Это сильная комбинация и проста в использовании.Должен ли я полностью избегать использования этих методов? Я бы не сказал «избегать» их. Я бы сказал, что если вы думаете, что они вам нужны, вы, вероятно, делаете что-то не так. Размеры компонентов определяются в контексте. Например, размеры текстового компонента определяются указанным количеством строк и столбцов в сочетании с выбранным вами шрифтом. Размер вашей кнопки и метки будет соответствовать размеру графического изображения, если вы его установили, или месту, необходимому для отображения заданного вами текста. Каждый компонент имеет естественный размер, и менеджеры компоновки будут использовать его для разметки всего, без необходимости указывать размеры. Основным исключением является JScrollPane, размер которого не зависит от содержимого. Для них я иногда буду звонить
setSize()
, и пусть этот размер определяет начальный размер окна, вызываяJFrame.pack()
, Обычно я позволяю размеру окна определять размер JScrollPane. Пользователь определит размер окна. Многие менеджеры компоновки игнорируют установленные вами размеры, поэтому они часто не приносят пользы.Методы были определены по причине. Так, когда я должен использовать их? В каком контексте? Для каких целей? Я полагаю, что они были добавлены, чтобы предоставить подсказки менеджерам по расположению. Возможно, они были написаны по историческим причинам, потому что менеджеры по компоновке были новыми, и люди не полностью доверяли им. Я знаю нескольких разработчиков, которые избегали менеджеров компоновки и размещали все вручную только потому, что не хотели беспокоиться о изучении новой парадигмы. Это ужасная идея.
Каковы конкретно негативные последствия использования этих методов? (Я могу только подумать о добавлении переносимости между системами с разным разрешением экрана). Они неэффективны и создают плохие макеты, при этом объекты сжимаются или растягиваются до неестественных размеров. И макеты будут хрупкими. Изменения в размере окна иногда нарушают компоновку и помещают вещи в неправильные места.
Я не думаю, что любой LayoutManager может точно удовлетворить все желаемые потребности макета. Действительно ли мне нужно реализовывать новый LayoutManager для каждого небольшого изменения моего макета? Вы не должны «реализовывать» новый LayoutManager. Вы должны создать экземпляр существующих. Я часто использую несколько менеджеров компоновки в одном окне. Каждый JPanel будет иметь свой собственный менеджер макета. Некоторые люди отказываются от вложенных макетов, потому что их сложно поддерживать. Когда я их использую, я даю каждому свой метод создания, чтобы было легче увидеть, что делает каждый. Но я никогда не «внедряю» менеджер раскладок. Я просто создаю их экземпляр.
Если ответ на 4 «да», не приведет ли это к увеличению числа классов LayoutManager, которые будет трудно поддерживать? Если вы реализуете новые классы менеджера компоновки для небольших изменений в компоновке, вы используете их неправильно. Если вы просто внедряете новые менеджеры компоновки, вы, вероятно, делаете что-то не так. Единственный раз, когда я расширил класс LayoutManager, это было добавить ползунок масштабирования в JScrollPane.
В ситуации, когда мне нужно определить пропорции между дочерними элементами компонента (например, child1 должен использовать 10% пространства, child2 40%, child3 50%), возможно ли достичь этого без реализации пользовательского LayoutManager? В JSplitPane есть способ указать процент, который должен получить каждый компонент. По умолчанию разделитель является подвижным, но вы можете отключить его, если хотите. Я не пользуюсь этой функцией много. У меня обычно есть некоторые компоненты, которые занимают заданный размер, а остальное пространство занимает область прокрутки. Размер области прокрутки будет регулироваться в зависимости от размера окна. Если у вас есть две панели прокрутки рядом, вы можете поместить их в JSplitPane и указать процент нового пространства, выделенного для каждой из них, когда пользователь расширяет и сжимает окна.
источник