peacess

统计

留言簿(9)

积分与排名

阅读排行榜

评论排行榜

gwt项目开发的经验集----会一直增加

    

      正在做一个gwt项目的开发,我会把在项目开发中遇到的问题以及解决方法记录下来(有很多是同事,也整理放在其中了),以供同道中人参考,少走不该走的路,也希望与同仁交流。

      gwt的1.4发布了,好久没有更新我的文章了,现在又准备开始更新。源代码(总):http://www.blogjava.net/Files/peacess/freelinz-gwt-experience.rar

    mail:peacess@163.com
    qq:64407724
目录:
13,用gwt在web中实现上下文菜单(右键菜单、弹出菜单) 2007年8月3日

12,gwt中使用float样式实现 完成 2007年7月28日
11,文件下载(download,通过表单方式
完成 2007年8月6日

10,阻止事件传到父对象 2007年7月31日
9,文件上传客户端(upload隐藏表单) 2007年7月29日
8,不换行:表格字符、多种widget的组合 计划中
7,css的(边框)margin、border、padding、width、height与dom对象的属clientWidth、offsetWidth、offsetHeight等的关系及gwt的获取与设置>  完成 2007年5月9日
6,学习资源              完成 2006年12月21日
5,给gwt的ui组件增加事件 完成 2006年12月17日
4,按钮的鼠标进出样式    完成 2006年12月14日
3,元素宽度计算          完成
2,对话框居中            完成
1,关闭页面              完成
。。。。。。。。
13,用gwt在web中实现上下文菜单(右键菜单、弹出菜单)
/**
 * gwt的上下文菜单(右键菜单、弹出菜单)实现 在web应该程序中,有一个默认上下文菜单,
 * 在实现时,一定要把它禁用。 有两种实现方式实现上下文菜单,一种是用gwt的事件机制,一种是利用jsni实现
 * gwt实现 优点:基于gwt,那么不同浏览器的兼容性就不用考虑
 *      缺点:要把原widget放入一个div中,可能会产想不到的问题
 * jsni实现 优点:对原有widget不产生多内容,直接
 *      缺点:要考虑不同浏览的兼容性
 */

/**
 * 用gwt方式实现上下文菜单
 * 
@author wylpeace
 *
 
*/

class ContextMenuGwt extends Composite
{
    
private SimplePanel panel;

    
private MenuBar menuBar;

    
private ContextMenuGwt(Widget w,MenuBar menuBar)
    
{
        
super();
        panel 
= new SimplePanel();
        panel.setWidget(w);
        initWidget(panel);
        
this.menuBar = menuBar;
        DomEx.disableContextMenu(panel.getElement());
        unsinkEvents(
-1);
        sinkEvents(Event.ONMOUSEDOWN);
    }

    
protected void onAttach()
    
{
        
super.onAttach();

        DOM.setEventListener(getElement(), 
this);
    }

    
public static Widget addContextMenu(Widget w,MenuBar menuBarIn)
    
{
        ContextMenuGwt c 
= new ContextMenuGwt(w,menuBarIn);
        
return c;
    }

    
private void popupMenu(Event event, MenuBar menuBarIn)
    
{
        
// 可以加上弹出菜单的理想位置,这里取最简单的
        final int x = DOM.eventGetClientX(event);
        
final int y = DOM.eventGetClientY(event);
        PopupPanel p 
= new PopupPanel(true);
        p.setWidget(menuBarIn);
        p.setPopupPosition(x, y);
        DomEx.disableContextMenu(p.getElement());
//防止弹出浏览的上下文菜单
        p.show();
    }


    
public void onBrowserEvent(Event event)
    
{
        
if(DOM.eventGetType(event) == Event.ONMOUSEDOWN)
        
{
            
if(DOM.eventGetButton(event) == Event.BUTTON_RIGHT)
            
{
                popupMenu(event, 
this.menuBar);
                
return;
            }

        }

        
super.onBrowserEvent(event);
    }

}

 

/**
 * 用jsni方式实现上下文菜单
 * 这里的实现也可以放到一个函数中,不一定是一个类
 * 
@author wylpeace
 *
 
*/

public class ContextMenuJsni
{
    
public static Widget addContextMenu(Widget w,MenuBar menuBar)
    
{
        oncontextmenu(w.getElement(), menuBar);
        
return w;
    }

    
private static native void oncontextmenu(Element e, MenuBar menuBarIn)
    
/*-{
        e.oncontextmenu = function(evt)
        {
            var event = (evt?evt:$wnd.event); //在ie中evt的参数为空,它的当前事件在window.event中
            @freelinz.experience13.client.ContextMenuJsni::popupMenu(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/ui/MenuBar;)(event,menuBarIn);
            return false;
        };
    }-
*/
;

    
private static void popupMenu(Event event, MenuBar menuBarIn)
    
{
        
// 可以加上弹出菜单的理想位置,这里取最简单的
        final int x = DOM.eventGetClientX(event);
        
final int y = DOM.eventGetClientY(event);

        PopupPanel p 
= new PopupPanel(true);
        p.setWidget(menuBarIn);
        p.setPopupPosition(x, y);
        DomEx.disableContextMenu(p.getElement());
//防止弹出浏览的上下文菜单
        p.show();
    }

}


12,gwt中使用float样式实现
      css的float样式在ie与firefox中对应的dom属性名不同,所以不能直接用如下的语句
               DOM.setStyleAttribute(elem,"float", "left");
      可以这样使用(在ie与firefox都可以)

public static native void setStyleAttributeEx(Element elem, String jsStyle, String value)
    
/*-{
         if(jsStyle=="float" || jsStyle == "styleFloat" || jsStyle =="cssFloat")
         {
         jsStyle = (elem.style.styleFloat || elem.style.styleFloat=="")  ? "styleFloat":"cssFloat";
         }
         elem.style[jsStyle]=value;
     }-
*/
;


>11,文件下载(download,通过表单方式)

    /**
     * 创建下载的form,通过form带参数进行下载,
     * 而不用直接把下载文件的地址写在代码里
     * 
@return form
     
*/

    
public FormPanel createDown()
    
{
        FormPanel formPanel 
= new FormPanel();
        FlowPanel flowPanel 
= new FlowPanel();

        formPanel.setWidget(flowPanel);
        formPanel.setAction(GWT.getModuleBaseURL() 
+ "filedownload");//设置action
        formPanel.setEncoding(FormPanel.ENCODING_URLENCODED);
        formPanel.setMethod(FormPanel.METHOD_POST);
        DOM.setStyleAttribute(formPanel.getElement(), 
"margin""0px");//使大小为零

        Hidden hidden 
= new Hidden("name","value");//可以增加多个,下载时带的参数
        flowPanel.add(hidden);

        
return formPanel;
    }


>10,阻止事件传到父对象

/**
 * 阻止事件传到父对象中
 * 事件比如单击事件,当一个Element收到后,进行处理。
 * 如果不作处理,这个单击事件还会被传到父element。
 *  这里一个实例使用的例子。 在表格中放一按钮,当单击按钮时,
 *  表格的单击事件不被触发
 
*/

public class Experience10 implements EntryPoint
{
    RootPanel rootPanel;

    
public void onModuleLoad()
    
{
        rootPanel 
= RootPanel.get();

        Grid table 
= new Grid();
        table.resize(
21);
        table.addTableListener(
new TableListener()
        
{
            
public void onCellClicked(SourcesTableEvents arg0, int arg1, int arg2)
            
{
                Window.alert(
"表格被单击");
            }


        }
);

        
// 一般按钮
        Button normal = new Button("一般按钮");
        normal.addClickListener(
new ClickListener()
        
{
            
public void onClick(Widget arg0)
            
{
                Window.alert(
"一般按钮 ---- 按钮被单击");
            }


        }
);
        table.setWidget(
00, normal);

        
// 阻止事件传到父对象
        Button cancelBubble = new Button("阻止事件传到父对象")
        
{
            
public void onBrowserEvent(Event event)
            
{
                
if(DOM.eventGetType(event) == Event.ONCLICK)
                
{
                    DOM.eventCancelBubble(event, 
true);// 阻止事件传到父对象
                }

                
super.onBrowserEvent(event);
            }

        }
;
        cancelBubble.addClickListener(
new ClickListener()
        
{
            
public void onClick(Widget arg0)
            
{
                Window.alert(
"阻止事件传到父对象 ---- 按钮被单击");
            }


        }
);
        table.setWidget(
10, cancelBubble);

        rootPanel.add(table);

    }

}



>9,文件上传客户端(隐藏表单,有一个简单的服务端,见源代码) 2007年7月29日

package freelinz.experience9.client;

import com.google.gwt.core.client.GWT;

/**
 * 文件上传,gwt client端
 *
 
*/

public class FileUploadDlg extends DialogBox implements ClickListener
{
    
/**
     * 操作提示
     
*/

    
private Label note;

    FileUpload fileUpload;

    FormPanel formPanel;

    
private Button confirm;

    
private Button close;

    
public FileUploadDlg()
    
{
        setText(
"文件上传");

        fileUpload 
= new FileUpload();
        fileUpload.setName(
"fileww");// 这个名字可以任意给,但一定要记着给
        note = new Label("");
        formPanel 
= new FormPanel();
        FlowPanel dlgPanel 
= new FlowPanel();

        FlowPanel formWidget 
= new FlowPanel();
        formPanel.setWidget(formWidget);
        Hidden[] ws 
= new Hidden[2];// 用于向服务端传送信息
        ws[0= new Hidden("userwe""test");
        ws[
1= new Hidden("idwe""12312");

        
for(int i = 0, num = ws.length; i < num; i++)
            formWidget.add(ws[i]);
        formWidget.add(fileUpload);

        dlgPanel.add(formWidget);
        dlgPanel.add(note);
        
// 设置表单默认属性
        formPanel.setMethod(FormPanel.METHOD_POST);// 提交方式"post
        formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);// "encoding"为"multipart/form-data
        formPanel.setAction(GWT.getModuleBaseURL() + "fileupload");// servlet的url
        formPanel.addFormHandler(new FormHandler()
        
{
            
public void onSubmitComplete(FormSubmitCompleteEvent event)
            
{
                
// String temp = event.getResults();// 服务端的返回值
                note.setText("上传完成");
            }


            
public void onSubmit(FormSubmitEvent event)
            
{
            }

        }
);

        confirm 
= new Button("上传"this);
        
// 关闭按钮
        close = new Button("取消"this);

        dlgPanel.add(formPanel);
        dlgPanel.add(confirm);
        dlgPanel.add(close);
        setWidget(dlgPanel);
    }


    
public void onClick(Widget sender)
    
{
        
// 确定,提交表单
        if(sender == confirm)
        
{
            String temp 
= fileUpload.getFilename();
            
// 未选择文件
            if(temp == null || temp.length() < 1)
                
return;
            formPanel.submit();
            note.setText(
"文件上传中");
        }

        
// 取消,关闭对话框
        if(sender == close)
            
this.hide();
    }

}


8,不换行:表格字符、多种widget的组合

//div中的文本不换行
        Label label = new Label("div中的文本不换行");
        
//css       white-space: nowrap;
        
//gwt实现:
        DOM.setStyleAttribute(label.getElement(), "white-space""nowrap");

        
//table中的文本不换行
        
//先把文件放入一个div中,再放到表格中,或者设置table的td的css样式

        
//不同类型的widget在div中不换行