我正在尝试使用本机GWT拖动事件进行简单的拖放FlexTable,以允许用户移动行。
//This works fine
galleryList.getElement().setDraggable(Element.DRAGGABLE_TRUE);
galleryList.addDragStartHandler(new DragStartHandler() {
@Override
public void onDragStart(DragStartEvent event) {
event.setData("text", "Hello World");
groupList.getElement().getStyle().setBackgroundColor("#aff");
}
});
但是,我想: 1.给出物品掉落的可视指示器。 2.当drop事件触发时,找出我应该放弃行的位置。
galleryList.addDragOverHandler(new DragOverHandler() {
@Override
public void onDragOver(DragOverEvent event) {
//TODO: How do i get the current location one would drop an item into a flextable here
}
});
galleryList.addDragEndHandler(new DragEndHandler() {
@Override
public void onDragEnd(DragEndEvent event) {
//TODO: How do i know where i am in the flextable
}
});
我看到这些FlexTable方法在获取单元格/行时非常有用:
public Cell getCellForEvent(ClickEvent event)
protected Element getEventTargetCell(Event event)
但问题是Drag事件没有继承Event
提前致谢
答案 0 :(得分:1)
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;
public class DragFlexTable extends FlexTable implements DraggableWidget {
public String dragStyle = "drag-table-row";
public String dragReplaceStyle;
protected DragVerticalHandler dragFlexTableHandler;
private int currentRow;
private int[] yLocations;
private int rowBeingDragged;
DragFlexTable() {
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
getElement().setDraggable(Element.DRAGGABLE_TRUE);
final DragUtil dragUtil = new DragUtil();
addDragStartHandler(new DragStartHandler() {
@Override
public void onDragStart(DragStartEvent event) {
dragUtil.startVerticalDrag(event, DragFlexTable.this);
}
});
addDragEndHandler(new DragEndHandler() {
@Override
public void onDragEnd(DragEndEvent event) {
dragUtil.endVerticalDrag(event, DragFlexTable.this);
}
});
addDragOverHandler(new DragOverHandler() {
@Override
public void onDragOver(DragOverEvent event) {
dragUtil.handleVerticalDragOver(event, DragFlexTable.this, 3);
}
});
}
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
Element td = getEventTargetCell(event);
if (td == null) return;
Element tr = DOM.getParent(td);
currentRow = TableRowElement.as(td.getParentElement()).getSectionRowIndex();
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEOVER: {
//tr.addClassName(ROW_STYLE_NAME + "-mouseover");
tr.addClassName(dragStyle);
break;
}
case Event.ONMOUSEOUT: {
tr.removeClassName(dragStyle);
break;
}
}
}
public void setDragStyle(String dragStyle) {
this.dragStyle = dragStyle;
}
@Override
public void resetDragState() {
yLocations = null;
}
@Override
public void setRowBeingDragged(int currentRow) {
this.rowBeingDragged = currentRow;
}
@Override
public int getDragRow(DragDropEventBase event) {
if (yLocations == null) {
yLocations = new int[getRowCount()];
for (int i = 0; i < getRowCount(); i++) {
Widget widget = getWidget(i, 0);
if (widget.isVisible()) {
com.google.gwt.dom.client.Element imgTd = widget.getElement().getParentElement();
int absoluteBottom = imgTd.getAbsoluteBottom();
yLocations[i] = absoluteBottom;
} else {
yLocations[i] = -1;
}
}
}
int lastY = 0;
for (int i = 0; i < yLocations.length; i++) {
int absoluteBottom = yLocations[i];
//invisible
if (absoluteBottom != -1) {
int absoluteTop = lastY;
int clientY = event.getNativeEvent().getClientY();
if (absoluteBottom > clientY && absoluteTop < clientY) {
//com.google.gwt.dom.client.Element tr = imgTd.getParentElement();
return i;
}
lastY = absoluteBottom;
}
}
return currentRow;
}
@Override
public com.google.gwt.dom.client.Element getTrElement(int row) {
return getWidget(row, 0).getElement().getParentElement().getParentElement();
}
@Override
public DragVerticalHandler getDragFlexTableHandler() {
return dragFlexTableHandler;
}
public void setDragReplaceStyle(String dragReplaceStyle) {
this.dragReplaceStyle = dragReplaceStyle;
}
@Override
public int getRowBeingDragged() {
return rowBeingDragged;
}
@Override
public String getDragReplaceStyle() {
return dragReplaceStyle;
}
public void setDragFlexTableHandler(DragVerticalHandler dragFlexTableHandler) {
this.dragFlexTableHandler = dragFlexTableHandler;
}
}
这是它使用的util类
import com.google.gwt.event.dom.client.DragEndEvent;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragStartEvent;
import com.google.gwt.user.client.ui.Image;
public class DragUtil {
private int alternateIgnoreEvent = 0;
private int lastDragRow = -1;
public void startVerticalDrag(DragStartEvent event, DraggableWidget widget) {
widget.resetDragState();
//Required
event.setData("text", "dragging");
int currentRow = widget.getDragRow(event);
widget.setRowBeingDragged(currentRow);
if (widget.getDragFlexTableHandler()!=null) {
Image thumbnailImg = widget.getDragFlexTableHandler().getImage(currentRow);
if (thumbnailImg!=null) {
event.getDataTransfer().setDragImage(thumbnailImg.getElement(), -10, -10);
}
}
}
public void handleVerticalDragOver(DragOverEvent event, DraggableWidget widgets, int sensitivity) {
if (alternateIgnoreEvent++ % sensitivity != 0) {
//many events fire, for every pixel move, which slow the browser, so ill ignore some
return;
}
int dragRow = widgets.getDragRow(event);
if (dragRow != lastDragRow) {
com.google.gwt.dom.client.Element dragOverTr = widgets.getTrElement(dragRow);
if (lastDragRow != -1) {
com.google.gwt.dom.client.Element lastTr = widgets.getTrElement(lastDragRow);
lastTr.removeClassName(widgets.getDragReplaceStyle());
}
lastDragRow = dragRow;
dragOverTr.addClassName(widgets.getDragReplaceStyle());
}
}
public void endVerticalDrag(DragEndEvent event, DraggableWidget widgets) {
int newRowPosition = widgets.getDragRow(event);
//cleanup last position
if (newRowPosition != lastDragRow) {
com.google.gwt.dom.client.Element lastTr = widgets.getTrElement(lastDragRow);
lastTr.removeClassName(widgets.getDragReplaceStyle());
}
if (newRowPosition != widgets.getRowBeingDragged()) {
com.google.gwt.dom.client.Element dragOverTr = widgets.getTrElement(newRowPosition);
dragOverTr.removeClassName(widgets.getDragReplaceStyle());
widgets.getDragFlexTableHandler().moveRow(widgets.getRowBeingDragged(), newRowPosition);
}
}
}
在uibinder中我然后使用它:
<adminDnd:DragFlexTable ui:field='itemFlexTable' styleName='{style.table}' cellSpacing='0'
cellPadding='0'
dragStyle='{style.drag-table-row-mouseover}'
dragReplaceStyle='{style.drag-replace-table-row}'
/>
答案 1 :(得分:1)
即使我遇到了这个问题,经过一些原型设计,这也是我最终的结果 。我创建了一个扩展flex表的类。这是代码
public class DragFlexTable extends FlexTable implements
MouseDownHandler,MouseUpHandler,MouseMoveHandler,
MouseOutHandler
{
private int row,column,draggedrow,draggedcolumn;
private Element td;
private Widget w;
private boolean emptycellclicked;
DragFlexTable()
{
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEDOWN | Event.ONMOUSEMOVE);
this.addMouseDownHandler(this);
this.addMouseMoveHandler(this);
this.addMouseUpHandler(this);
this.addMouseOutHandler(this);
}
@Override
public void onBrowserEvent(Event event)
{
super.onBrowserEvent(event);
td = getEventTargetCell(event);
if (td == null)
{
return;
}
Element tr = DOM.getParent((com.google.gwt.user.client.Element) td);
Element body = DOM.getParent((com.google.gwt.user.client.Element) tr);
row = DOM.getChildIndex((com.google.gwt.user.client.Element) body, (com.google.gwt.user.client.Element) tr);//(body, tr);
column = DOM.getChildIndex((com.google.gwt.user.client.Element) tr, (com.google.gwt.user.client.Element) td);
}
boolean mousedown;
@Override
public void onMouseDown(MouseDownEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
//to ensure empty cell is not clciked
if (!td.hasChildNodes())
{
emptycellclicked = true;
}
event.preventDefault();
start(event);
mousedown = true;
}
}
@Override
public void onMouseMove(MouseMoveEvent event)
{
if (mousedown)
{
drag(event);
}
}
@Override
public void onMouseUp(MouseUpEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
if (!emptycellclicked)
{
end(event);
}
emptycellclicked = false;
mousedown = false;
}
}
@Override
public void onMouseOut(MouseOutEvent event)
{
this.getCellFormatter().getElement(row, column).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderColor();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
mousedown = false;
}
private void start(MouseDownEvent event)
{
w = this.getWidget(row, column);
w.getElement().getStyle().setOpacity(0.5);
}
private void drag(MouseMoveEvent event)
{
if (draggedrow != row || draggedcolumn != column)
{
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderColor();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderWidth();
this.draggedrow = row;
this.draggedcolumn = column;
this.getCellFormatter().getElement(row, column).getStyle().setBorderStyle(BorderStyle.DASHED);
this.getCellFormatter().getElement(row, column).getStyle().setBorderColor("black");
this.getCellFormatter().getElement(row, column).getStyle().setBorderWidth(2, Unit.PX);
}
}
private void end(MouseUpEvent event)
{
insertDraggedWidget(row, column);
}
private void insertDraggedWidget(int r,int c)
{
this.getCellFormatter().getElement(r, c).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderColor();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
if (this.getWidget(r, c) != null)
{
//pushing down the widgets already in the column
// int widgetheight = (this.getWidget(r, c).getOffsetHeight() / 2) + this.getWidget(r, c).getAbsoluteTop();
// int rw;
//placing the widget above the dropped widget
for (int i = this.getRowCount() - 1; i >= r; i--)
{
if (this.isCellPresent(i, c))
{
this.setWidget(i + 1, c, this.getWidget(i, c));
}
}
}
this.setWidget(r, c, w);
//removes unneccesary blank rows
cleanupRows();
//pushing up the column in the stack
// for (int i = oldrow;i<this.getRowCount()-1 ;i++)
// {
//
// this.setWidget(i ,oldcolumn, this.getWidget(i+1, oldcolumn));
//
// }
}
private void cleanupRows()
{
ArrayList<Integer> rowsfilled = new ArrayList<Integer>();
for (int i = 0; i <= this.getRowCount() - 1; i++)
{
for (int j = 0; j <= this.getCellCount(i) - 1; j++)
{
if (this.getWidget(i, j) != null)
{
rowsfilled.add(i);
break;
}
}
}
//replace the empty rows
for (int i = 0; i < rowsfilled.size(); i++)
{
int currentFilledRow = rowsfilled.get(i);
if (i != currentFilledRow)
{
for (int j = 0; j < this.getCellCount(currentFilledRow); j++)
{
this.setWidget(i, j, this.getWidget(currentFilledRow, j));
}
}
}
for (int i = rowsfilled.size(); i < this.getRowCount(); i++)
{
this.removeRow(i);
}
}
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler)
{
return addDomHandler(handler, MouseUpEvent.getType());
}
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler)
{
return addDomHandler(handler, MouseDownEvent.getType());
}
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler)
{
return addDomHandler(handler, MouseMoveEvent.getType());
}
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler)
{
return addDomHandler(handler, MouseOutEvent.getType());
}
}
以上自定义窗口小部件的on模块加载
public void onModuleLoad()
{
Label a = new Label("asad");
Label b = new Label("ad");
Label c = new Label("qwad");
Label w = new Label("zxd");
a.setPixelSize(200, 200);
a.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
a.getElement().getStyle().setBorderWidth(1, Unit.PX);
b.setPixelSize(200, 200);
c.setPixelSize(200, 200);
w.setPixelSize(200, 200);
a.getElement().getStyle().setBackgroundColor("red");
b.getElement().getStyle().setBackgroundColor("yellowgreen");
c.getElement().getStyle().setBackgroundColor("lightblue");
w.getElement().getStyle().setBackgroundColor("grey");
DragFlexTable d = new DragFlexTable();
d.setWidget(0, 0, a);
d.setWidget(0, 1, b);
d.setWidget(1, 0, c);
d.setWidget(1, 1, w);
d.setCellPadding(20);
RootPanel.get().add(d);
}