SWT可交互式Browser控件
在许多
平台中,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
来源:www.va1314.com/bc
则没有实现。
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 (Illegal AccessException e) {
} catch (InstantiationException e) {
}
if (webBrowser == null) {
dispose ();
SWT.error (SWT.ERROR_NO_HANDLES);
}
webBrowser.setBrowser (this);
webBrowser.create (parent, style);
}
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能够设置值。 view plaincopy to clipboardprint?
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
* @param id
* @param value
*/
public void setValue( String id, Object value ){
if (execute("var obj = document.getElementById('" + id + "');"
+ "if( obj != null ) obj.value='" + value + "';")) {
}
}
@Override
public void changed(StatusTextEvent event) {
setData(DATA, event.text);
}
}