【问题标题】:how to get drag/drop event on listitem of listbox in zk framework如何在zk框架中的列表框列表项上获取拖放事件
【发布时间】:2012-11-29 10:39:42
【问题描述】:

我正在使用两个使用 java 类的 listBox 编写拖放功能。我已经实现了两个场景。

  1. 列表项 A 添加到列表项 B 的底部
  2. 如果我已经在 B 中选择了一个列表项,当我将项目放入 列表,它被添加到那个位置

我的要求更接近2。即我不必预先选择项目列表,并且应该将A中的项目列表移动到鼠标指向的索引处(如鼠标悬停效果)。我无法在ListboxListitem 中找到任何可以给我那个位置的方法。

以下是在 2 的情况下工作的代码。

droppedListbox.insertBefore(draggedListitem, droppedListbox.getSelectedItem());

在上面的代码中,第二个参数应该是鼠标突出显示的Listitem,因为它发生在使用 zul 文件的演示应用程序中。

正如我之前提到的,我想将项目移动到Listitem B 中的选定位置。为此,我必须在我的 zul 文件中进行这些更改。

<listbox id="adminListbox" droppable="true" draggable="true" model="${win$composer.systemAdminListModel}" width="330px" height="100%" oddRowSclass="non-odd">
.
.
.
<template name="model">
<listitem draggable="true" droppable="true">
<listcell label="${each.id}" ></listcell>
<listcell label="${each.name}" ></listcell>
<listcell label="${each.role}" ></listcell>
</listitem>
</template> [added dropable to listitem]

现在我的java代码如下在Listitem B上放置项目时没有被激活:

@Listen("onDrop = #userListbox")
public void onDragDropUserListitem(){
}

如果我从 listitem 中删除 droppable,那么它就会被调用。但是要将列表项移动到该位置,我必须在此处添加 droppable true。我还要提到 listitem 是动态的,所以我不能给它一个 id 来附加 @wire 并获取它的事件。

我想知道如何在 java 中获取 listitem 上的事件,以便我可以对其执行任何操作。在当前的情况下,我的事件“onDrop”没有被调用。

这里是事件方法

@Listen("onDrop = #userListbox")
public void onDragDropUserListitem(DropEvent dropEvent){

    userListbox.addEventListener("onDrop", new EventListener<Event>() {
        @Override
        public void onEvent(Event event) throws Exception {

            Listbox droppedListbox = (Listbox)(((DropEvent)event).getTarget());
            Listitem draggedListitem = (Listitem)((DropEvent)event).getDragged();

            if (draggedListitem instanceof Listitem) {    
                droppedListbox.insertBefore(draggedListitem, droppedListbox.getNextSibling());
            } else {
                droppedListbox.appendChild(draggedListitem);
            }
        }
    });
}

这里是zul完整组件

<listbox id="userListbox"  droppable="true" model="${win$composer.systemUserListModel}"  width="330px" height="100%" oddRowSclass="non-odd">
    <listhead>
        <listheader label="User ID" align="center" />
        <listheader label="User Name" align="center" />
        <listheader label="User Role" align="center" />
    </listhead>
    <template name="model">
        <listitem draggable="true" droppable="true" >
            <listcell label="${each.id}" />
            <listcell label="${each.name}" />
            <listcell label="${each.role}" />
        </listitem>
    </template>
</listbox>

我希望它就是你所需要的,如果你从 listitem 中删除、droppable,它可以正常工作,但不是我的要求。

