<!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:95634971; mso-list-type:hybrid; mso-list-template-ids:973640628 -1954540214 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l0:level1 {mso-level-start-at:0; mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:24.0pt; mso-level-number-position:left; margin-left:24.0pt; text-indent:-18.0pt; font-family:Wingdings; mso-fareast-font-family:宋体; mso-bidi-font-family:宋体;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
在许多平台中,Browser 控件皆被作为一个必需的控件给出,并提供了DOM 接口,用于访问Browser 的内容,相对来说SWT 中的Browser 控 件就比较薄弱,没有提供DOM 的可控制接口,那么,如何和控件所加载的页面进行交互呢?比如需要在集成web 应用的环境中实现模拟登陆、自动填表等功能。
SWT 中对Browser 有不同的实现,目前实现的有IE 和Mozilla 。在Browser 的构造函数中根据不同的平台和不同的style 设置类决定使用哪个类的实现。
org.eclipse.swt.browser.Mozilla
org.eclipse.swt.browser.IE 是已经实现的,而其他的 org.eclipse.swt.browser.Safari
org.eclipse.swt.browser.Voyager
则没有实现。
public Browser (Composite parent, int style)
{
super (checkParent (parent), checkStyle (style));
String platform = SWT.getPlatform ();
Display display = parent.getDisplay ();
if ("gtk".equals (platform))
display.setData (NO_INPUT_METHOD, null); //$NON-NLS-1$
String className = null;
if ((style & SWT.MOZILLA) != 0)
{
className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$ }
else
{ if ("win32".equals (platform) || "wpf".equals (platform)) { //$NON-NLS-1$ $NON-NLS-2$
className = "org.eclipse.swt.browser.IE"; //$NON-NLS-1$
}
else if ("motif".equals (platform))
{ //$NON-NLS-1$
className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$
}
else if ("gtk".equals (platform))
{
//$NON-NLS-1$
className = "org.eclipse.swt.browser.Mozilla"; //$NON-NLS-1$
}
else if ("carbon".equals (platform))
{ //$NON-NLS-1$
className = "org.eclipse.swt.browser.Safari"; //$NON-NLS-1$
}
else if ("photon".equals (platform))
{ //$NON-NLS-1$
className = "org.eclipse.swt.browser.Voyager"; //$NON-NLS-1$
}
else
{
dispose ();
SWT.error (SWT.ERROR_NO_HANDLES);
}
}
try
{
Class clazz = Class.forName (className);
webBrowser = (WebBrowser)clazz.newInstance ();
}
catch (ClassNotFoundException e) { }
catch (IllegalAccessException e) { }
catch (InstantiationException e) { }
if (webBrowser == null)
{
dispose ();
SWT.error (SWT.ERROR_NO_HANDLES);
}
webBrowser.setBrowser (this);
webBrowser.create (parent, style); }
其中对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 可以设置值。
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.StatusTextEvent;
import org.eclipse.swt.browser.StatusTextListener;
import org.eclipse.swt.widgets.Composite;
public class CoolBrowser extends Browser implements StatusTextListener {
private final String DATA = "Browser_Data";
public CoolBrowser(Composite parent, int style)
{
super(parent, style);
addStatusTextListener(this);
}
@Override protected void checkSubclass()
{ }
/** * Get the value of one input control in the web
@param id * @return */
public String getValue(String id)
{
if (execute("var obj = document.getElementById('" + id + "');" + "if( obj != null ) window.status=obj.value;"))
{ return (String) getData(DATA); }
return null; }
/** * Set the value of the input control
l @param id * @param value */
l public void setValue( String id, Object value )
l { if (execute("var obj = document.getElementById('" + id + "');" + "if( obj != null ) obj.value='" + value + "';")) { } }
l
@Override public void changed(StatusTextEvent event) { setData(DATA, event.text); } }