ADF Faces framework поддерживает возможность перетаскивания элементов на странице из одного места, в другое. Например перенос строки из одной таблицы в другую, перемещение компонентов на странице или копирование значений из одних объектов в другой.
private List<Digit> sourceTable;
private List<Digit> targetTable;
public DndBean() {
}
public List<Digit> getSourceTable()
{
if (sourceTable == null)
{
sourceTable = new ArrayList<Digit>();
sourceTable.add(new Digit(11));
sourceTable.add(new Digit(12));
sourceTable.add(new Digit(13));
sourceTable.add(new Digit(14));
}
return sourceTable;
}
public List<Digit> getTargetTable()
{
if (targetTable == null)
{
targetTable = new ArrayList<Digit>();
targetTable.add(new Digit(15));
targetTable.add(new Digit(16));
targetTable.add(new Digit(17));
targetTable.add(new Digit(18));
}
return targetTable;
}
public static class Digit implements Serializable
{
private Number digitCol;
private Digit(Number title)
{
digitCol = title;
}
public Number getCol()
{
return digitCol;
}
}
<af:dragSource actions="MOVE" discriminant="rowmove"/>
где actions - действия которые могут выполняться (move,copy,link). У нас будет перемещаться строка, а значит move. То есть в обоих тэгах нужно добавить actions="MOVE".
<af:collectionDropTarget dropListener="#{viewScope.dndBean.handleMove}"
actions="MOVE" modelName="rowmove"/>
9. Завершающим этапом является написание обработки события:
//получение источника
RichTable dragComponent = (RichTable) dropEvent.getDragComponent();
//получение цели
RichTable dropComponent = (RichTable) dropEvent.getDropComponent();
Transferable t = dropEvent.getTransferable();
DataFlavor<RowKeySet> df =
DataFlavor.getDataFlavor(RowKeySet.class, "rowmove");
RowKeySet rks = t.getData(df);
Iterator iter = rks.iterator();
//получение выбранной строки в источнике
ADF Faces поддерживает следующие сценарии:
Когда пользователь нажимает на источник и начинает перемещение, браузер отображает прозрачным перетаскиваемый компонент прикрепленный к указателю мышки.
- Перемещение значения атрибута из одного экземпляра компонента и копирование в другой. Например, пользователь может перенести данные из outputText в inputText .
- Перемещение значения одного объекта в другой объект так, что он становится значением другого объекта.
- Перемещение объекта из одной коллекции в другую.
- Перемещение компонента из одной части страницы в другую.
- Перемещения в компоненте calendar
- Перемещения компонента из или в panelDashboard .
- Перемещения маркера в DVT графиках для изменения значений.
- Перемещение объекта из диаграммы Gantt в другой компонент.
- Прочие перемещения в DVT
Компонент который перемещается и содержит значение называется источником(source). Компонент который принимает перемещаемый компонент, называется целью (target).Для источника и цели нужно использовать определенные тэги ( attributeDragSource, dragSource, componentDragSource,attributeDropTarget,dropTarget,collectionDropTarget,calendarDropTarget,dataFlavor) Ниже показаны возможные сценарии использования Drag and Drop в ADF
Сценарий
|
Источник(Source)
|
Цель(Target)
|
Перемещение
значение атрибута
|
Компонент со значением(с атрибутом
value)
|
Тип атрибута должен
соответствовать переносимому значению
|
Тэг:
attributeDragSource
|
Тэг:
attributeDropTarget
|
|
Перемещение
объекта из одного компонента в другой
|
Любой компонент
|
Любой компонент
|
Тэг:
attributeDragSource
|
Тэг:
dropTarget
|
|
Перемещение
объекта из одной коллекции в другую
|
table, tree, и treeTable компоненты
|
table, tree, and treeTable компоненты
|
Тэг:
dragSource
|
Тэг:
collectionDropTarget
|
|
Перемещение
компонента из одного контейнера в другой
|
Любой компонент
|
Любой компонент
|
Тэг:
componentDragSource
|
Тэг:
dropTarget
|
|
Перемещение
дат в календаре
|
объект calendarActivity
|
компоненты calendar
|
Тэг:
не нужен
|
Тэг:
calendarDropTarget
|
|
Перемещение
panelBox вpanelDashboard
|
компонент panelBox |
компонент panelDashboard
|
Тэг:
componentDragSource
|
Тэг:
dataFlavor
|
|
Перемещение
panelBox из panelDashboard
|
компонент panelBox в panelDashboard компоненте
|
Любой компонент
|
Тэг:
componentDragSource
|
Тэг:
dropTarget
|
|
Перемещение
маркера в DVT graph
|
компонент graph
|
компоненты graph
|
Тэг:
dragSource
|
Тэг:
dropTarget
|
|
Перемещение
объекта из DVT Gantt chart в другой компонент
|
Gantt chart
|
Любой компонент
|
Тэг:
dragSource
|
Тэг:
dropTarget
|
|
Перемещение
узла (ноды) из DVT hierarchy viewer, sunburst, или treemap в другой
компонент
|
hierarchyViewer, sunburst, или treemap компонент
|
Любой компонент
|
Тэг:
dragSource
|
Тэг:
dropTarget
|
|
Перемещение
события из timeline компонента в компоненты и с коллекциями.
|
timeline компоненты
|
table, tree, и treeTable компоненты
|
Тэг:
dragSource
|
Тэг:
collectionDropTarget
|
Для наилучшего понимания drag and drop функциональности создадим приложение с двумя таблицами. И добавим возможность перемещения строк из одной в другую (исходники можно скачать на github: https://github.com/JealousyM/AdfDnd).
1. Создайте ADF Fusion Web Application;
2. Создайте jspx страницу (для вывода таблиц);
3. Создайте managed bean (для инициализации таблиц и обработки drag and drop события);
4. Добавьте в jspx страницу две таблицы(af:table). Что бы упростить приложение, данные будем брать не с БД, а формировать в бине.
<af:panelGroupLayout id="pgl2" layout="horizontal" styleClass="AFStretchWidth">
<af:table var="row" rowBandingInterval="0" id="t1"
value="#{viewScope.dndBean.sourceTable}" rowSelection="single">
<af:column sortable="false" headerText="Source" id="c2">
<af:outputText value="#{row.col}" id="ot1"/>
</af:column>
</af:table>
<af:table var="row" rowBandingInterval="0" id="t2" value="#{viewScope.dndBean.targetTable}"
rowSelection="single">
<af:column sortable="false" headerText="Target" id="c1">
<af:outputText value="#{row.col}" id="ot2"/>
</af:column>
</af:table>
</af:panelGroupLayout>
<af:table var="row" rowBandingInterval="0" id="t1"
value="#{viewScope.dndBean.sourceTable}" rowSelection="single">
<af:column sortable="false" headerText="Source" id="c2">
<af:outputText value="#{row.col}" id="ot1"/>
</af:column>
</af:table>
<af:table var="row" rowBandingInterval="0" id="t2" value="#{viewScope.dndBean.targetTable}"
rowSelection="single">
<af:column sortable="false" headerText="Target" id="c1">
<af:outputText value="#{row.col}" id="ot2"/>
</af:column>
</af:table>
</af:panelGroupLayout>
5. В bean-е создайте две переменных типа List<Digit> (Digit внутренний класс в бине, для вывода данных в таблице) и заполните их данными:
private List<Digit> sourceTable;
private List<Digit> targetTable;
public DndBean() {
}
public List<Digit> getSourceTable()
{
if (sourceTable == null)
{
sourceTable = new ArrayList<Digit>();
sourceTable.add(new Digit(11));
sourceTable.add(new Digit(12));
sourceTable.add(new Digit(13));
sourceTable.add(new Digit(14));
}
return sourceTable;
}
public List<Digit> getTargetTable()
{
if (targetTable == null)
{
targetTable = new ArrayList<Digit>();
targetTable.add(new Digit(15));
targetTable.add(new Digit(16));
targetTable.add(new Digit(17));
targetTable.add(new Digit(18));
}
return targetTable;
}
public static class Digit implements Serializable
{
private Number digitCol;
private Digit(Number title)
{
digitCol = title;
}
public Number getCol()
{
return digitCol;
}
}
Если запустить приложение, то можно увидеть что таблицы заполнены. Теперь нужно добавить к ним drag and drop функциональность . Исходя из верхней таблицы нам нужно использовать тэги dragSource и collectionDropTarget.
6. Добавьте внутрь первой таблицы тэг dragSource (эта таблица у нас будет Источником) , и collectionDropTarget во вторую (эта таблица у нас будет Целью).
Этого мало, что бы всё заработало. Дальше нужно прописать необходимые атрибуты в тэгах и написать обработчик события.
7. В dragSource пропишите следующие свойства:
<af:dragSource actions="MOVE" discriminant="rowmove"/>
где actions - действия которые могут выполняться (move,copy,link). У нас будет перемещаться строка, а значит move. То есть в обоих тэгах нужно добавить actions="MOVE".
discriminant - значение для идентификации источника. Вы можете написать произвольное значение
8. При добавлении collectionDropTarget через Components window, вам будет предложено создать dropListener (слушатель для событий target-а), создайте его. Так же пропишите свойства actions и modelname( значение discriminant из источника)
<af:collectionDropTarget dropListener="#{viewScope.dndBean.handleMove}"
actions="MOVE" modelName="rowmove"/>
9. Завершающим этапом является написание обработки события:
public DnDAction handleMove(DropEvent dropEvent) {
//получение источника
RichTable dragComponent = (RichTable) dropEvent.getDragComponent();
//получение цели
RichTable dropComponent = (RichTable) dropEvent.getDropComponent();
Transferable t = dropEvent.getTransferable();
DataFlavor<RowKeySet> df =
DataFlavor.getDataFlavor(RowKeySet.class, "rowmove");
RowKeySet rks = t.getData(df);
Iterator iter = rks.iterator();
//получение выбранной строки в источнике
Digit dragRow = (Digit) dragComponent.getSelectedRowData();
Digit dropRow = null;
//получение выбранной строки в цели
if (iter.hasNext()) {
Integer key = (Integer)iter.next();
dropComponent.setRowKey(key);
dropRow =(Digit)dropComponent.getRowData();
if (iter.hasNext()) {
Integer key = (Integer)iter.next();
dropComponent.setRowKey(key);
dropRow =(Digit)dropComponent.getRowData();
//удаление строки из источника и добавление её в Цель
getTargetTable().add(getTargetTable().indexOf(dropRow), dragRow);
getSourceTable().remove(dragRow);
}
getTargetTable().add(getTargetTable().indexOf(dropRow), dragRow);
getSourceTable().remove(dragRow);
}
// обновление таблиц
AdfFacesContext.getCurrentInstance().addPartialTarget(dragComponent);
AdfFacesContext.getCurrentInstance().addPartialTarget(dropComponent);
AdfFacesContext.getCurrentInstance().addPartialTarget(dragComponent);
AdfFacesContext.getCurrentInstance().addPartialTarget(dropComponent);
return DnDAction.MOVE;
}
}
Готово : )
Более детально о Drag and Drop в ADF можно прочитать здесь: https://docs.oracle.com/middleware/1212/adf/ADFUI/af_dnd.htm
Комментариев нет:
Отправить комментарий