Статьи

SWT ScrolledComposite объяснил

Как однажды сказал мой друг, SWTs ScrolledComposite — отвратительный зверь. И в какой-то момент я согласен. Это, вероятно, причина, почему так много вопросов задают о том, как использовать этот виджет.

Но виноваты не только авторы ScrolledComposite. Когда часть программного обеспечения работает не так, как вы ожидаете, тогда… вы ругаетесь… и пробуете немного по-другому… и ругаетесь по-другому… и просите Google о помощи… и (надеюсь) найти этот прекрасный маленький пост. Что говорит вам: RTFM! — ups, эм, я имею в виду, конечно, взглянуть на документацию.

И если вы прочтете JavaDoc, вы узнаете, что есть два способа использования ScrolledComposite, и увидите соответствующий пример кода.

Два в одном

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

В качестве альтернативы, при соответствующей настройке ScrolledComposite имитирует работу браузера. Содержимое будет увеличиваться и уменьшаться в зависимости от размера ScrolledComposite — пока видимая область не станет меньше указанного минимального размера. В последнем случае полосы прокрутки будут показаны, и содержание никогда не будет уменьшено ниже минимального размера.

Видео показывает различные режимы работы рядом:

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

Прокрутка фиксированного контента

Настроить ScrolledComposite для отображения фиксированного контента очень просто:

1
2
3
4
5
scrolledComposite = new ScrolledComposite( parent, SWT.H_SCROLL | SWT.V_SCROLL );
Label label = new Label( scrolledComposite, SWT.NONE );
label.setBackground( display.getSystemColor( SWT.COLOR_DARK_GREEN ) );
label.setSize( 400, 400 );
scrolledComposite.setContent( label );

Обратите внимание, что вам нужно явно указать флаги стиля H_SCROLL и V_SCROLL . В противном случае полосы прокрутки не создаются, а ScrolledComposite оказывается бесполезным ( подробнее о полосах прокрутки позже ).

Другая заслуживающая внимания часть фрагмента — это то, где создается контент — зеленая метка размером 400 x 400 пикселей. Родителем контента должен быть сам ScrolledComposite. Если нет, вы увидите смешные результаты. И, наконец, ScrolledComposite нужно сообщить содержимому, что он должен управлять с помощью setContent ().

В примере демонстрируется простейший случай, когда содержимое является единым элементом управления. Если, однако, содержимое для прокрутки состоит из нескольких элементов управления, их необходимо обернуть в Composite с подходящим макетом, как показано в примере с контактными данными .

Контент с фиксированным размером в этом контексте не означает, что контент должен или не может изменить свой размер. В этом случае ScrolledComposite адаптируется к новому размеру и соответственно отображает или скрывает полосы прокрутки. Контент, однако, не меняет свой размер, если ScrolledComposite изменил его размер.

Прокрутка Расширение Контента

С помощью нескольких дополнительных строк приведенный выше фрагмент можно расширить, чтобы расширить его содержимое:

1
2
3
scrolledComposite.setExpandHorizontal( true );
scrolledComposite.setExpandVertical( true );
scrolledComposite.setMinSize( 250, 250 );

После этого ScrolledComposite будет расширять содержимое при изменении его размера и отображать полосы прокрутки только в том случае, если его размер уменьшен, чтобы он был меньше минимального размера. SWT API предлагает дополнительные способы установки минимального размера. Либо для минимальной ширины и высоты независимо с помощью setMinWidth () и setMinHeight (), либо с помощью setMinSize (Point).

Допустимо устанавливать минимальный размер на ноль (значение по умолчанию) при расширении контента. В результате содержимое будет сокращаться без нижнего предела, и полосы прокрутки не будут отображаться.

Это два основных режима ScrolledComposite: управление содержимым фиксированного размера или расширение и уменьшение содержимого.

Прокрутка только по вертикали

Другой вариант использования, с которым я столкнулся, — это список еще неизвестной длины элементов. Подумайте о длинной контактной форме с множеством строк, каждая из которых состоит из метки и поля ввода. Ширина каждой строки занимает столько места, сколько есть, но если число строк превышает доступную высоту, ее следует прокручивать.

С небольшим изменением, показанный выше расширяющийся ScrolledComposite может быть расширен для прокрутки только по вертикали. Ключевым моментом здесь является динамическая установка минимального размера. Всякий раз, когда ScrolledComposite изменяет свой размер, минимальная ширина содержимого устанавливается равной доступной ширине ScrolledComposite.

Код для выполнения описанного поведения довольно прост:

1
2
3
4
scrollComposite.addListener( SWT.Resize, event -> {
  int width = scrollComposite.getClientArea().width;
  scrollComposite.setMinSize( parent.computeSize( width, SWT.DEFAULT ) );
} );