【问题讨论】:

  • 请查看预览并更好地格式化您的 anwsers。
  • 我认为第一个问题是,您不了解 droppable/dragable 的工作原理。如果你在项目A中写dragable="test",在项目B中写droppable="test",那么你可以将A拖到B上。真的意味着没有限制。这里的项目是指 .zul 文件中的每个组件。最好写 public void onDragDropUserListitem(DropEvent event)。
  • 谢谢你,nabil,我知道你刚才所说的,我可以使用 java 进行拖放,它在底部添加了项目列表。如果您在 zk 演示中看到拖放示例,我只想使用 java 来添加它。问题是,无法在上述场景中获取事件来操作 itemlist。你对我的要求有什么解决方案吗???
  • 请提供更多代码。我需要查看更多的 Composer,它在哪里被应用,并且 Composer 应用到的组件的开始和 colseing xml 标记之间的完整代码将是完美的。
  • 好吧,如果可以的话,我可以这样做,这一行给了我列表框:Listbox droppedListbox = (Listbox)(((DropEvent)event).getTarget());,所以我必须这样做方式,我无法达到列表项级别

标签: java zk


【解决方案1】:

好的,第一个问题是

@Listen("onDrop = #userListbox")
public void onDragDropUserListitem(DropEvent dropEvent){

    userListbox.addEventListener("onDrop", new EventListener<Event>() {

        @Override
        public void onEvent(Event event) throws Exception {

在这段代码中,每次你添加一个 EventListener,因为你在 EventListener 中添加了一个 EventListener。

@Listen("onDrop = #userListbox")
public void onDragDropUserListitem(DropEvent dropEvent){
      Listbox droppedListbox = (Listbox)dropEvent.getTarget());
      Listitem draggedListitem = (Listitem)dropEvent.getDragged();

            if (draggedListitem instanceof Listitem) {

                droppedListbox.insertBefore(draggedListitem, droppedListbox.getNextSibling());

            }else{
                droppedListbox.appendChild(draggedListitem);
            }

}

这应该会更好。

接下来是,我没有看到像 apply="ComposerName" 这样的东西,我希望这样做。
如果您在更高级别的组件中这样做,最好在您的@Listen("onDrop = #userListbox") 中的= 之后添加组件的完整路径

Klick here 了解如何操作。
但是现在,这段代码有问题

Listbox droppedListbox = (Listbox)dropEvent.getTarget();
Listitem draggedListitem = (Listitem)dropEvent.getDragged();

因为 traget 可以是 ListboxListitem,你应该处理这个。

在此步骤中,您也可以为您的预期订单添加代码。
只需将draggedListitem 添加到userListbox 之前或之后droppedListitem
或者如果getTarget()Listbox,则在列表末尾,通过调用userListbox的插入方法。

编辑

但是@Listen("onDrop = #userListbox") 只听Listbox,但我们也想听Listitems。

您的最终代码可能如下所示

@Listen("onDrop = #userListbox")
public void onDragDropUserListbox(DropEvent dropEvent) {
    userListbox.appendChild(dropEvent.getTarget());
}

@Listen("onDrop = listitem")
public void onDragDropUserListitem(DropEvent dropEvent) {
    Listitem droppedListitem = (Listitem) dropEvent.getTarget();
    Listitem draggedListitem = (Listitem) dropEvent.getDragged();

    userListbox.insertBefore(draggedListitem, droppedListitem);
}

我已经对此进行了测试,它会在拖放到的元素之前添加拖动的元素。

【讨论】:

  • 谢谢,但这不是我想要的(我已经检查过了),我的旧代码也可以拖放到列表框的底部,我想将它添加到列表中的某个位置我使用 java 代码删除它。
  • 天哪!当然,我如此专注于方法,以至于我没有看到 Listener 是错误的。我会编辑它。
  • 最终代码,第一种方法,不起作用,它给出了语法错误,你可以从解决方案中删除它,第二个选项使用2种方法,从A到B的下降是在指定位置完成的.现在还有另一个问题,当我像在演示示例中那样放置相同的对象以对列表框中的列表项进行随机播放时,我得到“无法添加具有相同父项的组件:”,请您查看也请?
  • 您好 Nabil,您的解决方案有效,我只需要删除并删除项目列表中的 shuffle 组件,它现在工作正常。非常感谢您的大力帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2013-03-10
  • 2016-11-03
  • 2012-07-27
  • 2013-05-14
  • 1970-01-01
相关资源
最近更新 更多