Статьи

Pivot: практический пример, часть 1 — разметка пользовательского интерфейса с использованием WTKX

Это первая из пяти статей, в которых рассказывается о реализации простого, но практичного приложения Pivot под названием Stock Tracker . Этот раздел посвящен построению пользовательского интерфейса с использованием WTKX, языка разметки Pivot XML. Следующая статья будет посвящена обработке событий в Pivot.

Пользовательский интерфейс приложения Pivot часто определяется с использованием разметки XML, а не кода Java. Это потому, что XML может быть значительно проще для чтения и работы, чем обычная Java. Иерархическая структура XML-документа более точно соответствует структуре иерархии компонентов, что упрощает визуализацию полученного результата.

Pivot позволяет разработчикам разделить определение пользовательского интерфейса на несколько файлов WTKX. Это позволяет каждому элементу варьироваться независимо и упрощает управление общей структурой. Макет приложения Stock Tracker разделен на два документа WTKX: один задает основную структуру приложения, а другой — макет для детализации цитаты:

Сначала мы рассмотрим разметку верхнего уровня в stocktracker.wtkx, концентрируясь на двух элементах главной страницы, TablePane и TableView. Затем мы исследуем разметку для детализации котировок акций, которая использует контейнер Form и закладывает основу для поддержки связывания данных, которую мы обсудим в следующем разделе.

TablePane

Корневой узел stocktracker.wtkx является элементом TablePane. TablePane — это тип контейнера макета, который упорядочивает свои дочерние элементы аналогично таблице HTML.

Как и таблицы HTML, содержимое TablePane организовано в строки и столбцы. Однако, в отличие от HTML, который может попытаться вывести структуру таблицы из ее содержимого, структура TablePane должна быть определена заранее, как показано ниже:

<TablePane styles="{padding:8, spacing:6}">
<rows>
<Row height="-1"/>
<Row height="1*"/>
<Row height="-1"/>
<Row height="-1"/>
</rows>
<columns>
<Column width="244"/>
<Column width="1*"/>
</columns>
...
</TablePane>

Высоты строк и ширины столбцов в TablePane можно указывать как автоматические, абсолютные или относительные:

  • Значение -1 указывает автоматический размер; панель таблицы будет определять высоту строки как максимальную предпочтительную высоту всех компонентов в этой строке; То же самое относится к автоматической ширине столбца.

  • Явное неотрицательное значение определяет абсолютную ширину или высоту, указанную в пикселях.

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

В приведенном выше примере второй строке присваивается относительная высота, которая назначит ему все доступное пространство после учета других строк; все остальные ряды имеют автоматическую высоту. Первый столбец имеет явную ширину 244 пикселя, а второй столбец — 100% оставшейся ширины.

На следующем рисунке показан итоговый макет (синие линии представляют границы ячеек таблицы):

Ячейки панели таблицы Stock Tracker

Стили

Обратите внимание на стили атрибута элемента TabPane. Стили используются для настройки внешнего вида компонента и указываются в WTKX как коллекция пар имя / значение в формате JSON. Все элементы WTKX поддерживают атрибут styles , но каждый элемент может поддерживать различный набор стилей в зависимости от установленной в данный момент темы оформления.

В этом примере для TablePane назначается значение отступа 8 и значение интервала 6. Заполнение представляет собой объем пространства, которое панель таблицы оставит вокруг своих компонентов, а интервал — это размер промежутка, оставленного панелью таблицы. составные части.

Ячейки в виде таблицы

Фактическое содержимое панели таблицы указывается в элементе <ячейки> . Каждый непосредственный дочерний элемент элемента <cell> считается дочерним компонентом панели таблицы. Строка и столбец, в которые будет помещен дочерний элемент, определяются атрибутами строки и столбца, прикрепленными к подэлементу, как показано ниже:

<Label row="0" column="0" text="%stockTracker"
styles="{font:'Verdana bold 14', verticalAlignment:'center'}"/>

Обратите внимание на использование символа процента в значении текстового атрибута. Это говорит загрузчику компонентов WTKX, что значение текстового атрибута должно быть представлено строкой ресурса с именем, указанным в атрибуте, за вычетом знака процента. Это будет обсуждаться более подробно в разделе «Локализация».

TableView

