如何挂钩内部Eclipse浏览器?

时间:2012-04-30 21:53:27

标签: java eclipse eclipse-plugin

对于我的eclipse插件,我想跟踪用内部(如果可能还有外部)Eclipse浏览器打开的每个URL。

到目前为止,我使用

org.eclipse.swt.browser.Browser;

addLocationListener(...)

但我更喜欢它也适用于内部Eclipse浏览器。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

Eclipse内部浏览器的一个可能的解决方案是创建一个注册IStartup扩展的eclipse插件。在earlyStartup()方法中,您将在workbenchPage上注册一个IPartListener。然后,当创建内部浏览器部件时,您将收到一个带有对WebBrowserEditor(或WebBrowserView)的引用的回调。由于没有直接的API,您将不得不破解并使用反射来获取内部SWT浏览器实例。完成后,您可以添加位置监听器。

有时在早期启动时,没有活动的Workbench窗口,因此您必须遍历所有现有的工作台窗口(通常只有一个)和每个工作台页面以添加部件监听器。

以下是earlyStartup()例程的代码片段。请注意,在处理windows / pages期间,我已经省略了对侦听器的任何清理,因此仍然需要完成。

//Add this code to an IStartup.earlyStartup() method
final IPartListener partListener = new IPartListener() {
    @Override
    public void partOpened(IWorkbenchPart part) {
        if (part instanceof WebBrowserEditor)
        {
            WebBrowserEditor editor = (WebBrowserEditor) part;

            try {
                Field webBrowser = editor.getClass().getDeclaredField("webBrowser");
                webBrowser.setAccessible(true);
                BrowserViewer viewer = (BrowserViewer)webBrowser.get(editor);

                Field browser = viewer.getClass().getDeclaredField("browser");
                browser.setAccessible(true);
                Browser swtBrowser = (Browser) browser.get(viewer);

                swtBrowser.addLocationListener(new LocationListener() {
                    @Override
                    public void changed(LocationEvent event) {
                        System.out.println(event.location);
                    }
                });
            } catch (Exception e) {
            }
        }
        else if (part instanceof WebBrowserView)
        {
            WebBrowserView view = (WebBrowserView) part;

            try {
                Field webBrowser = editor.getClass().getDeclaredField("viewer");
                webBrowser.setAccessible(true);
                BrowserViewer viewer = (BrowserViewer)webBrowser.get(view);

                Field browser = viewer.getClass().getDeclaredField("browser");
                browser.setAccessible(true);
                Browser swtBrowser = (Browser) browser.get(viewer);

                swtBrowser.addLocationListener(new LocationListener() {
                    @Override
                    public void changed(LocationEvent event) {
                        System.out.println(event.location);
                    }
                });
            } catch (Exception e) {
            }
        }
    }
    ...
};

final IPageListener pageListener = new IPageListener() {
    @Override
    public void pageOpened(IWorkbenchPage page) {
        page.addPartListener(partListener);
    }
    ...
};

final IWindowListener windowListener = new IWindowListener() {
    @Override
    public void windowOpened(IWorkbenchWindow window) {
        window.addPageListener(pageListener);
    }
    ...
};


IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();

if (activeWindow != null)
{
    IWorkbenchPage activePage = activeWindow.getActivePage();

    if (activePage != null)
    {
        activePage.addPartListener(partListener);
    }
    else
    {
        activeWindow.addPageListener(pageListener);
    }
}
else
{
    for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows())
    {
        for (IWorkbenchPage page : window.getPages()) {
            page.addPartListener(partListener);
        }
        window.addPageListener(pageListener);
    }

    PlatformUI.getWorkbench().addWindowListener(windowListener);
}       

关于此代码段的最后一个细节是,它需要依赖org.eclipse.ui.browser插件才能访问WebBrowserEditor类。