JExplorer Programmer's Guide


Version: 1.8
Last Updated: June 12, 2007

Chapter 1. Introduction


All Java programmers who have ever developed a Web site testing tool or desktop Java application with an HTML viewer need a library that could load, display an HTML document and access its content. Of course, the implementation of such a library from scratch may take a lot of programming and testing efforts. Therefore, integrating the existing browser is a preferable way.

The JExplorer library is based on the Microsoft Internet Explorer browser and provides the base WebBrowser interface and its two implementations: the Browser component and HeadlessBrowser class. The Browser component displays HTML documents in Java Swing applications. The HeadlessBrowser class works like the Browser component, except that it doesn't have a visual presentation and can be used for automated testing.

Also, it would be useful if the library could provide access to the document object model (DOM). For example, some testing script may need to find a form in the HTML document, fill its controls with values and then submit the form to the web server. The JExplorer library provides such functionality. Besides, it can handle various browser and document events, read and write elements' attributes, execute JavaScript code, and even listen to script error events, etc. The DOM implementation in JExplorer provides access to elements inside frames.

The JExplorer distribution contains a demo application (JExplorerDemo) allowing you to browse HTML documents in tabbed mode and view the DOM model of a currently opened page. You can find the application in the samples\JExplorerDemo folder.

Each chapter below provides code samples which you can also find in the samples\Guide folder of the JExplorer distribution.

Chapter 2. JExplorer Architecture


As mentioned above, JExplorer uses Internet Explorer, i.e. JExplorer is a Java wrapper for the WebBrowser COM component and is based on the COM integration of the JNIWrapper library.

The functionality of the WebBrowser component can be divided into several parts described in the sections below.

2.1. General IWebBrowser2 Interface Functionality

JExplorer provides the WebBrowser interface that is implemented by both Browser and HeadlessBrowser classes. Using this interface, you can:

  • Load a new document into the browser.

  • Use history commands.

  • Disable error, alert, and confirmation dialogs.

2.2. Exposing DOM Model

The DOM model of Internet Explorer is exposed through the IWebBrowser2::Document property as a tree of COM objects that represent elements in the document. The WebBrowser interface from the JExplorer library has the getDocument() method that returns a Java object (a wrapper for the native document). The returned object implements the com.jniwrapper.win32.ie.dom.HTMLDocument interface. The HTMLDocument interface extends the org.w3c.dom.Document interface, so the document object contains methods for accessing the elements in a document. These methods return objects that wrap native COM objects representing elements or element collections. The element wrapper implements the com.jniwrapper.win32.ie.dom.HTMLElement interface, and the element collection wrapper implements the org.w3c.dom.NodeList interface. The HTMLElement interface extends the org.w3c.dom.Element interface, therefore element objects contain methods for accessing their child elements, too.

2.3. Listening to Events

JExplorer allows you to set up listeners for getting events related to navigation to another page, creation of a new Internet Explorer window, status bar text change, etc. You can find these listeners in the event subpackage.

JExplorer uses its own dispatch server that implements the DWebBrowserEvents2 interface and receives notifications from the WebBrowser component. This dispatch server calls appropriate methods of Java listeners and handlers. Method parameters in the listeners and handlers are of Java types: the library creates corresponding Java objects for native objects. For example, BSTR is converted to a java.lang.String object, IWebBrowser2 interface pointer to a Java object implementing the WebBrowser interface, and so on.

2.4. JavaScript Execution

To execute JavaScript code, use the executeScript() method provided by the WebBrowser interface.

2.5. Listening to and Firing Events for Specific DOM Elements

Each DOM element wrapper provided by JExplorer implements the EventTarget and HTMLElement interfaces. Therefore, you can add event listeners for a DOM element wrapper. Also, you can add event listeners using HTMLElement variables, because the HTMLElement interface extends the EventTarget interface.

Call the HTMLElement.fireEvent() method to fire events on specific DOM elements.