Компонент TableView используется для представления табличных данных в виде сетки строк и столбцов. Хотя он имеет внешнее сходство с TablePane, назначение этих двух компонентов совершенно различно: TablePane — это контейнер; его основная цель заключается в размещении подкомпонентов, а его структура чаще всего определяется во время разработки. TableView — это компонент, который действует как представление набора данных модели и чаще всего заполняется во время выполнения.

Как и TablePane, столбцы TableView должны быть определены заранее. Однако, поскольку содержимое табличного представления обычно не известно до времени выполнения, нет необходимости определять структуру строк табличного представления — это обеспечивается данными модели табличного представления при заполнении табличного представления.

TableView используется демонстрационной программой Stock Tracker для отображения выбираемого списка данных котировок акций. Следующий листинг показывает разметку, используемую демонстрацией для создания табличного представления:

<TableView id="stocksTableView" selectMode="multi"
styles="{showHorizontalGridLines:false}">
<columns>
<Column name="symbol" headerData="'%symbol'" width="80"/>
<Column name="value" headerData="'%value'" width="80"
cellRenderer="pivot.wtk.content.TableViewNumberCellRenderer"
cellRendererStyles="{horizontalAlignment:'right'}"
cellRendererProperties="{numberFormat:'$0.00'}"/>

<Column name="change" headerData="'%change'" width="80"
cellRenderer="pivot.tutorials.stocktracker.ChangeCellRenderer"
cellRendererStyles="{horizontalAlignment:'right'}"
cellRendererProperties="{numberFormat:'+0.00;-0.00'}"/>
</columns>
</TableView>

Обратите внимание, что TableView присваивается значение атрибута id «stocksTableView». Это используется для связи табличного представления с экземпляром TableViewHeader, который обсуждается в следующем разделе. Значения идентификаторов также используются для получения доступа к компонентам WTKX из кода Java при подключении обработчиков событий. Это будет обсуждаться более подробно в следующем разделе об обработке событий.

SelectMode = «мульти» атрибут указывает , что пользователь может выбрать несколько строк в этом виде таблицы. Другими возможными значениями для selectMode являются «single» и «none». Если для стиля showHor horizontalGridLines задано значение false, табличное представление не будет рисовать горизонтальные линии сетки, разделяющие его ячейки. Вертикальные линии сетки все еще будут нарисованы; однако их также можно отключить, установив для showVerticalGridLines значение false .

Столбцы Столбца

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

Ширина каждого столбца в этом примере установлена ​​на абсолютное значение 80 пикселей. Столбцам табличного представления также можно назначить относительную ширину, но они не поддерживают автоматическую ширину, поддерживаемую компонентом TablePane.

Столбцы «value» и «change» определяют несколько дополнительных атрибутов, связанных с средствами визуализации ячеек. По умолчанию ячейки таблицы отрисовываются с использованием средства визуализации, которое представляет содержимое ячейки в виде текстовой строки. Пользовательские средства визуализации ячеек могут использоваться для представления данных ячейки, отформатированных в виде числа, даты или иным образом. Демонстрация Stock Tracker использует встроенное средство визуализации числовых ячеек для форматирования столбца значений и настраиваемое средство визуализации для отображения значений в столбце изменений с использованием красного или зеленого текста в зависимости от направления изменения. Полное обсуждение средств визуализации ячеек выходит за рамки данного руководства, но исходный код пользовательского средства визуализации можно посмотреть здесь .

TableViewHeader

Компонент TableView Pivot не включает поддержку встроенных заголовков; скорее поддержка заголовков столбцов и изменение их размеров обеспечивается компонентом TableViewHeader. Это связано с тем, что TableView (и другие подобные компоненты, включая ListView и TreeView) не включают встроенную поддержку прокрутки. Прокрутка обеспечивается классом ScrollPane, который обсуждается в следующем разделе.

Представление таблицы Stock Tracker и заголовок таблицы

Следующая разметка используется для объявления компонента заголовка табличного представления для демонстрации Stock Tracker:

<TableViewHeader tableViewID="stocksTableView"/>

Это оно! Заголовок автоматически связывается с табличным представлением, идентифицированным атрибутом tableViewID — никакой дополнительной разметки или кодирования не требуется.

Хотя это не показано в демонстрации Stock Tracker, TableViewHeader также может использоваться для поддержки сортировки столбцов. Пример этого показан в демонстрационном приложении «кухонная раковина» .

