I'm using JavaXPCOM to embed Mozilla-based browser into my Java app. As
I know it is a straightforward wrapper for C++ classes and functions:
all the XPCOM C++ interfaces (abstract classes) are turned into Java
interfaces, and calls to all the Java methods are automatically
converted via JNI into C++ methods and vice versa.
After my previous letter I tried almost the same way as you suggested,
but... For unknown reasons all I wrote failed. First I tried to register
a listener on browser's content DOM window:
nsIDOMWindow dw = browser.getContentDOMWindow();
nsIDOMEventTarget domEventTarget = (nsIDOMEventTarget)
dw.queryInterface(nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID);
domEventTarget.addEventListener("mouseover", new EventListener(),
false);
EventListener class implements nsIDOMEventListener. This doesn't work,
the method handleEvent is not called:( "mousemove", "click" and many
others don't work either.
Then I thought that after a page is loaded in browser its content window
changes, so I need to add an event listener only after the page is
loaded. It is possible with nsIWebProgressListener:
browser.addWebBrowserListener(new WebBrowserListener(),
nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
WebBrowserListener class implements nsIWebProgressListener,
nsIWeakReference and nsIInterfaceRequestor interfaces. This doesn't work
either: Java crashes somewhere deep in xul.dll in the call to
addWebBrowserListener(). CCing this letter to Javier (the author of
JavaXPCOM library), not sure if he is subscribed to the dev-embedding alias.
As for documentation... I use XulPlanet web site, Xulrunner/Mozilla
source tree and Eclipse AJAX Tools Framework (it uses JavaXPCOM also) -
not very easy to get a help but better than nothing:)
Thank you for the help,
Artem
Niky Williams wrote:
In reference to making the browser window scroll, I don't have any
issues with that on my C++ app. I did not have to register or enable
anything for that to work..it just..worked. :-( I'm sorry I can't help
you on that one.
However, let me pull some code out here and see if any of it can help
you with events and such.
I'm not real sure how you embed Gecko with Java, but in my class
definition for C++, this is how I have it defined
class CGecko :
public nsSupportsWeakReference,
public nsIWindowCreator,
public nsIWebBrowserChrome,
public nsIEmbeddingSiteWindow,
public nsIWebProgressListener,
public nsIInterfaceRequestor,
public nsIPromptService,
public nsIDOMEventListener
{
...
};
Notice I have quite a bit more things implemented there than what you
have stated in your app...again, I'm not sure how different Java is from
C++ when doing this, but you will need to implement
nsIWebProgressListener and nsIDOMEventListener if you ever want to
receive events such as click, dblclick, load, document start/stop load,
etc...
First thing is that you will need to register for what I call the web
browser events (start/stop load), this is how I do it:
This is done in the initialization of the chrome and browser, etc..
//----------------------------------------------------------------------
//Now trying to setup for events from the web progress listener if
( (pCOM_wr = do_GetWeakReference (NS_STATIC_CAST
(nsIWebBrowserChrome*, pCg))) == 0 ||
NS_FAILED (pCOM_wb->AddWebBrowserListener (pCOM_wr, NS_GET_IID
(nsIWebProgressListener))))
{
MsgBox (0, "CreateChromeWindow (): Failed to create the web event
listener.", __FILE__, __LINE__);
Shutdown ();
return (S_FALSE);
}
//----------------------------------------------------------------------
I never completely understood the above part, why you needed a weak
reference, but it works LOL. I grab a weak reference (this is why you
see nsSupportsWeakReference listed as one of my base classes, so I can
QI it from my class), then call AddWebBrowserListener () from my
nsIWebBrowser interface. That should set you up to receive 2 critical
events, "Document Start Load" and "Document Stop Load"
Now that you can receive events when the document starts/stops loading,
you can then register for "DOM Events", this is how I do it:
The below method is part of nsIWebProgressListener interface and where
you determine the Document Start/Stop event
NS_IMETHODIMP CGecko::OnStateChange (nsIWebProgress *aWebProgress,
nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
{
//Temp vars
nsCOMPtr<nsIWebNavigation> pCOM_wn;
nsCOMPtr<nsIURI> pCOM_u; nsCOMPtr<nsIDOMWindow> pCOM_dw;
nsCOMPtr<nsIDOMEventTarget> pCOM_det;
nsCString csURI;
char *pszURI = 0;
//Getting URI that loaded and making sure we have an object
if (
(pCOM_wn = do_QueryInterface (pwb)) == 0 ||
NS_FAILED (pCOM_wn->GetCurrentURI (getter_AddRefs (pCOM_u))))
{ MsgBox (this, "OnStateChange (): Failed to
retrieve URI.", __FILE__, __LINE__);
return (S_FALSE);
}
//Getting the URI here
pCOM_u->GetSpec (csURI);
//Seeing what is going on with the doucmnet
if (aStateFlags & STATE_IS_DOCUMENT)
{ if (aStateFlags & STATE_START)
{
...
}
if (aStateFlags & STATE_STOP)
{ //Getting DOM Window to get the event
target
aWebProgress->GetDOMWindow (getter_AddRefs (pCOM_dw));
//Getting event target
pCOM_det = do_QueryInterface (pCOM_dw);
//Setting up listeners on the DOM window
//FOR ABORT
//----------------------------
//Unregistering listener first incase it's already registered
for this..Prolly not necessary
pCOM_det->RemoveEventListener (NS_ConvertUTF8toUTF16
("abort"), this, false);
//Registering listener
pCOM_det->AddEventListener (NS_ConvertUTF8toUTF16 ("abort"),
this, false);
//----------------------------
...
}
}
If you want to setup for other events, you just add another block of
code and use "click", "dblclick", "load", etc...
Then once that is done, you will receive notifications through your
nsIDOMEventListener::HandleEvent () method
To figure out what event is happening, this is how I do it in that method.
NS_IMETHODIMP CGecko::HandleEvent (nsIDOMEvent *event)
{
//Temp vars
nsString sType;
//Getting the type of event that happened
event->GetType (sType); //Going to see what event happened and
pass along the info in a POST command
if (wcsicmp (sType.get (), L"Abort") == 0)
{ ...
}
...
}
Just add more compares here for what events you need to catch and deal
with the events when they come along.
I hope this helps, or at least gives you a start in the direction you
need to head with your Java app. Unfortunately, I have not been able to
find a good tutorial online anywhere, I THINK there was one posted on
the boards no too long ago. I use http://www.xulplanet.com/ a lot as a
reference...no code examples but a great reference. Also, if you can
find it...there is a plugin for Firefox that is an XPCOM component
viewer. It shows you all the interfaces on your system. Sometimes just
browsing through them can help you find the right interface you need for
things. I've just pieced things together as I have come across them and
documented them as best I could so I knew what they were. If I didn't
have a full time job and a family I'd write up a tutorial for
C++....darn responsibilities LOL. I wish you luck in your endeavor and
feel free to ask any other questions. I'll try to help you if I can.
Nik Williams
Artem Ananiev wrote:
I noticed these events (nsIDOMxxxEvent) yesterday but had no idea how
I could register my application to listen to them. I have an instance
of nsIWebBrowser and nsIWebBrowserChrome. Using queryInterface I can
get browser chrome's nsIBaseWindow - but none of these classes has any
method like addEventListener() or something like this.
As for browser scrolling - I don't need to receive scrolling events
(may be need them later), but want the browser to react on them
itself. For example, if I click a link inside a browser, it follows
that page automatically without any actions in my code, but for
scrolling this is not a case. Do I need to listen to key/mouse events
myself and then tell the browser to perform what I need?
If you can send me some short example it would be fine. Also, don't
you know is there any tutorial about mozilla UI (windows, widgets,
events, etc.) available? All I can find in the web is descriptions of
Mozilla interfaces, not how to use them together:(
Thanks,
Artem
Niky Williams wrote:
Artem Ananiev wrote:
I'm embedding Mozilla-based browser into my Java application using
JavaXPCOM, on Windows. One of the first difficulties I met is that
browser doesn't react on mouse wheel, thoug its scrollbar is
present. My container implements these interfaces:
nsIWebBrowserChrome, nsIWebBrowserChromeFocus,
nsIEmbeddingSiteWindow. What should I do to enable mouse wheel in
embedded browser?
Another question is: is it possible to get mouse and key events
occuring in browser? I don't need them right now but they can be
useful in my app later.
Thanks,
Artem
Artem,
I'm not real familiar with Java, but to receive events in my C++ app,
I implement the nsIDOMEventListener interface. You have to setup the
events you want notification from for this to work, but it's not that
hard. If you get to the point you need code examples, I can provide
you some in C++.
If you want to DISPATCH key or mouse events to an element, take a
look at:
nsIDOMDocumentEvent
nsIDOMEvent
nsIEventTarget
nsIDOMKeyEvent
nsIDOMMouseEvent
Again, if you need some code examples, I can provide you with a few.
Hope this helps!
Nik Williams
_______________________________________________
dev-embedding mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-embedding
_______________________________________________
dev-embedding mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-embedding