Chapter 3. Using Internet Explorer in a Java Application


JExplorer provides two main classes for working with Internet Explorer: the Browser class, which is a visual Swing component, and the HeadlessBrowser class, which has no visual presentation. Both classes reside in the com.jniwrapper.win32.ie package. The example below shows how to add an instance of the Browser component to JFrame:

       JFrame frame = new JFrame();
       frame.setSize(800, 600);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       Browser browser = new Browser();
       frame.getContentPane().add(browser);
       frame.setVisible(true);

       // wait until the browser is ready to work
       browser.waitReady();

The Browser.waitReady() method blocks further execution until the browser is ready to work. You should always call this method before starting to work with a Browser instance.

The Browser.navigate() method loads a specified HTML document:

       browser.navigate("http://www.teamdev.com");

The Browser.navigate() method starts document loading, but it doesn't guarantee that the document is completely loaded after the method is executed. Note that you will not find elements or get the contents for the document if it is partly loaded. Use the Browser.waitReady() method to force the calling thread to wait until the document is loaded completely:

       browser.waitReady();
       String content = browser.getContent();
       System.out.println("Document: " + content);

Again, you should call the Browser.waitReady() method after Browser.navigate() and before Browser.getContent() and Browser.getDocument() calls. Do not call the WebBrowser.waitReady() method in the Swing thread because this causes deadlock. For the same reason, do not execute time-consuming tasks in the Swing thread.

Now let's try to create a HeadlessBrowser instance:

       WebBrowser browser = new HeadlessBrowser();

The HeadlessBrowser class doesn't require any container as a parent, nor does it create visible Swing windows. The HeadlessBrowser class uses an invisible Swing window in its implementation, therefore a Swing thread runs when the program creates HeadlessBrowser instances. A Java application does not terminate when the main thread exits with the Swing thread still running. Therefore, call the System.exit(0) method to terminate the program.

The com.jniwrapper.win32.ie.WebBrowser interface provides navigate(), waitReady(), getContent() and other useful methods. Therefore, the Browser and HeadlessBrowser implementations are interchangeable.

The following code demonstrates the technique of loading an HTML document from a java.lang.String object:

       WebBrowser browser = new HeadlessBrowser();

       String content = "<html><body><h1>Simple document</h1></body></html>";

       browser.setContent(content);
       browser.waitReady();

       String content = browser.getContent();
       System.out.println("Document: " + content);

For the complete samples, please refer to the following files:

core/CreateBrowserSample.java, core/CreateHeadlessBrowserSample.java, core/SetBrowserContentSample.java

Chapter 4. Document Object Model Implementation in JExplorer


In the previous chapter, we called the browser.getContent() method and obtained a document as a String. You can also manipulate the document as a Document Object Model (DOM):

       HTMLDocument document = browser.getDocument();
       Element form = document.getElementById("mainForm");

The above code returns a com.jniwrapper.win32.ie.dom.HTMLDocument object that represents a document loaded into the browser and finds the element by ID. The found element is an org.w3c.dom.Element instance. A DOM element wrapper is an object of com.jniwrapper.win32.ie.dom.HTMLElement type, so the form object supports such functionality as clicking an element, firing an event on some element, getting an element position, size, styles and other:

       HTMLElement htmlElement = (HTMLElement) form;
    
       // call HTMLElement interface method
       Dimension elementSize = htmlElement.getSize();

Another way to find elements in the document is to search them by tag name:

       NodeList forms = document.getElementsByTagName("form");
       HTMLElement form1 = (HTMLElement) forms.item(0);

The forms object is a list of all forms in the document. The NodeList.item() method returns one element from this list. Another useful method of the NodeList interface is getLength() that returns the number of elements in the list.

Apart from finding elements by ID or tag name, you can get the children or parent of the element. The org.w3c.dom.Node interface provides the getChildNodes() and getParentNode() methods for these tasks. The org.w3c.dom.Document and org.w3c.dom.Element interfaces extend the Node interface.

