SWT可交互式Browser控件

来源:互联网 发布:网络安全设备有哪些 编辑:程序博客网 时间:2024/05/19 13:08
在许多平台中,Browser控件皆被作为一个必需的控件给出,并提供了DOM接口,用于访问Browser的内容,相对来说SWT中的Browser控件就比较薄弱,没有提供DOM的可控制接口,那么,如何和控件所加载的页面进行交互呢?比如需要在集成web应用的环境中实现模拟登陆、自动填表等功能。

SWT中对Browser有不同的实现,目前实现的有IE和Mozilla。在Browser的构造函数中根据不同的平台和不同的style设置类决定使用哪个类的实现。

org.eclipse.swt.browser.Mozillaorg.eclipse.swt.browser.IE是已经实现的,而其他的org.eclipse.swt.browser.Safariorg.eclipse.swt.browser.Voyager

则没有实现。

[java] view plaincopy
  1. public Browser (Composite parent, int style) {  
  2.   
  3.     super (checkParent (parent), checkStyle (style));  
  4.   
  5.     String platform = SWT.getPlatform ();  
  6.   
  7.     Display display = parent.getDisplay ();  
  8.   
  9.     if ("gtk".equals (platform)) display.setData (NO_INPUT_METHOD, null); //$NON-NLS-1$  
  10.   
  11.     String className = null;  
  12.   
  13.     if ((style & SWT.MOZILLA) != 0) {  
  14.   
  15.         className = "org.eclipse.swt.browser.Mozilla"//$NON-NLS-1$  
  16.   
  17.     } else {  
  18.   
  19.         if ("win32".equals (platform) || "wpf".equals (platform)) { //$NON-NLS-1$ $NON-NLS-2$  
  20.   
  21.             className = "org.eclipse.swt.browser.IE"//$NON-NLS-1$  
  22.   
  23.         } else if ("motif".equals (platform)) { //$NON-NLS-1$  
  24.   
  25.             className = "org.eclipse.swt.browser.Mozilla"//$NON-NLS-1$  
  26.   
  27.         } else if ("gtk".equals (platform)) { //$NON-NLS-1$  
  28.   
  29.             className = "org.eclipse.swt.browser.Mozilla"//$NON-NLS-1$  
  30.   
  31.         } else if ("carbon".equals (platform)) { //$NON-NLS-1$  
  32.   
  33.             className = "org.eclipse.swt.browser.Safari"//$NON-NLS-1$  
  34.   
  35.         } else if ("photon".equals (platform)) { //$NON-NLS-1$  
  36.   
  37.             className = "org.eclipse.swt.browser.Voyager"//$NON-NLS-1$  
  38.   
  39.         } else {  
  40.   
  41.             dispose ();  
  42.   
  43.             SWT.error (SWT.ERROR_NO_HANDLES);  
  44.   
  45.         }  
  46.   
  47.     }  
  48.   
  49.   
  50.   
  51.     try {  
  52.   
  53.         Class clazz = Class.forName (className);  
  54.   
  55.         webBrowser = (WebBrowser)clazz.newInstance ();  
  56.   
  57.     } catch (ClassNotFoundException e) {  
  58.   
  59.     } catch (IllegalAccessException e) {  
  60.   
  61.     } catch (InstantiationException e) {  
  62.   
  63.     }  
  64.   
  65.     if (webBrowser == null) {  
  66.   
  67.         dispose ();  
  68.   
  69.         SWT.error (SWT.ERROR_NO_HANDLES);  
  70.   
  71.     }  
  72.   
  73.   
  74.   
  75.     webBrowser.setBrowser (this);  
  76.   
  77.     webBrowser.create (parent, style);  
  78.   
  79. }  

其中对IE的实现主要是采用调用IE的Activex控件,直接加载IE,对Mozilla由于代码过多,本人没有具体研究,其本身开源,有兴趣可以参看。

那么回归主题,如何实现与Browser控件的交互呢? 其实仔细看Browser控件的API,可以发现一个execute()方法,这个方法适用于在web文档加载完毕时可以运行javascript code的。这样的话,交互就变得简单了,因为javascript是提供dom的支持的,既然可以调用javascript,那么就可以调用web页面中的每个节点了。控制的问题解决了,可是另外的问题来了。如何从javascript的code里边返回数据呢?比如我需要将一个<input type=text id=textid />的值返回到java code中。其实采用的方法是很投机的,因为execute()方法返回的结果是true or false,那么对它做文章是没有用的,我们看其他的api,可以发现:addStatusTextListener()方法。 这个方法可以监听web页面对于statusbar文本改变的值,并反映在java code里面,那么我们只要通过javascript把返回的值写到window.status,那么就可以在javacode里取到了。 具体代码请参考下面,对于Browser的继承重写,通过getValue可以取得指定id的html 控件的值,通过setValue可以设置值。
[java] view plaincopy
  1. import org.eclipse.swt.browser.Browser;  
  2.   
  3. import org.eclipse.swt.browser.StatusTextEvent;  
  4.   
  5. import org.eclipse.swt.browser.StatusTextListener;  
  6.   
  7. import org.eclipse.swt.widgets.Composite;  
  8.   
  9.   
  10.   
  11. public class CoolBrowser extends Browser implements StatusTextListener {  
  12.   
  13.   
  14.   
  15.     private final String DATA = "Browser_Data";  
  16.   
  17.   
  18.   
  19.     public CoolBrowser(Composite parent, int style) {  
  20.   
  21.         super(parent, style);  
  22.   
  23.         addStatusTextListener(this);  
  24.   
  25.     }  
  26.   
  27.   
  28.   
  29.     @Override  
  30.   
  31.     protected void checkSubclass() {  
  32.   
  33.     }  
  34.   
  35.   
  36.   
  37.     /** 
  38.  
  39.      * Get the value of one input control in the web 
  40.  
  41.      * @param id 
  42.  
  43.      * @return 
  44.  
  45.      */  
  46.   
  47.     public String getValue(String id) {  
  48.   
  49.         if (execute("var obj = document.getElementById('" + id + "');"  
  50.   
  51.                 + "if( obj != null ) window.status=obj.value;")) {  
  52.   
  53.             return (String) getData(DATA);  
  54.   
  55.         }  
  56.   
  57.         return null;  
  58.   
  59.     }  
  60.   
  61.       
  62.   
  63.     /** 
  64.  
  65.      * Set the value of the input control 
  66.  
  67.      * @param id 
  68.  
  69.      * @param value 
  70.  
  71.      */  
  72.   
  73.     public void setValue( String id, Object value ){  
  74.   
  75.         if (execute("var obj = document.getElementById('" + id + "');"  
  76.   
  77.                 + "if( obj != null ) obj.value='" + value + "';")) {  
  78.   
  79.         }  
  80.   
  81.     }  
  82.   
  83.   
  84.   
  85.     @Override  
  86.   
  87.     public void changed(StatusTextEvent event) {  
  88.   
  89.         setData(DATA, event.text);  
  90.   
  91.     }  
  92.   
  93.   
  94.   

0 0