I have a web application that processes events and audio received from a specialised microphone. The audio is processed by a Java applet that runs in the web page, but other events (microphone connected, microphone disconnected, microphone button pressed) are handled by an ActiveX object.
The ActiveX object traps these events and calls JavaScript code to handle them
<!-- Load the ActiveX control -->
<object id="PhilipsSpeechMikeCtrl" width="0" height="0" tabindex="-1"
classid="CLSID:AAA44754-CC81-4692-91AF-7064E58EB22A"
standby="Loading Philips SpeechMike component..."
type="application/x-oleobject">
</object>
<script type="text/javascript">
// This is Microsofts javascript way of trapping ActiveX object events.
function PhilipsSpeechMikeCtrl::SPMEventDeviceConnected(deviceID) {
// Call JavaScript code to handle the microphone connected event
}
function PhilipsSpeechMikeCtrl::SPMEventDeviceDisconnected(deviceID) {
// Call JavaScript code to handle the microphone disconnected event
}
function PhilipsSpeechMikeCtrl::SPMEventButton(deviceID, eventId) {
// Call JavaScript code to handle the microphone button pressed event
}
</script>
Of course a problem with this approach is that it's completely IE dependent. I would prefer to load the ActiveX object within the applet, trap the events there and handle the events either within the applet, or JavaScript code called from the applet. This should then enable me to run the app in any browser that supports applets.
I'm not entirely sure how to go about implementing the solution I've proposed above, any suggestions?
Update: I realise the solution I've proposed above would still be IE dependent, that's fine. My immediate goal is to support all browsers on Windows.
It has been suggested that instead of using ActiveX, I could use JNI (or JNA) to access the DLLs underlying the ActiveX object. However, I don't actually want to call the functions in the DLLs, I want the DLLs to call me, i.e. register an event handler.
Thanks,
Don
ActiveX are not supported by an another browser than IE, so there is no way for your application to support all browsers, even on Windows only.
An attempt (plugin) to port ActiveX under Firefox 1 was made, but wasn't really useful so as far as I know, there is today no "emulation" solution to your question.
Sorry...
(see here for Mozilla comments)
JACOB is supposed to let you call COM from Java. It looks like it supports events too.
You can probably access the dlls in the activeX component directly,
so you can write a jni wrapper that calls the native functions,
and then build a signed applet that can get permission to use jni.
Check this:
http://www.raditha.com/java/jni/
Ahh. You can do want you desire, but may have to eschew Javascript and instead leverage VBScript. It is about the ability to send "events" between two components.
You can use use JavaScript to directly call public methods in the applet or access public variables. JavaScript treats the embedded applet as an object. In the applet tag give the applet a name id.
Consider the example below where the applet has a method public void myMethodInMyApplet();
The HTML page would look something like :
<APPLET CODE="MyApplet.class"
width=200 height=200
name=counter ID=counter>
</APPLET>
<script type="text/javascript">
// This is Microsofts javascript way of trapping ActiveX object events.
function PhilipsSpeechMikeCtrl::SPMEventDeviceConnected(deviceID) {
document.applets[0].myMethodInMyApplet();
}
</script>
Wouldn't that still be Windows- or even IE-dependent, given that Java applets are executed on the client side? Just wondering...
You will obviously have to pass the events twice if you want them to end up in JavaScript.
There is a version of SWT that can be used in applets and can embed ActiveX controls. There are also commercial libraries like Coroutine who can do this as well (and are smaller in jar size). Someone else mentioned JACOB here, which would be another choice.
So, use any of these components to wrap your ActiveX control. These libraries will call a Java method when a registered event occurs.
To pass events from Java to JavaScript, you can use the netscape.javascript.JSObject class which is supported by all major browsers.
If you have the source code for the COM component, it might be a good idea to rewrite it to use JNI, as COM wrappers use up a lot of resources (which is especially important in applets), and most probably there is also some overhead inside the COM component for COM interop.
is activexobjects always hitting the acivex sites like activex.microsoft.com
Related
Suppose we have an applet on a webpage and JQuery code in the same page, as well. How can we notify JQuery upon an Applet action, for instance a timer in the applet stops and a file system change occurs, and i want to make some process upon this file change in JQuery part as soon as the change occurs. Any suggestions / solutions? Thanks.
You can start with short article: Java - Javascript interaction.
And then see Java-to-Javascript Communication and
JavaScript to Java Communication (Scripting) for more info.
My problem is pretty simple i have an application written in java and i want to send commands to it ex ( click a button , send some key strokes , click a menu item ) from my application witch i will write in delphi. Is this concept even possible ?
I actually had to do this at the last place I worked, you can get around it with complex window events etc... as mentioned above but if you have access to the Java source simply write other access methods either that call a specific runtime that closes (i.e. trigger a public static void main(String[] args); via a native call or via the command line.
OR
Implement simple a simple message system between Java/Delphi over TCP/IP and send either XML or some simple string mappings (I think it took about an hour to set up Maps that could pass back and forth).
In my case we were simply handling reporting and talking to the database so it was pretty easy to work around without getting into a native call. Alternatively, there is(was) a port of the JNI for Delphi that worked pretty well with Delphi 7. I have no clue what runtime you're using but it might be an option.
Honestly, the TCP/IP method is probably the easiest. It doesn't take a lot to implement, it doesn't eat a lot of resources and it allows you to execute "myMenuItem.onClick()" pretty easily as a packet, you just have to expose the methods.
http://home.pacifier.com/~mmead/jni/delphi/
Well It depends on which Java GUI technology is used . If SWT or AWT is used , you can get handle of UI components, because these two toolkit uses native libararies.. On the other hand, if that java application GUI is created by beans of SWING, you can not get any handle. Because, swing toolkit is implemented by pure Java..
If the Java app can be modified, the Java Robot API (included in JRE 1.3 and newer) might be helpful. This would allow to control a Swing application which does not provide windows handles as Gursel wrote. Obviously there would be some IPC required, which could be implemented using sockets for example.
The short: YES, but depending on the Java application, it might be difficult and unreliable.
I'm not a Java guy so I don't know if this is the norm, but the one Java application I had to automate displayed a single dialog that only used 1 (one) window handle! It was made up of several edit boxes, buttons, what looked like combo-boxes, but those were not true Windows controls but widgets re-created by whatever GUI toolkit the original developer used. I wasn't able to use normal Windows messages to manipulate those because, as far as Windows was concerned, it was a single window.
Happily the only thing I had to do was click a single button. I used mouse_event to move the mouse over the expected area for the button and then again to click the button. It works, but manipulating input this way is both unreliable and fragile.
To clarify Daniel ChapmanĀ and mjnĀ comments, find below a code extract showing Delphi controlling a Java Swing UI component (TextField) contained in a Jframe based on NetBeans ClientEditor sample.
Please notice, that this example does not use the Java source code or use TCP, XML, Windowing events handling technics or IPC, it's just simply Delphi code calling some Java code.
procedure TForm1.Button1Click(Sender: TObject);
begin
FJFrame := Tjavax_swing_JFrame.Create('Client Editor');
FClientEditor := Tclienteditor_ClientEditor.Create;
FJFrame.GetContentPane().Add(FClientEditor);
FJFrame.Pack;
FJFrame.SetVisible(True);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// Delphi setting a value in a Java Swing UI component
FclientEditor.FirstNameTextField.SetText('Delphi 1stName');
end;
The long type names are just as a matter of clarity for this example and can be shorter of course.Additionally there is no problem with JNI in this example.
Have you had a look at Java for Delphi?
It let's you call Java from Delphi exposing the Java types as Delphi types.
I've been trying to understand how flash animations or a Java Applet work within a browser.
I can think of a couple of ways -
The Flash Player/Java Applet are machine code that's dynamically linked it, and given
some parameters about the area of the screen that belongs to them; after that, they
run within the same process space.
The browser exposes an API that the player/applet use to talk to it and they live
in a separate process. (Presumably they talk via sockets?) The API could correspond to
openGL/X11/some custom calls.
These possibilities still don't explain things like how a button click can make the
player full-screen, how it can play music, how it can inspect the DOM, etc. For that matter,
is the video displayed by decoding to a sequence of images, and rendering them
one at a time, or is there a more efficient way, e.g., of pushing the deltas in the image?
The Wikipedia page on Java Applets (1)
talks about how the applet is run in a sandbox (presumably a separate process), but
it doesn't say how the browser and the applet communicate.
Perhaps the answer depends on the underlying platform?
Any pointers to systematic discussion of this topic would be appreciated (as would
a reference to the APIs).
(My interest in this stems from an insatiable curiosity.)
I'm pretty sure plugins like Java applets and Flash run via NPAPI in most browsers. I looked into this matter myself some time ago and NPAPI was the answer I found.
In the case of browser and Java applets, the applets are typically run within the Java plugin, which runs as a separate process (you can see it e.g. in the task administrator in Windows).
The plugin creates an object for each applet in the DOM, and you can thus interact with the applet from Javascript. Anyway, calls to the applet that take a while to return do have the effect to freeze the browser, therefore I'd say the communication with the plugin runs in the same thread as the main refresh loop. This seems at least to be the case with Firefox.
I have some long-running Java code running in a thread started by a Java applet. As soon as the code has finished, it has information for the user. I'd like to pass this information to a JavaScript callback in a thread-safe way. Just using the Java DOM API to modify the HTML document is not good enough, unless my JavaScript callback gets called as a side effect in a thread safe way (i.e. eventually, in the same browser thread where JavaScript callbacks execute). How can I implement this? Are there libraries already doing it?
Looks as though the Common DOM API is what you need. In essence you request a DOMService to call you back on the main UI thread when it is good and ready.
http://docs.oracle.com/javase/1.5.0/docs/guide/plugin/developer_guide/java_js.html
As I understand things, JSObject is the "old way" and the Common DOM API is the newer way (as of Java 6). What you need to do is call a method of your applet and pass the function object that you want to have called back. Your applet then calls that function object from within your DOMAction.
I have no code at hand to show you and this is not something I've done before using Java. However I have used a similar technique from with an NPAPI web plugin written in C++ i.e. had JS call my C++ object passing a function as a parameter, and then at a later stage, have the C++ object call the JS function. 'hope that this helps.
I had concurrency issues with multiple applet threads calling Javascript. Some of the calls were simply ignored by Internet Explorer 8 (Firefox 3.6 and Safari 5 worked fine).
I tried to wrap calls to Javascript with DOMService.invokeAndWait - that didn't help.
I ended up ensuring that all the Java->Javascript calls are made from the same thread, and my problems were solved (at least temporarily - I haven't checked what happens if the Javascript thread is busy with some user-initiated work).
To serialize the calls, I used Executors.newSingleThreadExecutor
It seems that there is no public tutorial how to do it. The whole JavaScript--Java interface is underdocumented, and it is subject to browser limitations.
I am working for a developing firm and am doing a major redesign on a Web Application, which reloaded everything after each click, to make extensive use of Javascript, so it actually feels like a real Web application. One of the Features is to use a web-based Painter (think of MSPaint on the Web), which I embed on the Page on Demand. After the image is painted and uploaded, the Web-app then unloads the applet and proceeds to show the directory where the file was uploaded to.
This is where Trouble starts. It all works on IE and Safari, but not on Firefox 3.5 (3.0 works perfectly though). Firebug tells me that the expando property is missing.
The Web-app Tiparlo which I was working on before had a similar Problem (in fact, any manipulation done on an applet via jQuery is faulty) but solved that Problem by wrapping a div around and controlling (hide and show) the div instead of the applet. This, unfortunately isn't applicable on this Web-app, because the Applet has to be destroyed and not just hidden and shown, as it takes up too much resources to be run the entire time where it is not needed.
To make it short: Is it possible to make an Applet destroy itself via Javascript? Alternatively: Is there a workaround on the jQuery/expando/applet problem? I know that applet is deprecated in HTML 4.01 strict but changing it to object is not an option right now.
EDIT: I have added a Picture of Firefox + Firebug to show you the actual Error Message. Posting Code does no god, since it works flawless on every other Browser and is a Firefox 3.5 specific Problem. Here be pictures
Note: You can ignore the JS Bug coming from button.js.
You could always load the applet in a an iframe and just navigate away from the page where the applet is loaded. This will kill it.
Your other option if you want to call the destroy from javascript would be to put something like this in.
<script>
document.MyApplet.killApplet();
</script>
public void killApplet() {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
// kill the JVM System.exit(0); return null;
}
});
}
This is not a nice way to kill an applet but on newer browsers it does not throw a JS error, on older ones like IE6 it will throw a js error.
I would suggest that you create a class that monitors the applet to be killed. run the monitor as some sort of servlet and get javascript to post 'kill applet' commands when it needs to be killed.