And finally, the org.w3c.dom.Element interface contains the getElementsByTagName() method, enabling you to search for an element inside another element. For example, you can search input elements in the form:

       NodeList inputs = mainForm.getElementsByTagName("input");

If you need more information about DOM, please refer to W3C Document Object Model.

For the complete samples, please refer to the following files:

dom/DomNavigationSample.java, dom/SubmitFormSample.java

Chapter 5. DOM Element Attributes


Element attributes can be used to fill the form controls on the HTML page with values, get the link text or retrieve the type of an input element. The Element.getAttribute() method returns an attribute value. The following code finds the "Groups" link on a Google page and gets the link text:

       WebBrowser browser = new HeadlessBrowser(); 

       browser.navigate("http://www.google.com");
       browser.waitReady(); 

       Element groupsLink = (Element) browser.getDocument().getElementsByTagName("a").item(1);
       String linkText = groupsLink.getAttribute("innerHTML");

Use the type attribute of the input element to determine its type:

       browser.navigate("http://www.google.com");
       browser.waitReady(); 

       Element input = (Element) browser.getDocument().getElementsByTagName("input").item(0);
       String inputType = input.getAttribute("type");

The Element.setAttribute() method sets the element's attribute value. The following sample fills the input field on the Google page:

       browser.navigate("http://www.google.com");
       browser.waitReady();

       Element textInput = getTextInput(browser.getDocument());
       textInput.setAttribute("value", "JExplorer");

Use the value attribute to fill the text and password fields, text areas and select controls with values as demonstrated in the sample above. Use the checked attribute to work with check boxes and radio button controls:

       // select a checkbox
       checkbox.setAttribute("checked", "true");

       // select a radio button
       radio1.setAttribute("checked", "true");

Note that setting a value in the file chooser control through the value attribute does not work because of the security restrictions of the WebBrowser COM component.

You can find additional information about DHTML attributes in HTML and DHTML Reference on MSDN.

For the complete samples, please refer to the following files:

dom/NavigateLinkSample.java, dom/SubmitFormSample.java, dom/FormValuesSample.java

Chapter 6. DOM Element Styles


Each DOM element has style properties (or styles) responsible for its visual presentation in an HTML page. Each style determines a certain aspect of visual presentation. For example, the border style contains information about the border type, its thickness, and color.

JExplorer provides methods for managing styles in the HTMLElement interface. The sample below finds the font element in the document and changes its background color:

       browser.navigate("http://www.google.com ");
       browser.waitReady(); 

       HTMLElement font = getFontElement(browser.getDocument()); 

       font.setStyle("background", "green");

The HTMLElement.getStyle() method returns the element's style value. Also, the HTMLElement interface contains helper methods to customize the background and border colors. This sample illustrates how to set the border color for the element:

       input.setBorder(Color.RED);

You can find additional information about styles in HTML and DHTML Reference on MSDN.

For the complete sample, please refer to the following file:

dom/StyleSample.java

Chapter 7. Navigating to URL and Submitting a Form


JExplorer provides the ability to click a link or button in the form. Use the HTMLElement.click() method to emulate the user click action on an element. The sample below shows how to click a link on the HTML page:

       browser.navigate("http://www.google.com");
       browser.waitReady(); 

       HTMLElement groupsLink = (HTMLElement) browser.getDocument().getElementsByTagName("a").item(1); 

       groupsLink.click();

The HTMLElement.click() method used on the form's submit button sends the form data to the server. The following sample runs Google search:

       browser.navigate("http://www.google.com");
       browser.waitReady(); 

       Element textInput = getTextInput(browser.getDocument());
       textInput.setAttribute("value", "JExplorer"); 

       HTMLElement button = getSearchButton(browser.getDocument());
       button.click();

For the complete samples, please refer to the following files:

