如何在DataGrid中为单元格创建拖放功能

6
我正在尝试为单元格小部件添加拖放功能。更具体地说,我想拖放ClickableTextCell,但是它们没有特定的方法,甚至没有addDomHandler,因此我不能只创建像.addDomHandler(new DragStartHandler() { ... }这样的东西。
有人可以提供如何使用纯GWT进行单元格拖放的帮助吗?
1个回答

1

我不知道如何在GWT中实现DnD,但我知道如何实现CnC(Clic 'n Clic),这可能会对您有所帮助。 DnD很酷,有趣且美观,但我认为有时它们并不是非常方便。例如,如果您有一个需要滚动的大屏幕,并且想要从顶部拖放项目到底部,那么必须按住鼠标并不是很方便...但这只是个人感觉...

无论如何,我建议您使用ListDataProvider和简单事件一起移动您的项目:第一次单击选择源项目,第二次单击选择目标。一旦确定了源和目标,就可以移动项目。

这对我很有效...如果您添加一些样式来突出显示源和目标,它会非常好看。

例如:

这是主类:

        import java.util.ArrayList;

        import com.google.gwt.event.dom.client.ClickEvent;
        import com.google.gwt.event.dom.client.ClickHandler;
        import com.google.gwt.user.cellview.client.CellList;
        import com.google.gwt.user.client.ui.DialogBox;
        import com.google.gwt.user.client.ui.FlowPanel;
        import com.google.gwt.user.client.ui.FocusPanel;
        import com.google.gwt.user.client.ui.Grid;
        import com.google.gwt.user.client.ui.Label;
        import com.google.gwt.view.client.ListDataProvider;
        import com.google.gwt.view.client.SelectionChangeEvent;
        import com.google.gwt.view.client.SingleSelectionModel;

        public class Clic_Clic {

          private static final Integer LEFT = 0;

          private static final Integer CENTER = 1;

          private static final Integer RIGHT = 2;

          private ClicClicSelectionModel<Item> selectionModel = new ClicClicSelectionModel<Item>();

          ListDataProvider<Item> leftLDP = new ListDataProvider<Item>();

          ListDataProvider<Item> centerLDP = new ListDataProvider<Item>();

          ListDataProvider<Item> rightLDP = new ListDataProvider<Item>();

          FocusPanel left = new FocusPanel(), center = new FocusPanel(), right = new FocusPanel();

          Item selected = null;

          public Clic_Clic() {

            // --- Builds the GUI
            DialogBox clic_clic = buildGUI();
            clic_clic.center();
            clic_clic.show();

            // --- Initializes data
            configureSelectionManagement();
            initCellLists();
            configureAddAndRemove();

            // --- Fills the left LDP
            leftLDP.getList().add(new Item("Fraternité", LEFT));
            leftLDP.refresh();

            // --- Fills the center LDP
            centerLDP.getList().add(new Item("Egalité", LEFT));
            centerLDP.refresh();

            // --- Fills the right LDP
            rightLDP.getList().add(new Item("Liberté", RIGHT));
            rightLDP.refresh();
          }

          private DialogBox buildGUI() {
            DialogBox db = new DialogBox();
            db.setText("A simple example for Clic 'n Clic");
            db.setSize("300px", "200px");
            db.setGlassEnabled(true);
            db.setModal(true);

            FlowPanel fp = buildContent();
            db.add(fp);

            return db;
          }

          private FlowPanel buildContent() {

            Grid g = new Grid(1, 3);
            g.setSize("300px", "200px");

            g.setWidget(0, 0, left);
            left.setSize("100px", "100px");
            left.getElement().getStyle().setBackgroundColor("blue");

            g.setWidget(0, 1, center);
            center.setSize("100px", "100px");

            g.setWidget(0, 2, right);
            right.setSize("100px", "100px");
            right.getElement().getStyle().setBackgroundColor("red");

            FlowPanel fp = new FlowPanel();
            fp.setSize("300px", "200px");
            fp.add(new Label("Do you know the correct order ?"));
            fp.add(g);

            return fp;
          }

          private void initCellLists() {
            // --- Associates the left panel with the leftLDP ListDataProvider
            CellList<Item> cellListLeft = new CellList<Item>(new MyCell());
            cellListLeft.setSelectionModel(selectionModel);
            left.add(cellListLeft);
            leftLDP = new ListDataProvider<Item>(new ArrayList<Item>());
            leftLDP.addDataDisplay(cellListLeft);

            // --- Associates the center panel with the centerLDP ListDataProvider
            CellList<Item> cellListCenter = new CellList<Item>(new MyCell());
            cellListCenter.setSelectionModel(selectionModel);
            center.add(cellListCenter);
            centerLDP = new ListDataProvider<Item>(new ArrayList<Item>());
            centerLDP.addDataDisplay(cellListCenter);

            // --- Associates the right panel with the rightLDP ListDataProvider
            CellList<Item> cellListRight = new CellList<Item>(new MyCell());
            cellListRight.setSelectionModel(selectionModel);
            right.add(cellListRight);
            rightLDP = new ListDataProvider<Item>(new ArrayList<Item>());
            rightLDP.addDataDisplay(cellListRight);
          }

          private void configureAddAndRemove() {
            // --- If the user clic on the left
            left.addClickHandler(new ClickHandler() {

              @Override
              public void onClick(ClickEvent event) {
                if (selected != null) {
                  // --- If the selected item comes from the right
                  if (selected.getContainerIndex() == RIGHT) {
                    rightLDP.getList().remove(selected);
                    rightLDP.refresh();

                    selected.setContainerIndex(LEFT);
                    leftLDP.getList().add(selected);
                    leftLDP.refresh();

                    selected = null;
                  }
                  // --- If the selected item comes from the center
                  if (selected.getContainerIndex() == CENTER) {
                    centerLDP.getList().remove(selected);
                    centerLDP.refresh();

                    selected.setContainerIndex(LEFT);
                    leftLDP.getList().add(selected);
                    leftLDP.refresh();

                    selected = null;
                  }
                }
              }
            });
            // --- If the user clic on the center
            center.addClickHandler(new ClickHandler() {

              @Override
              public void onClick(ClickEvent event) {
                if (selected != null) {
                  // --- If the selected item comes from the right
                  if (selected.getContainerIndex() == RIGHT) {
                    rightLDP.getList().remove(selected);
                    rightLDP.refresh();

                    selected.setContainerIndex(CENTER);
                    centerLDP.getList().add(selected);
                    centerLDP.refresh();

                    selected = null;
                  }
                  // --- If the selected item comes from the left
                  if (selected.getContainerIndex() == LEFT) {
                    leftLDP.getList().remove(selected);
                    leftLDP.refresh();

                    selected.setContainerIndex(CENTER);
                    centerLDP.getList().add(selected);
                    centerLDP.refresh();

                    selected = null;
                  }
                }
              }
            });
            // --- If the user clic on the right
            right.addClickHandler(new ClickHandler() {

              @Override
              public void onClick(ClickEvent event) {
                // --- If the selected item comes from the left
                if (selected.getContainerIndex() == LEFT) {
                  leftLDP.getList().remove(selected);
                  leftLDP.refresh();

                  selected.setContainerIndex(RIGHT);
                  rightLDP.getList().add(selected);
                  rightLDP.refresh();

                  selected = null;
                }
                // --- If the selected item comes from the center
                if (selected.getContainerIndex() == CENTER) {
                  centerLDP.getList().remove(selected);
                  centerLDP.refresh();

                  selected.setContainerIndex(RIGHT);
                  rightLDP.getList().add(selected);
                  rightLDP.refresh();

                  selected = null;
                }
              }
            });
          }

          @SuppressWarnings("hiding")
          class ClicClicSelectionModel<Item> extends SingleSelectionModel<Item> {

            @Override
            public void setSelected(Item object, boolean selected) {
              if (getSelectedObject() != null && getSelectedObject().equals(object)) {
                super.setSelected(object, !selected);
              } else {
                super.setSelected(object, selected);
              }
            };
          }

          private void configureSelectionManagement() {
            selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {

              @Override
              public void onSelectionChange(SelectionChangeEvent event) {
                Item selected = selectionModel.getSelectedObject();
                updateSelected(selected);
              }

            });

          }

          private void updateSelected(Item item) {
            // --- If no item has been selected, update the selected item
            if (selected == null) {
              selected = item;
            }
          }

        }

你还需要这个:

        public class Item {

          private String label;

          private Integer containerIndex;

          public Item(String l, Integer id) {
            this.label = l;
            this.containerIndex = id;
          }

          public String getLabel() {
            return label;
          }

          public void setLabel(String label) {
            this.label = label;
          }

          public Integer getContainerIndex() {
            return containerIndex;
          }

          public void setContainerIndex(Integer containerIndex) {
            this.containerIndex = containerIndex;
          }

        }

最后,还有这个:
        import com.google.gwt.cell.client.AbstractCell;
        import com.google.gwt.safehtml.shared.SafeHtml;
        import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
        import com.google.gwt.safehtml.shared.SafeHtmlUtils;

        public class MyCell extends AbstractCell<Item> {

          @Override
          public void render(com.google.gwt.cell.client.Cell.Context context, Item value, SafeHtmlBuilder sb) {
            if (value != null) {
              // --- If the value comes from the user, we escape it to avoid XSS
              // attacks.
              SafeHtml safeValue = SafeHtmlUtils.fromString(value.getLabel());
              sb.append(safeValue);
            }

          }

        }

给你。

下次我会尝试做一个有趣的例子 :)

希望能帮到你。


你能分享一下你实现CnC的代码吗? - Display name
我会尝试在这个周末做一些简单的事情。 - tlapeg07
我也对这个感兴趣,但可能对我没有太大帮助,因为在这种情况下,DnD被用作复制机制,并且简单的点击会打开该项的编辑对话框。 - user1879896

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接