ScrollPane и Border

Компоненты Pivot не управляют внутренней прокруткой — вся прокрутка в Pivot обрабатывается классом ScrollPane (точнее, экземпляром класса Viewport, но это различие не имеет отношения к этому обсуждению). Панель прокрутки обеспечивает оконный вид на другой компонент и позволяет пользователю выбирать, какая часть компонента отображается, перетаскивая горизонтальную или вертикальную полосу прокрутки.

Прокручиваемый компонент называется «представлением» и определяется как дочерний элемент элемента <представление> ScrollPane . ScrollPane также обеспечивает поддержку фиксированных заголовков строк и столбцов, которые прокручиваются вместе с представлением, но всегда остаются видимыми. Они определяются с использованием подэлементов ScrollPane <rowHeader> и <columnHeader> . TableViewHeader часто используется в качестве заголовка столбца для экземпляра TableView, но заголовок строки или столбца может быть экземпляром любого типа компонента — например, разработчик приложения может создать компонент «линейка» для использования в качестве заголовка в программа для рисования, чтобы помочь дизайнеру визуализировать масштаб большого прокручиваемого изображения.

Фондовая Цитата Подробнее

Файл stocktracker.wtkx определяет общую структуру приложения, а компоновка содержимого подробностей цитаты определяется отдельно в stocktracker.detail.wtkx. Однако при запуске приложения создается впечатление, что все приложение было определено в одном файле WTKX. Как это работает? Ключ является тегом компонента:

<Component namespace="detail" src="stocktracker.detail.wtkx"/>

Тег Component действует как своего рода оператор «include» — он сообщает загрузчику компонента, что компонент должен быть размещен здесь, но содержимое компонента не определено в этом файле. Местоположение фактического содержимого указывается тегом src и является либо абсолютным (начиная с символа косой черты), либо относительным (без косой черты) путем к другому файлу WTKX. Относительные пути разрешаются в контексте текущего файла WTKX, а абсолютные пути разрешаются в контексте пути к классам приложения. Полноценные URL (те, которые начинаются с протокола) не поддерживаются.

В дополнение к атрибуту src тегу Component требуется значение для атрибута пространства имен . Это используется для разделения значений идентификаторов, определенных в каждом файле WTKX, на отдельные пространства имен, что позволяет разработчикам избегать конфликтов имен. На компоненты ссылаются путем объединения пространства имен с идентификатором компонента; например, путь «detail.changeLabel» относится к метке с идентификатором «changeLabel», определенной в файле stocktracker.detail.wtkx.

формы

Хотя элементом верхнего уровня страницы сведений является FlowPane, большая часть макета обрабатывается контейнером Form. Формы размещают свои дочерние компоненты в вертикальный стек, аналогично вертикальной FlowPane, добавляя текстовую метку к каждому полю.

Детальный просмотр Stock Tracker с использованием контейнера Form

Метка поля определяется атрибутом метки, прикрепленным к дочернему элементу, как показано ниже:

<Form styles="{rightAlignLabels:true, fieldAlignment:'right'}">
<Label label="%value" textKey="value"/>
<Label id="changeLabel" label="%change" textKey="change"/>
<Label label="%openingValue" textKey="openingValue"/>
<Label label="%highValue" textKey="highValue"/>
<Label label="%lowValue" textKey="lowValue"/>
<Label label="%volume" textKey="volume"/>
</Form>

Так как данные цитаты доступны только для чтения, «поля» в этом примере фактически являются экземплярами Label. Их значения меток формы указываются как строковые ресурсы, поэтому их можно легко перевести.

Привязка данных

Каждая метка в форме определяет атрибут textKey . Этот атрибут указывает имя свойства, из которого метка будет получать свое текстовое значение во время привязки данных. В частности, это имя ключа значения в «контексте привязки», экземпляр Dictionary <String, Object>, который передается в метод load () экземпляра Form, а затем рекурсивно передается в сами метки. Это будет обсуждаться более подробно в разделе привязки данных.

Хотя привязка данных часто используется для заполнения содержимого формы, она может использоваться с любым классом контейнера. Например, компоненты ввода текста в FlowPane также могут быть привязаны к данным, как и представление списка в области карточек; нет ничего особенного в классе Form, который поддерживает привязку данных — он поддерживается всеми типами контейнеров и многими классами компонентов.