dom/NavigateLinkSample.java, dom/SubmitFormSample.java, dom/FormValuesSample.java

Chapter 8. Forms API


Working with the form controls is not an easy task because each control requires its own methods for setting and getting its values. Forms API simplifies the task of setting and getting the form control values. You can find an appropriate element through the DOM API and cast its instance to one of the interfaces described below. These interfaces provide methods to work with the form control values.

The controls are divided into three groups:

  • Controls that implement the TextControl interface.

    The value of this control is a java.lang.String object. The text area, password and text fields belong to text controls:

       TextControl text = (TextControl) document.getElementById("loginId");
       text.setValue("John");

    If you need to enter several lines into the text area control, use "\r\n" strings as line separators:

       area.setValue("1st line" + "\r\n" + "2nd line");
  • Controls that implement the CheckControl interface.

    The value of this control is boolean. The checkbox and radio button belong to check controls:

       CheckControl checkbox = (CheckControl) document.getElementById("isorderId");
       checkbox.setValue(true);
  • The SelectElement interface represents a select HTML control. This element contains options that are represented by OptionElement instances:

       SelectElement select = (SelectElement) document.getElementById("stateId");
       List options = select.getOptions();
       OptionElement option1 = (OptionElement) options.get(1);
       option1.select();

You can find the form in the HTML document and cast its instance to the HTMLForm type. The HTMLForm interface provides methods for getting:

  • Form's elements

  • Form's action attribute

  • Form's method attribute to send the form data to the server.

For the complete sample, please refer to the following file:

dom/FormValuesSample.java

Chapter 9. Working with Frames


Elements in the frames are not accessible from the HTML document directly. Therefore, first you should find the frame containing the element and then find the element in the frame:

    Document doc = browser.getDocument();
        
    // find a frame
    NodeList frames = doc.getElementsByTagName("frame");
    Element frame = (Element) frames.item(0);
    
    // find an element in the frame
    Element login = frame.getElementsById("login");

The DOM wrapper of a frame element implements the WebBrowser interface. Thus, the frame provides all browser functionality like navigation, getting content, and other operations:

    WebBrowser frameBrowser = (WebBrowser) frame;
    String content = frameBrowser.getContent();

For the complete sample, please refer to the following file:

dom/FrameAccessSample.java

Chapter 10. Working with Pop-ups


Sometimes you need to click a button that opens a pop-up window, fill a form in that pop-up window, submit the form and then continue working with the document that opened the pop-up window. JExplorer allows you to wait for a pop-up window to be loaded and get a reference to it:

    // Start tracking creation of a child window
    browser.trackChildren();

    HTMLElement element = (HTMLElement) browser.getDocument().getElementById("theLink");
    
    // click the link that opens a pop-up window
    element.click();

    // get a reference to the pop-up window
    WebBrowser child = browser.waitChildCreation();
    child.waitReady();

    String childTitle = child.getDocument().getTitle();

For the complete sample, please refer to the following file:

core/ChildBrowserSample.java

Chapter 11. Working with Events from DOM Elements


Each DOM element wrapper in JExplorer's Document Object Model implements the org.w3c.dom.events. EventTarget interface. Therefore, you can add a listener to an element:

   HTMLElement link = (HTMLElement) links.item(i);
    
   EventListener listener = new EventListener() {
      public void handleEvent(Event evt)
      {
            Element target = (Element) event.getTarget();
            System.out.println("Event from " + target.getTagName());
      }
   };
   link.addEventListener("onclick", listener, false);

The event listener implements the org.w3c.dom.events.EventListener interface with one method that is called when a specified event is fired. The Event object passed to the method contains information about the event type, source of the event, coordinates of the mouse pointer for the mouse event, and pressed keys.

