Files
jlibcom/EventCallbacks.htm
clay_shooter 43dce6d42f Generated basic javadoc for most methods. Still need some help here
Reformatteda all source using eclipse
eliminated parameters with same names as method variagles
repackaged all tests so that their package names match the directories they are in
merged in Jiffie and Variant EventProxy changes
2005-01-08 17:02:55 +00:00

284 lines
12 KiB
HTML
Raw Blame History

<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 11">
<meta name=Originator content="Microsoft Word 11">
<link rel=File-List href="EventsAndCallBacks_files/filelist.xml">
<title>Jacob can register Java classes for MS application events or callbacks</title>
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:RemovePersonalInformation/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:DisplayBackgroundShape/>
<w:SpellingState>Clean</w:SpellingState>
<w:GrammarState>Clean</w:GrammarState>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SelectEntireFieldWithStartOrEnd/>
<w:UseWord2002TableStyleRules/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
</w:LatentStyles>
</xml><![endif]-->
<style>
<!--
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Courier New";
mso-fareast-font-family:"Times New Roman";}
span.SpellE
{mso-style-name:"";
mso-spl-e:yes;}
span.GramE
{mso-style-name:"";
mso-gram-e:yes;}
@page Section1
{size:8.5in 11.0in;
margin:1.0in 65.95pt 1.0in 65.95pt;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.Section1
{page:Section1;}
/* List Definitions */
@list l0
{mso-list-id:369961789;
mso-list-type:hybrid;
mso-list-template-ids:-80199436 -1920937264 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
{mso-level-text:"%1\)";
mso-level-tab-stop:42.0pt;
mso-level-number-position:left;
margin-left:42.0pt;
text-indent:-24.0pt;}
@list l1
{mso-list-id:1316765558;
mso-list-type:hybrid;
mso-list-template-ids:860497186 -1920937264 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l1:level1
{mso-level-text:"%1\)";
mso-level-tab-stop:42.0pt;
mso-level-number-position:left;
margin-left:42.0pt;
text-indent:-24.0pt;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
-->
</style>
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin:0in;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]-->
</head>
<body lang=EN-US style='tab-interval:.5in'>
<div class=Section1>
<p class=MsoPlainText>Jacob can register Java classes for MS application events
or callbacks.<span style='mso-spacerun:yes'><EFBFBD> </span>The normal flow for this
is:</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Application thread creates an instance of the
event handler and registers it with Jacob</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The application continues on doing other work.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Some time later, the MS application takes some
action and initiates the event callback.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The Java VM receives the event and spins up a
new thread to handle it.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>5)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
in the <span class=SpellE>dll</span> is called by the VM.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>6)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
creates Variant objects to handle the parameters of the passed in event.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>7)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
uses reflection to map the event name to a method name with the exact same
name.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l1 level1 lfo1;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>8)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
sends the message to the registered event handler.</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText>Swing developers should note that this message comes in
on a thread other than the event thread.<span style='mso-spacerun:yes'><EFBFBD>
</span>All objects receiving events that require user intervention or drawing
in the UI should use <span class=SpellE><span class=GramE>invokeLater</span></span><span
class=GramE>(</span>) to post requests for actions onto the event queue.<span
style='mso-spacerun:yes'><EFBFBD> </span>Failure to do so will insure random failures
in the GUI.</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText>Java Web Start (JWS) and other launchers can have
additional issues related to the class loader.<span style='mso-spacerun:yes'><EFBFBD>
</span>The Jacob C++ library uses <span class=SpellE><span class=GramE>FindClass</span></span><span
class=GramE>(</span>) to find the Variant class when building the parameter
list.<span style='mso-spacerun:yes'><EFBFBD> </span><span class=SpellE><span
class=GramE>FindClass</span></span><span class=GramE>(</span>) uses the system
class loader which includes only the classes specified at run time or in the
CLASSPATH.<span style='mso-spacerun:yes'><EFBFBD> </span>Most of the application
classes in this situation live in an alternate set of class loaders that were
created when the launcher located and ran the application classes.<span
style='mso-spacerun:yes'><EFBFBD> </span>This means that the search for Variant will
fail usually with the silent and immediate termination of the Java application.<span
style='mso-spacerun:yes'><EFBFBD> </span>The thread <span class=SpellE>classloader</span>
probably can<61>t be used to try and find the class because this new thread does
not have a <span class=SpellE>classloader</span> associated with it other than
the system class loader.<span style='mso-spacerun:yes'><EFBFBD> </span>The end result
is that the Variant class needs to be located via other means and that the
thread <span class=SpellE>classloader</span> should be set to be the context
class loader of the event handler class.</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText>The Jacob <span class=SpellE>EventProxy</span> class has
been modified (off of the 1.8 tree) so that it takes a two step approach to towards
fixing these problems.</p>
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span></p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span class=SpellE>EventProxy</span> first
attempts to locate the Variant class using <span class=SpellE>FindClass</span>()</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>Failing that, it looks to see if the event
callback object implements <span class=SpellE><span class=GramE>getVariantClass</span></span><span
class=GramE>(</span>) that returns the <span class=SpellE>Variant.class</span>
object.<span style='mso-spacerun:yes'><EFBFBD> </span>If so, it uses that class to
create variants for the callback parameters.</p>
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
l0 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]>If all that fails, it logs a message and then
fails in the spectacular fashion of the previous versions.</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText>This means developers can receive call back events in JWS
other Java launching programs by implementing <span class=SpellE><span
class=GramE>getVariantClass</span></span><span class=GramE>(</span>) on all of
their classes that receive Microsoft Events.<span style='mso-spacerun:yes'><EFBFBD>
</span>The <span class=SpellE><span class=GramE>getVariantClass</span></span><span
class=GramE>(</span>) method has the added benefit of providing a spot for the
thread <span class=SpellE>classloader</span> to be set:</p>
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Public Class <span
class=SpellE><span class=GramE>getVariantClass</span></span><span class=GramE>(</span>){</p>
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span class=SpellE><span class=GramE>Thread.currentThread</span></span><span
class=GramE>(</span>).<span class=SpellE>setContextClassLoader</span>(</p>
<p class=MsoPlainText><span style='mso-tab-count:3'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
class=SpellE><span class=GramE>this.getClass</span></span><span class=GramE>(</span>).<span
class=SpellE>getClassLoader</span>());</p>
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span class=GramE>return</span> <span
class=SpellE>Variant.class</span></p>
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>}</p>
<p class=MsoPlainText><o:p>&nbsp;</o:p></p>
<p class=MsoPlainText>There may still be a dual event queue issue in JWS
applications that needs to be looked at.</p>
</div>
</body>
</html>