代码之家  ›  专栏  ›  技术社区  ›  Stoto

GWT FlexTable-如何拖动选择?

gwt
  •  1
  • Stoto  · 技术社区  · 16 年前

    到目前为止,我只设法做到这一点,点击工作得很好,但拖动选择会更好。我一直在阅读文档和搜索,但我找到的所有东西都是基于不推荐的代码。我使用gwt2.0。

    我知道我需要一些事件处理程序,它会在鼠标拖动选择动作发生时运行,并且该处理程序需要知道单元格的索引,其中选择从哪里开始,当然还有单元格的索引,其中选择从哪里结束。

    任何建议| |代码将不胜感激。

    1 回复  |  直到 16 年前
        1
  •  1
  •   pistolPanties    14 年前

    这需要改进,但它应该给你的基本想法。首先,您需要创建一个监听MouseEvents的CustomTable。您可以通过扩展composite来包装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,以确定其在选定区域中的位置:

    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);
    }
    

    我知道确定小部件是否在所选区域内的实际逻辑是不完整的,需要改进,但是我认为这个解决方案足够清晰,可以给出基本的想法。干杯

    推荐文章