The sample below adds a listener for the onchange event from the select element:

      private void setupChangeListener(final Element select)
        {
            EventTarget eventTarget = (EventTarget) select;
    
            eventTarget.addEventListener("onchange", new EventListener()
            {
                public void handleEvent(Event evt)
                {
                    Element target = (Element) evt.getTarget();
    
                    // Gets current value of select target
                    String value = target.getAttribute("value");
                }
            }, false);
        }

The event handler gets the current value of the select element and prints it. The org.w3c.dom.Element does not extend the org.w3c.dom.events.EventTarget interface, so you need to cast the select element to the EventTarget type.

JExplorer provides the HTMLElement.fireEvent() method that fires a specified event on a selected DOM element, like shown below:

      div.fireEvent("onclick");

For the complete samples, please refer to the following files:

dom/event/ClickListenerSample.java, dom/event/SelectElementSample.java, dom/event/FireEventSample.java

Chapter 12. Working with Browser Events


Internet Explorer sends notifications about its various events related to navigation, document load completion, document title or status bar text change, etc.

NavigationEventListener, StatusEventListener, NewWindowEventHandler, NewWindowEventListener, and WebBrowserEventsHandler provide methods that are called when the browser events occur. You can find these interfaces and their basic implementations in the com.jniwrapper.win32.ie.event package.

The following sample demonstrates how to add a document completed event listener to the browser:

   browser.addNavigationListener(new NavigationEventAdapter() {
         public void documentCompleted(WebBrowser webBrowser, String url)
         {
               System.out.println("Document completed: " + url);
         }
   });

NavigationEventListener handles navigation-related events, such as the start and completion of navigation and its progress. The documentCompleted() method is called when the document is completely loaded to the browser.

StatusEventListener handles browser state change events such as changes of the document title, status text, navigation button state, etc.

The NavigationEventAdapter class implements the NavigationEventListener interface and contains only methods with empty bodies. You can extend the adapter class instead of implementing a listener. This way is convenient when you create a listener that handles only one event.

Instances of the Browser and HeadlessBrowser classes can have several listeners. However, each instance of WebBrowser cannot have more than one event handler, because the handler methods return values that affect the browser's behavior. For example, you can cancel navigation by a link.

The code below shows how to add a handler for a navigation event:

   browser.setEventHandler(new DefaultWebBrowserEventsHandler() { 
         public boolean beforeNavigate(
             WebBrowser webBrowser, 
             String url, 
             String targetFrameName, 
             String postData, 
             String headers)
         {
             System.out.println("url = " + url);
             System.out.println("postData = " + postData);
             System.out.println("headers = " + headers); 
             
             // proceed
             return false;
         }
   });

The beforeNavigate event is fired when some link is clicked or a form is submitted. If the handler's method returns true, navigation is cancelled. Otherwise, navigation or the form submission is performed. The DefaultWebBrowserEventsHandler class is the basic implementation of WebBrowserEventsHandler that enables navigation by links, navigation to error pages, etc.

NewWindowEventHandler contains the newWindow() method that you can use to create a tabbed browser. Please see JExplorerDemo for more details.

Using JExplorer, a Java application can listen to JavaScript errors that may occur in a document. Use ScriptErrorListener with the errorOccured() method for this purpose. This method is called on JavaScript error in the browser document. The code below demonstrates how to assign a script error listener for the current document:

   browser.setScriptErrorListener(new ScriptErrorListener() {
      public void errorOccured(ScriptErrorEvent event)
      {
            int errorCode = event.getErrorCode();
            String url = event.getUrl();
            String message = event.getMessage(); 

            System.out.println("errorCode = " + errorCode);
            System.out.println("url = " + url);
            System.out.println("message = " + message);
      }
   });

Any script error produces a dialog that blocks the execution of the calling thread until the dialog is closed. This is inconvenient for code that uses the HeadlessBrowser class. The code below demonstrates how to disable the error, alert, and confirmation dialogs:

      WebBrowser browser = new HeadlessBrowser();
      browser.setSilent(true);