Слушатель изменения размера запрашивает доступное пространство ScrolledComposite с помощью getClientArea ()
и вычисляет необходимый размер для контента, учитывая ширину клиентских областей. Наконец, результирующий размер устанавливается как минимальный размер ScrolledComposite.

В этом примере внешний вид содержимого определяется макетом из двух столбцов. Столбец метки имеет ширину, необходимую для отображения самой длинной метки, а в столбце поля ввода используется оставшаяся ширина. Каждая строка в свою очередь использует оптимальную высоту (т. Е. Настолько высока, насколько это необходимо для отображения поля ввода с одной линией).

Несмотря на то, что я не видел сценарий использования в реальном мире, этот подход также сработал бы при горизонтальном расширении.

Вычисление предпочтительного размера для ScrolledComposite

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

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

Сама формула проста:

1
2
numberOfItems = 10
initialHeight = numberOfItems * ( itemHeight + spacing )

Дальнейшим уточнением будет проверка полученной высоты по размеру экрана и уменьшение ее при необходимости.

Получившийся макет хорошо масштабируется на разных платформах, разрешениях экрана и настройках шрифтов. Если это вас заинтересует, вы также можете прочитать отзывчивый пользовательский интерфейс с Eclipse и SWT .

Вертикальная и горизонтальная полоса прокрутки

Чтобы получить полосы прокрутки, используйте getVerticalBar () и getHor HorizontalBar () соответственно. Как видно из фрагментов, флаги стиля V_SCROLL и H_SCROLL должны быть указаны для создания вертикальных и / или горизонтальных полос прокрутки. Если соответствующий флаг стиля опущен, полоса прокрутки не создается, и getVerticalBar () или getHorizontBar () возвращают ноль.

Однако существующие полосы прокрутки могут быть показаны или скрыты, включены или отключены в любое время. По умолчанию ScrolledComposite показывает полосы прокрутки только при необходимости, но с помощью setAlwaysShowScrollBars () это поведение можно изменить, чтобы всегда показывать полосы прокрутки. Поэтому вы обычно хотите создать обе полосы прокрутки и позволить ScrolledComposite решать, когда показывать или скрывать отдельные полосы.

В общем, имейте в виду, что полосы прокрутки управляются ScrolledComposite. Следовательно, безопасно запрашивать их состояние, но манипулирование свойствами, скорее всего, будет мешать взгляду ScrolledComposite на вещи.

Чтобы изменить положение полос прокрутки для отображения определенных частей содержимого, используйте указанные методы, описанные ниже.

Единственным исключением из вышеперечисленного может быть включенное состояние полос прокрутки. Если это действительно желательно, то вызывать setEnabled () должно быть безопасно.

Прокрутка в Просмотр

ScrolledComposite имеет несколько методов для изменения положения полосы прокрутки. Основным является setOrigin (). Он прокручивает элемент управления содержимым, чтобы указанная точка в содержимом находилась в верхнем левом углу. Желаемая позиция может быть задана как отдельные координаты x и y или как точка. И, следовательно, есть метод getOrigin (), который возвращает точку, которая в данный момент отображается в верхнем левом углу.

Чтобы избавить клиентов от некоторого отображения координат, есть метод showControl (), который основывается на setOrigin () и прокручивает содержимое, чтобы данный элемент управления был видимым.

И если сфокусированный элемент управления всегда должен быть видимым, ScrolledComposite можно посоветовать с помощью setShowFocusedControl () автоматически прокрутить сфокусированный элемент управления в поле зрения.

Завершение SWT ScrolledComposite

Действительно, ScrolledComposite — не самый интуитивно понятный виджет в коллекции SWT, и я надеюсь, что рецепты, представленные здесь, помогут лучше ладить с ним. Обсуждаемые здесь варианты использования — это те, с которыми я столкнулся в основном до сих пор Тем не менее, мне было бы интересно узнать о дальнейшем использовании, и если вы хотите поделиться своим, пожалуйста, оставьте комментарий.

  • Показанные фрагменты представляют собой выдержки из небольших, готовых к запуску примеров программ, которые можно найти здесь: https://gist.github.com/rherrmann/b1a2a633cd4c9b607fe7

И последнее, но не менее важное: я хотел бы отметить, что все представленные здесь концепции и код не только применимы к SWT, но и одинаково хорошо работают в браузере с Eclipse RAP . Вы даже можете использовать эту онлайн-демонстрацию RAP, чтобы изменить различные флаги и свойства и сразу увидеть их эффект.

Ссылка: SWT ScrolledComposite Объяснено нашим партнером по JCG Рудигером Херрманном в блоге Code Affine .