2010-02-10 43 views
1

我想獲得適當的方法對天在flextable的專欄中選擇多個單元格。GWT FlexTable - 拖動選擇如何?

到目前爲止,我只設法與行之有效點擊做到這一點,但一拖選擇會好得多。我一直在閱讀文檔和搜索,但我發現的所有內容都基於不推薦使用的代碼。我使用GWT 2.0。

我知道我需要時,拖動鼠標選擇手勢發生這將運行一些事件處理程序,該處理程序需要知道小區的索引,其中,選擇起點和過程的細胞的指數,其中選擇結束。

任何意見||代碼將不勝感激。

+1

你有沒有看GWT-DND(http://code.google.com/p/gwt-dnd/)? – 2010-02-10 21:03:19

+0

是的,我也發現了gwt-dnd。我查看了演示和維基,並且他們支持所有類型的拖放操作,但不支持拖動選擇。 – Stoto 2010-02-11 11:33:20

+0

我仍在尋找解決方案。 – Stoto 2010-02-13 13:17:34

回答

1

這需要改進,但它應該給你的基本理念。首先,您需要創建一個偵聽MouseEvent的CustomTable。您可以通過擴展複合包裝一個focuspanel和flextable這樣做:

public class CustomTable extends Composite implements MouseDownHandler, MouseMoveHandler, MouseUpHandler{ 

List<CellWidget> widgets = new ArrayList<CellWidget>(); 
FlexTable table = new FlexTable(); 
FocusPanel focusPanel = new FocusPanel(); 
boolean selecting= false; 
Point selectStart,selectEnd;  

public CustomTable(){ 
    focusPanel.setWidget(table); 
    focusPanel.addMouseDownHandler(this); 
    focusPanel.addMouseMoveHandler(this); 
    focusPanel.addMouseUpHandler(this); 

    initWidget(focusPanel); 
} 

public void setWidget(int row, int column, CellWidget widget){ 
    widgets.add(widget); 
    table.setWidget(row, column, widget); 
} 

@Override 
public void onMouseUp(MouseUpEvent event) { 
    event.preventDefault(); 
    if (selecting){ 
     selecting=false; 
     DOM.releaseCapture(this.getElement()); 
     selectEnd = new Point(event.getClientX(),event.getClientY()); 

     for (CellWidget widget : widgets){ 
      if (widget.isIn(selectStart,selectEnd)) 
       widget.say();    
     } 
     selectStart = selectEnd = null;   
    }  
} 

@Override 
public void onMouseMove(MouseMoveEvent event) { 
    event.preventDefault(); 
    if (selecting){ 
     //do some fancy layout 
    }  
} 

@Override 
public void onMouseDown(MouseDownEvent event) { 
    event.preventDefault(); 
    selecting = true; 
    DOM.setCapture(this.getElement()); 
    selectStart = new Point(event.getClientX(),event.getClientY()); 
} 
} 

接下來,定義一個CellWidget基本上封裝你想添加到您的細胞是什麼。當添加到DOM,CellWidget計算,稍後存儲的位置,以確定它是否在所選擇的區域:

public class CellWidget extends Composite{ 

Widget content; 
Point topLeft,topRight,bottomLeft,bottomRight; 

public CellWidget(Widget w){ 
    this.content = w; 
    initWidget(w); 
} 

@Override 
protected void onLoad() { 
    topLeft = new Point(getAbsoluteLeft(),getAbsoluteTop()); 
    topRight = new Point(getAbsoluteLeft()+getOffsetWidth(),getAbsoluteTop()); 
    bottomLeft = new Point(getAbsoluteLeft(),getAbsoluteTop()+getOffsetHeight()); 
    bottomRight = new Point(getAbsoluteLeft()+getOffsetWidth(),getAbsoluteTop()+getOffsetHeight()); 
} 

public void say(){ 
    Window.alert(content + " is selected!"); 
} 

public boolean isIn(Point start, Point end){ 
    if (topLeft.isBetween(start, end) || topRight.isBetween(start, end) 
      || bottomLeft.isBetween(start, end) || bottomRight.isBetween(start, end)) 
     return true; 
    else 
     return false;   
} 
} 

簡單點的實現,使事情變得更加容易:

public class Point { 

int x,y; 

public Point(int x,int y){ 
    this.x=x; 
    this.y=y; 
} 
public int getX() { 
    return x; 
} 
public int getY() { 
    return y; 
} 
@Override 
public String toString() { 
    return x+","+y; 
} 
public boolean isBetween(Point p1,Point p2){ 
    if (p1.getX() < x && p2.getX() > x && p1.getY() < y && p2.getY() > y) 
     return true; 
    return false; 
} 
} 

最後,在您的入口點模塊你換東西了由:

public void onModuleLoad() { 
    RootPanel rootPanel = RootPanel.get(); 
    CustomTable table = new CustomTable(); 
    table.setWidget(0, 0, new CellWidget(new Label("hello 0,0"))); 
    table.setWidget(0, 1, new CellWidget(new Label("hello 0,1"))); 
    table.setWidget(1, 0, new CellWidget(new Label("hello 1,0"))); 
    table.setWidget(1, 1, new CellWidget(new Label("hello 1,1"))); 
    rootPanel.add(table); 
} 

我知道,實際的邏輯,以確定部件落在所選區域內是不完整的,需要進行即興但我認爲這個解決方案是足夠清晰的,給出了基本的想法。乾杯