Note that the WebBrowser.setSilent() call sets up its own DialogEventHandler. Therefore, if a dialog event handler is already set up, it will be removed.

For the complete samples, please refer to the following files:

core/event/NavigationListenerSample.java, core/event/ErrorLoggingSample.java, core/DisableDialogsSample.java

Chapter 13. Working with Document Cookies


HTMLDocument provides methods for working with document cookies. The HTMLDocument.getCookies() method returns java.util.Set of com.jniwrapper.win32.ie.dom.Cookie objects that contain the name, value, domain of a cookie, and other information:

   Set cookies = browser.getDocument().getCookies();
   if (cookies.size() > 0)
   {
      Cookie cookie = (Cookie)cookies.iterator().next();
   }

If you need to set a cookie, follow these steps:

  1. Create a Cookie object.

  2. Assign its value and other needed parameters.

  3. Add the Cookie object to an empty set.

  4. Pass this set to the HTMLDocument.setCookies() method.

The cookie will be modified after the user navigates to a different page or sends the form data to the server.

For the complete sample, please refer to the following file:

core/CookieSample.java

Chapter 14. Executing Document Operations (Save, Print)


The IWebBrowser2.execWB() native interface call allows you to execute such commands as invoking Save, Print, and Print Preview dialogs. JExplorer has the WebBrowser.execute(BrowserCommand command) method that provides the same functionality. You create a BrowserCommand instance and pass it to the WebBrowser.execute() method:

   browser.execute(new SaveAsCommand());

The com.jniwrapper.win32.ie.command package contains classes for working with browser commands.

For the complete samples, please refer to the following files:

command/PrintSample.java, command/SaveDialogSample.java

Chapter 15. Setting Custom Context Menu


The Browser component allows you to display a custom Java pop-up menu instead of the default one displayed by Internet Explorer. Because the contents of the menu depends on what element of a page is under the mouse pointer, the menu is dynamically constructed by the application.

To customize the browser context menu, you need to:

  1. Configure Swing to use heavyweight pop-up menus.

  2. Implement the ContextMenuProvider interface.

  3. Assign the context menu provider to the browser.

Below is given a detailed description of these steps.

15.1. Configuring Swing to Use Heavyweight Pop-up Menus

Since the browser is a native window inserted into Swing UI, pop-up menus will not be displayed over the browser component unless the menus are made heavyweight, as the code line below shows:

   JPopupMenu.setDefaultLightWeightPopupEnabled(false);

15.2. Implementing Context Menu Provider

The purpose of the context menu provider is to supply the browser control with an instance of JPopupMenu that provides actions for the DOM element clicked in the browser. The ContextMenuProvider interface defines a single getPopupMenu() method that accepts the org.w3c.dom.Element instance.

The following code demonstrates a simple provider that changes a menu item text if the context menu is invoked for a link element:

   ContextMenuProvider contextMenuProvider = new ContextMenuProvider() {
      public JPopupMenu getPopupMenu(Element contextElement)
      {
         final boolean isLink = "A".equals(contextElement.getTagName());
         String openItemText = isLink ? "Open in New Tab" : "New Tab";
 
         _openItem.setText(openItemText);
 
         return _contextMenu;
      }
   };

Note that the Browser component invokes the menu provider's method each time before displaying the context menu. It is necessary that the implementation does not contain time-consuming operations to ensure that the menu is displayed promptly at the user's request.

15.3. Assigning Context Menu Provider

To assign the context menu provider that was created at the previous step, the setContextMenuProvider() method of the Browser component should be called:

   browser.setContextMenuProvider(contextMenuProvider);

15.4. Getting Context Element in Action Code

To get an element the context name was called for, use the getContextElement() method of the browser component:

   Element contextElement = browser.getContextElement();

15.5. Disabling Context Menu

To disable the context menu, you need to implement ContextMenuProvider that returns null in the getPopupMenu() method and assign the provider to the browser.

For the complete samples, please refer to the following files:

contextmenu/ContextMenuSample.java, contextmenu/DisableContextMenuSample.java, contextmenu/ContextMenuActionSample.java

Chapter 16. Working with Native Peers and Avoiding Thread Issues


A Web browser control is a thread unsafe component, therefore you should call its methods from one thread, i.e. from the thread that created this component (its OLE message loop). Our API calls (WebBrowser interface, DOM wrappers and other) invoke native methods from this thread, so you don't need to invoke these methods from the OLE message loop. The direct use of native peers' methods should be performed in the OLE message loop. You should consider this when working with native peer objects (interface method calls and interface querying) like shown in the code sample below:

   IWebBrowser2 peer = (IWebBrowser2)getBrowser().getBrowserPeer();
   IDispatch dispatch = peer.getDocument();
   IHTMLDocument2 doc2 = new IHTMLDocument2Impl(peer.getDocument());
   String title = doc2.getTitle().getValue();

The native peer functionality is available in the JExplorer Professional version only. You can find a Java wrapper for the IWebBrowser2 COM interface and other COM interfaces in the mshtml.jar library in the JExplorer Professional distribution.

If you need to work with a native object, do it in the browser OLE message loop:

   getBrowser().getOleMessageLoop().doInvokeLater(new Runnable() {
        public void run()
        {
            IWebBrowser2 peer = (IWebBrowser2)getBrowser().getBrowserPeer();
            IDispatch dispatch = peer.getDocument();
            IHTMLDocument2 doc2 = new IHTMLDocument2Impl(peer.getDocument());
            String title = doc2.getTitle().getValue();
        }
    });

The OleMessageLoop class provides two methods for executing methods in this thread: doInvokeLater() and doInvokeAndWait(). The difference between these methods is that the former returns immediately, and the latter blocks further execution while the task defined by Runnable method parameter is being executed. Use doInvokeLater() in a Swing thread for time-consuming tasks to prevent this thread from blocking.

The HTMLElement interface provides the getElementPeer() method that returns IHTMLElement instance (a Java wrapper for COM inteface). Therefore, you can call COM interface methods of an element to work with functionality that JExplorer does not provide:

   WebBrowser browser = new HeadlessBrowser();

        browser.setContent("<html><body><div width='400' height='300'>div text</div></body>");
        browser.waitReady();

        HTMLElement element = (HTMLElement) browser.getDocument().getElementsByTagName("div").item(0);
        final IHTMLElement peer = (IHTMLElement) element.getElementPeer();

        browser.getOleMessageLoop().doInvokeAndWait(new Runnable()
        {
            public void run()
            {
                BStr outerHTML = peer.getOuterHTML();
                System.out.println("outerHTML = " + outerHTML);
            }
        });

Chapter 17. Support


If you have any problems or questions regarding JExplorer, please e-mail us at:

jexplorer-support@teamdev.com

17.1. JExplorer Forum

If you want to discuss topics related to JExplorer, please visit a specialized forum on the TeamDev integrated customer support and troubleshooting center at:

http://support.teamdev.com/category.jspa?categoryID=11

17.2. Reporting Problems

If you find any bugs in JExplorer, please submit the issue to us using a special report form on the TeamDev integrated customer support and troubleshooting center at:

http://support.teamdev.com/

The form will help you provide all necessary information.

17.3. Troubleshooting

To find a solution to your problem, please visit the Troubleshooting page on our site at:

http://www.teamdev.com/explorer/tshoot.jsf

This page is regularly updated using information from support requests.

If you don't find a solution, please e-mail us at jexplorer-support@teamdev.com or report the problem as described in the previous section.

Chapter 18. Where to Get a New Version


To get the latest version of JExplorer, please visit:

http://www.teamdev.com/jexplorer/downloads.jsf

Copyright © 2002-2007 TeamDev Ltd.