<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Blair Robot Project Blog &#187; Java</title>
	<atom:link href="http://robot.mbhs.edu/wordpress/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://robot.mbhs.edu/wordpress</link>
	<description></description>
	<lastBuildDate>Thu, 04 Mar 2010 16:10:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating an Eclipse Plug-in Update Site &#8211; And Fixing Hidden Errors in Plug-ins</title>
		<link>http://robot.mbhs.edu/wordpress/2009/creating-an-eclipse-plug-in-update-site-and-fixing-hidden-errors-in-plug-ins/</link>
		<comments>http://robot.mbhs.edu/wordpress/2009/creating-an-eclipse-plug-in-update-site-and-fixing-hidden-errors-in-plug-ins/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 07:40:20 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://robot.mbhs.edu/wordpress/?p=406</guid>
		<description><![CDATA[Today, I set out to create an Eclipse update site to host Team 449&#8217;s plug-ins.  (If you&#8217;re in a rush for answers, just scroll to the bottom.)
Eclipse is actually one of the less buggy of applications.  It doesn&#8217;t crash every three minutes like Bloodshed Dev-C++, it doesn&#8217;t crash every two minutes like Internet [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I set out to create an Eclipse update site to host Team 449&#8217;s plug-ins.  (If you&#8217;re in a rush for answers, just scroll to the bottom.)</p>
<p>Eclipse is actually one of the less buggy of applications.  It doesn&#8217;t crash every three minutes like Bloodshed Dev-C++, it doesn&#8217;t crash every two minutes like Internet Explorer, and it doesn&#8217;t crash every minute like Windows.  The Java development environment is beautiful, the task management system is well-designed if poorly-integrated, and the C++ development environment is second only to Emacs, Vim, Ed, and the ever-elusive butterfly technique (its not actually that great).  Eclipse has a unique system of managing views and perspectives that allows a huge amount of flexibility to the user.  But Eclipse&#8217;s plug-in development environment is less than satisfactory to the developer.</p>
<p>To begin with, Eclipse plug-ins are based on a less-than-easy-to-use API.  Sure, its easy to do the things the designers anticipated you would be doing &#8211; like compiling their sample projects.  But there&#8217;s no level of abstraction between &#8220;here&#8217;s a method to do exactly what you want&#8221; and rewriting half the API from scratch.  Furthermore, the Eclipse developers insisted on creating their own system for everything, from user interface functionality to file system access.  A good deal of the documentation is totally obscure, and the sample projects are no help.</p>
<p>Now suppose you&#8217;ve suffered through the experience of writing a plug-in, you&#8217;re almost done, and you&#8217;re ready to export.  Or more likely, you&#8217;ve just begun, and you&#8217;re ready to export just to see what happens.  There&#8217;s just one little problem &#8211; that tiny icon over in the &#8220;package explorer&#8221; with the red X or the yellow exclamation point &#8211; Eclipse doesn&#8217;t like something.  Such was my situation as I was trying to export my plugin, so that I could export my feature, so that I could test my update site.</p><span id="more-406"></span>
<p>Now if you&#8217;re lucky &#8211; and odds are you&#8217;re not &#8211; that little icon will be over a &#8220;.java&#8221; file.  That means you messed up your Java code, and that can be fixed with relative ease.  If you&#8217;re unlucky, that icon will be over the <code>build.properties</code> or <code>MANIFEST.MF</code> file.  You double click on that file, glance through the tabs, and discover that in none of the tabs does Eclipse have a complaint.</p>
<p>So I think to myself (or you think to yourself), &#8220;oh, I&#8217;ve been here before.  I just have to look <em>really</em> carefully, and I&#8217;ll find it.&#8221;  Now, I think that memory is actually a dream.  The technique didn&#8217;t work. Ok, maybe Eclipse is caching something.  Nope, restarting Eclipse doesn&#8217;t help.</p>
<p>The end result was that I went to the tab &#8221;plugin.xml&#8221;, went through the source code, found the error, went to the related part of the wizard, and fixed it.  But that&#8217;s not what happened next.</p>
<p>I decided that the warning probably didn&#8217;t matter, so I went right ahead and created my update side.  Oops!  It won&#8217;t let me add plug-ins, I can only add features.  Ok, that&#8217;s fine, I&#8217;ll create a feature with one plug-in in it, and add it.  I create the feature &#8211; no problems there.  I add it to the update site &#8211; no problems there.  I click &#8216;build all&#8217;, thinking, &#8220;wow, this is easy!&#8221;</p>
<p>Nothing happens.</p>
<p>I remove the feature and put it back in.  Doesn&#8217;t help.  I create a category and put the feature in it.  Doesn&#8217;t help.  Finally, I decide to go back and fix the plug-in.  I finally land upon the correct tab, find the problem, find the associated part of the wizard, and fix it.  I go back to the update site, remove the plug-in, add the plugin, and click &#8216;build all&#8217;.  The progress bar scrolls nicely along, and then I refresh the project.  <strong>Tada!</strong>  Lots of new material.  I look through it and like what I see.  Now I&#8217;m ready to place this site online.</p>
<p>I create a new directory in my raw data folder (created as an easy way to avoid ending up with my serving script happily spitting out its own source code, passwords and all) called &#8220;eclipse-update&#8221; and copy the whole mess produced by Eclipse into there.  The <code>content.xml</code> file is surprisingly large, but at this point I don&#8217;t have enough curiosity to find out what&#8217;s in it.  Now, as a test, I go there in my web browser.  <a href="http://robot.mbhs.edu/eclipse-update/">Here, that is</a>.  And what I get is:</p>
<a href="http://robot.mbhs.edu/wordpress/2009/creating-an-eclipse-plug-in-update-site-and-fixing-hidden-errors-in-plug-ins/screen/" rel="attachment wp-att-412"><img src="http://robot.mbhs.edu/wordpress/wp-content/uploads/2009/06/screen-300x187.png" alt="Eclipse Update Site Not Working" title="Eclipse Update Site Not Working" width="300" class="alignnone size-medium wp-image-412" /></a>
<p>In case you can&#8217;t make it out, it says &#8220;undefined&#8221;.  I look at the source code, and it is just one big mess of Javascript.</p>
<p>So again, I try to just accomplish the goal, and leave all the niceties to rot.  For once, things decide to start working.  I add the update site, and everything shows up properly.  I select &#8220;Team 449 Eclipse Plugins&#8221; and click &#8216;install&#8217;.  The progress bar moves, albeit somewhat sluggishly, my Internet connection falters but does not die, and the selected items install.  Well, sort of. There was just the little glitch of, Eclipse appeared to think that every plugin I had installed on my machine was a dependency for the one I had created, so I made a mental note to fix that.  Other than that, there was no problem installing.</p>
<p>Now its back to fixing the niceties. With my fingers crossed, I go to the index.html page again, and check firefox&#8217;s error console for errors it produced.  If there were any, fixing them should be easy.  Nope, none (save for some CSS errors).  Great. Now I go to the source code.  Here it is (without the HTML):</p>
<div class="geshi javascript"><ol><li class="li1"><div class="de1">&nbsp;<span class="kw2">var</span> returnval = <span class="nu0">0</span>;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">var</span> stylesheet, xmlFile, cache, doc;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// NSCP 7.1+ / Mozilla 1.4.1+ / Safari</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// Use the standard DOM Level 2 technique, if it is supported</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>document.<span class="me1">implementation</span> <span class="sy0">&amp;&amp;</span> document.<span class="me1">implementation</span>.<span class="me1">createDocument</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;xmlFile = document.<span class="me1">implementation</span>.<span class="me1">createDocument</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span>, <span class="kw2">null</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;stylesheet = document.<span class="me1">implementation</span>.<span class="me1">createDocument</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span>, <span class="st0">&quot;&quot;</span>, <span class="kw2">null</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>xmlFile.<span class="me1">load</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; xmlFile.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;site.xml&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; stylesheet.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;web/site.xsl&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Document could not be loaded by browser.&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;xmlFile.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">&quot;load&quot;</span>, transform, <span class="kw2">false</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;stylesheet.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">&quot;load&quot;</span>, transform, <span class="kw2">false</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">//IE 6.0+ solution</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">ActiveXObject</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;xmlFile = <span class="kw2">new</span> ActiveXObject<span class="br0">&#40;</span><span class="st0">&quot;msxml2.DOMDocument.3.0&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;xmlFile.<span class="me1">async</span> = <span class="kw2">false</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;xmlFile.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;site.xml&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;stylesheet = <span class="kw2">new</span> ActiveXObject<span class="br0">&#40;</span><span class="st0">&quot;msxml2.FreeThreadedDOMDocument.3.0&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;stylesheet.<span class="me1">async</span> = <span class="kw2">false</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;stylesheet.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&quot;web/site.xsl&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;cache = <span class="kw2">new</span> ActiveXObject<span class="br0">&#40;</span><span class="st0">&quot;msxml2.XSLTemplate.3.0&quot;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;cache.<span class="me1">stylesheet</span> = stylesheet;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;transformData<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="co1">// separate transformation function for IE 6.0+</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">function</span> transformData<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">var</span> processor = cache.<span class="me1">createProcessor</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; processor.<span class="me1">input</span> = xmlFile;</div></li>
<li class="li1"><div class="de1">&nbsp; processor.<span class="me1">transform</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; data.<span class="me1">innerHTML</span> = processor.<span class="me1">output</span>;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="co1">// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+ </span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">function</span> transform<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; returnval+=<span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>returnval==<span class="nu0">2</span><span class="br0">&#41;</span><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">var</span> processor = <span class="kw2">new</span> XSLTProcessor<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;processor.<span class="me1">importStylesheet</span><span class="br0">&#40;</span>stylesheet<span class="br0">&#41;</span>; </div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;doc = processor.<span class="me1">transformToDocument</span><span class="br0">&#40;</span>xmlFile<span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&quot;data&quot;</span><span class="br0">&#41;</span>.<span class="me1">innerHTML</span> = doc.<span class="me1">documentElement</span>.<span class="me1">innerHTML</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li></ol></div>
<p>Ahh&#8230;.  This makes some sense.  First, I note that IE is treated differently.  Does the IE version work?  Yes!  Now we can ignore all the non-IE parts.  I pull up Safari 4 Beta and test it there.  It doesn&#8217;t work there instead: I get the popup error message &#8220;document could not be loaded by browser&#8221;.</p>
<p>This is an important clue, since I know that this error message is only supposed to pop up when <code>xmlFile.load</code>, which is a function, does not exist.  On the assumption that <code>xmlFile</code> is a <code>document</code>, I search and discover that even the examples on W3Schools don&#8217;t work on Safari.  Great &#8211; the one browser that passes Acid3 doesn&#8217;t even support &#8220;standard DOM Level 2 techniques&#8221;.</p>
<p>This just leaves Firefox.  Suspecting that the problem lies in <code>transform()</code>, I add <code>alert()</code> statements for each variable.  My discovery is that everything exists but <code>doc.documentElement.innerHTML</code>.  After experimenting around a while, I decide that it is probably the fault of Firefox.  Just to be sure, I navigate to some other update sites.  I get a variety of results, including raw xml, but none of them actually work.</p>
<h3>The Answer</h3>
<p>Be sure there are no warnings in any <code>build.properties</code> files by going to the tab that contains the xml code, finding the error, and correcting it by finding the related part of the other pages.  Then remove from and place back in the update site the affected plug-ins.  Build your update site, and then refresh the project so that you can see what&#8217;s going on.</p>
<p>You can just use an ftp client to upload the files now, and your update site will be working.  Be sure to copy <em>all</em> of the files to your host server.  Your update site html page will not work in many browsers, so you should write your own.</p>]]></content:encoded>
			<wfw:commentRss>http://robot.mbhs.edu/wordpress/2009/creating-an-eclipse-plug-in-update-site-and-fixing-hidden-errors-in-plug-ins/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java OpenGL Example &#8211; Spheres</title>
		<link>http://robot.mbhs.edu/wordpress/2009/java-opengl-example-spheres/</link>
		<comments>http://robot.mbhs.edu/wordpress/2009/java-opengl-example-spheres/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 18:42:54 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JOGL]]></category>
		<category><![CDATA[opengl]]></category>

		<guid isPermaLink="false">http://robot.mbhs.edu/wordpress/?p=290</guid>
		<description><![CDATA[For those who want to take advantage of both hardware acceleration and Java&#8217;s cross-platform compatibility, Java has an OpenGL binding, known as JOGL.  This binding is exactly the same as the C version &#8211; the only difference is that Java requires all methods to be &#8216;object-oriented&#8217;.  In order to call an openGL method, [...]]]></description>
			<content:encoded><![CDATA[<p>For those who want to take advantage of both hardware acceleration and Java&#8217;s cross-platform compatibility, Java has an OpenGL binding, known as JOGL.  This binding is exactly the same as the C version &#8211; the only difference is that Java requires all methods to be &#8216;object-oriented&#8217;.  In order to call an openGL method, we first have to acquire a <code>GL</code> or a <code>GLU</code> object (depending on which library the method would come from in C), and then call the method on that.  For example, instead of the C code below:</p>
<div class="geshi no c"><ol><li class="li1"><div class="de1">glBegin<span class="br0">&#40;</span>GL_LINES<span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1"><span class="co1">//some stuff here</span></div></li>
<li class="li1"><div class="de1">glEnd<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div></li></ol></div>
<p>we would have the Java code:</p>
<div class="geshi no java"><ol><li class="li1"><div class="de1">GL gl=autoDrawableObject.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">gl.<span class="me1">glBegin</span><span class="br0">&#40;</span>GL_LINES<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1"><span class="co1">//some stuff here</span></div></li>
<li class="li1"><div class="de1">gl.<span class="me1">glEnd</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li></ol></div>
<p>This makes it easy to convert C++ to Java code, and vice versa.  In fact, if your code is longer than 100 or so lines, it&#8217;s probably best to just write a script to do the hard work for you.  The packages to include are <code>javax.media.opengl.*</code> and <code>javax.media.opengl.glu.*</code>.  As far as I know, there is no support for GLUT, at least with this particular Java OpenGL binding.  <span id="more-290"></span>The boilerplate code for Java is below.</p>
<div class="geshi no java"><ol><li class="li1"><div class="de1"><span class="kw2">package</span> edu.<span class="me1">mbhs</span>.<span class="me1">sclawren</span>.<span class="me1">misc</span>.<span class="me1">funfun</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.glu.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> FFScene <span class="kw2">implements</span> GLEventListener <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> display<span class="br0">&#40;</span>GLAutoDrawable drawable<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GL gl = drawable.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GLU glu=<span class="kw2">new</span> GLU<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//now do some drawing!</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> displayChanged<span class="br0">&#40;</span>GLAutoDrawable arg0, <span class="kw4">boolean</span> arg1, <span class="kw4">boolean</span> arg2<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; display<span class="br0">&#40;</span>arg0<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> init<span class="br0">&#40;</span>GLAutoDrawable glad<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">final</span> GL gl = glad.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//its useful to put stuff here, to</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> reshape<span class="br0">&#40;</span>GLAutoDrawable drawable, <span class="kw4">int</span> x, <span class="kw4">int</span> y, <span class="kw4">int</span> width, <span class="kw4">int</span> height<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//this is configured for full screen</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> h = <span class="br0">&#40;</span><span class="kw4">float</span><span class="br0">&#41;</span>height / <span class="br0">&#40;</span><span class="kw4">float</span><span class="br0">&#41;</span>width<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GL gl = drawable.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_PROJECTION</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glFrustum</span><span class="br0">&#40;</span><span class="nu0">-1</span>.0f, <span class="nu0">1</span>.0f, -h, h, <span class="nu0">2</span>.0f, <span class="nu0">60</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_MODELVIEW</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslatef</span><span class="br0">&#40;</span><span class="nu0">0</span>.0f, <span class="nu0">0</span>.0f, <span class="nu0">-3</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span> &nbsp; &nbsp; &nbsp; &nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">package</span> edu.<span class="me1">mbhs</span>.<span class="me1">sclawren</span>.<span class="me1">misc</span>.<span class="me1">funfun</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import java.awt.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.awt.event.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.swing.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import com.sun.opengl.util.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> FFFrame <span class="kw2">extends</span> <span class="kw3">JFrame</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;GLCanvas glScene<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;FPSAnimator animator<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> FFFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; glScene=<span class="kw2">new</span> GLCanvas<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; FFScene ff=<span class="kw2">new</span> FFScene<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;glScene.<span class="me1">addGLEventListener</span><span class="br0">&#40;</span>ff<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;animator = <span class="kw2">new</span> FPSAnimator<span class="br0">&#40;</span>glScene, <span class="nu0">20</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> display<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; setUndecorated<span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">GraphicsEnvironment</span>.<span class="me1">getLocalGraphicsEnvironment</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getDefaultScreenDevice</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">setFullScreenWindow</span><span class="br0">&#40;</span><span class="kw2">this</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; animator.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<p>Now for people who are new to OpenGL.  To set up a decent-looking three-dimensional scene (if you don&#8217;t want all three dimensions, don&#8217;t use opengl), you need three things &#8211; the lighting settings, the material settings, and the content (the position of the camera is taken care of in the boilerplate code above &#8211; if you want to more the camera, you can cheat and move the scene itself instead).  The material itself is easiest.  The four main functions are <code>gl.glBegin()</code>, <code>gl.glEnd()</code>, <code>gl.glVertex3d()</code>, and <code>glu.gluSphere</code>.  Use the first three together, to draw lines, and polygons; however, our example only uses spheres.  Draw a sphere with <code>glu.gluSphere(glu.gluNewQuadric(), radius,50,50)</code>.</p>
<p>And now, for your coding pleasure, I present you with a complete code listing for a simple application to show the moon orbiting the earth.  I&#8217;ve set it up so that the viewer rotates about both.</p>
<b>FFScene.java</b>
<div class="geshi java"><ol><li class="li1"><div class="de1"><span class="kw2">package</span> edu.<span class="me1">mbhs</span>.<span class="me1">sclawren</span>.<span class="me1">misc</span>.<span class="me1">funfun</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.glu.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> FFScene <span class="kw2">implements</span> GLEventListener <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw4">double</span> rot=<span class="nu0">0</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> display<span class="br0">&#40;</span>GLAutoDrawable drawable<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; rot+=<span class="nu0">1</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">//rot%=360;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GL gl = drawable.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GLU glu=<span class="kw2">new</span> GLU<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; gl.<span class="me1">glClear</span><span class="br0">&#40;</span>GL.<span class="me1">GL_COLOR_BUFFER_BIT</span> | GL.<span class="me1">GL_DEPTH_BUFFER_BIT</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp;<span class="co1">// Reset The Modelview Matrix</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslatef</span><span class="br0">&#40;</span><span class="nu0">0</span>.0f,<span class="nu0">0</span>.0f,<span class="nu0">-8</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glRotated</span><span class="br0">&#40;</span>rot,<span class="nu0">1.0</span>,<span class="nu0">0.0</span>,<span class="nu0">0.0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslatef</span><span class="br0">&#40;</span><span class="nu0">0</span>.0f,<span class="nu0">0</span>.0f,<span class="nu0">8</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslatef</span><span class="br0">&#40;</span><span class="nu0">0</span>.0f,<span class="nu0">0</span>.0f,<span class="nu0">-8</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// prepare ligthsource</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> ambient<span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="br0">&#123;</span><span class="nu0">0</span>.4f,<span class="nu0">0</span>.4f,<span class="nu0">0</span>.4f,<span class="nu0">1</span>.0f <span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> diffuse<span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="br0">&#123;</span><span class="nu0">1</span>.0f,<span class="nu0">1</span>.0f,<span class="nu0">1</span>.0f,<span class="nu0">1</span>.0f <span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> position<span class="br0">&#91;</span><span class="br0">&#93;</span> = <span class="br0">&#123;</span><span class="nu0">-1</span>.0f,<span class="nu0">1</span>.0f,<span class="nu0">1</span>.0f,<span class="nu0">0</span>.0f <span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLightfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LIGHT0</span>, GL.<span class="me1">GL_AMBIENT</span>, ambient,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLightfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LIGHT0</span>, GL.<span class="me1">GL_DIFFUSE</span>, diffuse,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLightfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LIGHT0</span>, GL.<span class="me1">GL_POSITION</span>, position,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glEnable</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LIGHT0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glEnable</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LIGHTING</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> amb<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.2f,<span class="nu0">0</span>.2f,<span class="nu0">0</span>.4f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> diff<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.2f,<span class="nu0">0</span>.2f,<span class="nu0">1</span>.0f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> spec<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.2f,<span class="nu0">0</span>.8f,<span class="nu0">0</span>.8f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> shine=<span class="nu0">0</span>.1f<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_AMBIENT</span>,amb,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_DIFFUSE</span>,diff,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_SPECULAR</span>,spec,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialf</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_SHININESS</span>,shine<span class="sy0">*</span><span class="nu0">128</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; GLUquadric qd=glu.<span class="me1">gluNewQuadric</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; glu.<span class="me1">gluSphere</span><span class="br0">&#40;</span>qd, <span class="nu0">1</span>.0f,<span class="nu0">100</span>,<span class="nu0">100</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">//now draw the cube</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glRotated</span><span class="br0">&#40;</span>rot<span class="sy0">*</span><span class="nu0">10</span>,<span class="nu0">0.0</span>,<span class="nu0">0.0</span>,<span class="nu0">1.0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslated</span><span class="br0">&#40;</span><span class="nu0">0.0</span>,<span class="nu0">1.6</span>,<span class="nu0">0.0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> amb2<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.3f,<span class="nu0">0</span>.3f,<span class="nu0">0</span>.3f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> diff2<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.4f,<span class="nu0">0</span>.4f,<span class="nu0">0</span>.6f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> spec2<span class="br0">&#91;</span><span class="br0">&#93;</span>=<span class="br0">&#123;</span><span class="nu0">0</span>.02f,<span class="nu0">0</span>.2f,<span class="nu0">0</span>.2f,<span class="nu0">1</span>.0f<span class="br0">&#125;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> shine2=<span class="nu0">0</span>.1f<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_AMBIENT</span>,amb2,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_DIFFUSE</span>,diff2,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialfv</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_SPECULAR</span>,spec2,<span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMaterialf</span><span class="br0">&#40;</span>GL.<span class="me1">GL_FRONT</span>,GL.<span class="me1">GL_SHININESS</span>,shine2<span class="sy0">*</span><span class="nu0">128</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; glu.<span class="me1">gluSphere</span><span class="br0">&#40;</span>qd, <span class="nu0">0</span>.3f,<span class="nu0">50</span>,<span class="nu0">50</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_MATRIX_MODE</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> displayChanged<span class="br0">&#40;</span>GLAutoDrawable arg0, <span class="kw4">boolean</span> arg1, <span class="kw4">boolean</span> arg2<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; display<span class="br0">&#40;</span>arg0<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> init<span class="br0">&#40;</span>GLAutoDrawable glad<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">final</span> GL gl = glad.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_PROJECTION</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_MODELVIEW</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// smooth the drawing</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glShadeModel</span><span class="br0">&#40;</span>GL.<span class="me1">GL_SMOOTH</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// depth sorting</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glEnable</span><span class="br0">&#40;</span>GL.<span class="me1">GL_DEPTH_TEST</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glDepthFunc</span><span class="br0">&#40;</span>GL.<span class="me1">GL_LESS</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">// set background to light gray</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glClearColor</span><span class="br0">&#40;</span><span class="nu0">0</span>.9f, <span class="nu0">0</span>.9f, <span class="nu0">0</span>.9f, <span class="nu0">1</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> reshape<span class="br0">&#40;</span>GLAutoDrawable drawable, <span class="kw4">int</span> x, <span class="kw4">int</span> y, <span class="kw4">int</span> width, <span class="kw4">int</span> height<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">float</span> h = <span class="br0">&#40;</span><span class="kw4">float</span><span class="br0">&#41;</span>height / <span class="br0">&#40;</span><span class="kw4">float</span><span class="br0">&#41;</span>width<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; GL gl = drawable.<span class="me1">getGL</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_PROJECTION</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glFrustum</span><span class="br0">&#40;</span><span class="nu0">-1</span>.0f, <span class="nu0">1</span>.0f, -h, h, <span class="nu0">2</span>.0f, <span class="nu0">60</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glMatrixMode</span><span class="br0">&#40;</span>GL.<span class="me1">GL_MODELVIEW</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glLoadIdentity</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gl.<span class="me1">glTranslatef</span><span class="br0">&#40;</span><span class="nu0">0</span>.0f, <span class="nu0">0</span>.0f, <span class="nu0">-3</span>.0f<span class="br0">&#41;</span><span class="sy0">;</span> &nbsp; &nbsp; &nbsp; &nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<b>FFFrame.java</b>
<div class="geshi java"><ol><li class="li1"><div class="de1"><span class="kw2">package</span> edu.<span class="me1">mbhs</span>.<span class="me1">sclawren</span>.<span class="me1">misc</span>.<span class="me1">funfun</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import java.awt.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.awt.event.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.media.opengl.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import javax.swing.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import com.sun.opengl.util.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> FFFrame <span class="kw2">extends</span> <span class="kw3">JFrame</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw2">static</span> <span class="kw2">final</span> <span class="kw4">long</span> serialVersionUID = -5712445927536229962L<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;GLCanvas glScene<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;FPSAnimator animator<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> FFFrame<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; glScene=<span class="kw2">new</span> GLCanvas<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; FFScene ff=<span class="kw2">new</span> FFScene<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;glScene.<span class="me1">addGLEventListener</span><span class="br0">&#40;</span>ff<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;getContentPane<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">add</span><span class="br0">&#40;</span>glScene, <span class="kw3">BorderLayout</span>.<span class="me1">CENTER</span><span class="br0">&#41;</span><span class="sy0">;</span>setBackground<span class="br0">&#40;</span><span class="kw3">Color</span>.<span class="me1">blue</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;glScene.<span class="me1">addMouseListener</span><span class="br0">&#40;</span><span class="kw2">new</span> <span class="kw3">MouseListener</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw4">void</span> mouseClicked<span class="br0">&#40;</span><span class="kw3">MouseEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">System</span>.<span class="me1">exit</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw4">void</span> mouseEntered<span class="br0">&#40;</span><span class="kw3">MouseEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw4">void</span> mouseExited<span class="br0">&#40;</span><span class="kw3">MouseEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw4">void</span> mousePressed<span class="br0">&#40;</span><span class="kw3">MouseEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">public</span> <span class="kw4">void</span> mouseReleased<span class="br0">&#40;</span><span class="kw3">MouseEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span> </div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;animator = <span class="kw2">new</span> FPSAnimator<span class="br0">&#40;</span>glScene, <span class="nu0">20</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> display<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; setUndecorated<span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">GraphicsEnvironment</span>.<span class="me1">getLocalGraphicsEnvironment</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getDefaultScreenDevice</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">setFullScreenWindow</span><span class="br0">&#40;</span><span class="kw2">this</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; animator.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<p>To show the FFFrame, just call <code>new FFFrame().display()</code>.</p>]]></content:encoded>
			<wfw:commentRss>http://robot.mbhs.edu/wordpress/2009/java-opengl-example-spheres/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Event-Driven Programming in Java</title>
		<link>http://robot.mbhs.edu/wordpress/2009/event-driven-programming-in-java/</link>
		<comments>http://robot.mbhs.edu/wordpress/2009/event-driven-programming-in-java/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 15:58:52 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[event-driven programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[multi-threading]]></category>
		<category><![CDATA[synchronize]]></category>

		<guid isPermaLink="false">http://robot.mbhs.edu/wordpress/?p=240</guid>
		<description><![CDATA[I recently noted that several students in a beginning computer science class at my school had been learning event-driven programming by themselves, without bothering to use google or any textbooks. While I approve of this experimental learning approach in general, in this case, the result was less than good.
The programmers in question wanted to design [...]]]></description>
			<content:encoded><![CDATA[<p>I recently noted that several students in a beginning computer science class at my school had been learning event-driven programming by themselves, without bothering to use google or any textbooks. While I approve of this experimental learning approach in general, in this case, the result was less than good.</p>
<p>The programmers in question wanted to design a system in which, so long as the number of button presses was less than the number of lines in a certain file, pressing the button would retrieve the next line, process it, and print out the result.  They did this as follows (I&#8217;ve made some modifications for readability):</p>
<div class="geshi java"><ol><li class="li1"><div class="de1">button.<span class="me1">addActionListener</span><span class="br0">&#40;</span><span class="kw2">new</span> MyActionListener<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">Scanner s=<span class="kw2">new</span> Scanner<span class="br0">&#40;</span><span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span><span class="st0">&quot;values.txt&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1"><span class="kw1">while</span><span class="br0">&#40;</span>s.<span class="me1">hasNextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">while</span><span class="br0">&#40;</span><span class="sy0">!</span>button_pressed<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; button_pressed=<span class="kw2">false</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; processLine<span class="br0">&#40;</span>s.<span class="me1">nextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">private</span> <span class="kw2">class</span> MyActionListener <span class="kw2">implements</span> <span class="kw3">ActionListener</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> <span class="kw4">void</span> actionPerformed<span class="br0">&#40;</span><span class="kw3">ActionEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; button_pressed=<span class="kw2">true</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<p>From the programmer&#8217;s standpoint, I suppose this actually is the intuitive way to do it.  If the user wasn&#8217;t involved, we would just loop until there were no more lines, but since the user <em>is</em> involved, we have to wait for the user to press the button, hence the while loop.  Nevertheless, this is a Very Bad way to do it.  While in the loop on line 5, we are using 100% CPU, even though all we are doing is waiting.  If we want to do another operation at the same time, we are doomed.</p>
<span id="more-240"></span>
<p>When programming an event-driven system, you have to think from the user&#8217;s standpoint.  And as far as the user is concerned, the mouse click on the button should be the cause of processing of the line.  Hence the term &#8220;event-driven&#8221; programming.  The correct code would be.</p>
<div class="geshi java"><ol><li class="li1"><div class="de1">button.<span class="me1">addActionListener</span><span class="br0">&#40;</span><span class="kw2">new</span> MyActionListener<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">Scanner s=<span class="kw2">new</span> Scanner<span class="br0">&#40;</span><span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span><span class="st0">&quot;values.txt&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">private</span> <span class="kw2">class</span> MyActionListener <span class="kw2">implements</span> <span class="kw3">ActionListener</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> <span class="kw4">void</span> actionPerformed<span class="br0">&#40;</span><span class="kw3">ActionEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>s.<span class="me1">hasNextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; processLine<span class="br0">&#40;</span>s.<span class="me1">nextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="co1">//do some alert, and maybe exit</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<p>These two code snippets are <em>almost</em> functionally the same.  The difference is subtle, but there.</p>
<p>Suppose the function <code>processLine()</code> takes a significant amount of time, like maybe three seconds.  In the first code sample, if the user presses the button again before the first call to the function <code>processLine()</code> has completed, nothing will happen until the call has completed.  In the second version, <code>processLine()</code> will be called immediately, resulting in two instances of <code>processLine()</code> running at the same time.  If they share resources (including the output buffer), then things might not work properly.  The solution is to synchronize them &#8211; something you may have seen if you have done multi-threaded programming.</p>
<div class="geshi java"><ol><li class="li1"><div class="de1">button.<span class="me1">addActionListener</span><span class="br0">&#40;</span><span class="kw2">new</span> MyActionListener<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">Scanner s=<span class="kw2">new</span> Scanner<span class="br0">&#40;</span><span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span><span class="st0">&quot;values.txt&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw2">private</span> <span class="kw2">class</span> MyActionListener <span class="kw2">implements</span> <span class="kw3">ActionListener</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> <span class="kw2">synchronized</span> <span class="kw4">void</span> actionPerformed<span class="br0">&#40;</span><span class="kw3">ActionEvent</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>s.<span class="me1">hasNextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; processLine<span class="br0">&#40;</span>s.<span class="me1">nextLine</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="co1">//do some alert, and maybe exit</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
<p>The first and third versions of the code are functionally the same, but the third one does not use 100% CPU.  Waiting for stuff to happen should never be CPU-intensive &#8211; if it is, you&#8217;re doing something wrong.</p>]]></content:encoded>
			<wfw:commentRss>http://robot.mbhs.edu/wordpress/2009/event-driven-programming-in-java/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java Plugin Architecture with ClassLoader</title>
		<link>http://robot.mbhs.edu/wordpress/2009/java-plugin-architecture-with-classloader/</link>
		<comments>http://robot.mbhs.edu/wordpress/2009/java-plugin-architecture-with-classloader/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 02:19:03 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Scout449]]></category>

		<guid isPermaLink="false">http://robot.mbhs.edu/wordpress/?p=144</guid>
		<description><![CDATA[<p>For a program I was writing (GCenter - a productivity tool - saves you time by minimizing the time it takes to load your games), I found it necessary to create a plugin architecture with Java and <code>ClassLoader</code>.  (I expect Scout449 to eventually use a similar system, although probably with cleaner code.)  My code has several cheap hacks, but remains an effective demonstration of a decent plugin system.</p> 
<p>Java lends itself particularly well to plugin systems, since classes are loaded dynamically anyway. The idea of a plugin system is to modify how Java loads things.  Normally, Java will load your program from the class files in its directory or jar file.  When creating a plugin architecture, you want it to also load classes from different jar files (generally the jar files in a certain directory).  The solution is to create your own version of the <code>ClassLoader</code>.</p>
<p>Most of the code below is just to navigate the jar files.  In the execution of the application, a <code>PluginReader</code> is created for each jar file in the plugin directory.  The <code>read()</code> method is then called (line 39), which first fetches a manifest file named "MANIFEST.GMF" which contains the name the actual plugin class (the class that has information like author's name, as well as functions for starting the plugin running).  This class is then loaded, and the class itself is registered with <code>PluginUtils</code>, so that it shows up as an option on the application screen.  Then, all the other classes are loaded via the same method (but they are not registered), so that they can be used by the plugin.  Finally, <code>copyFiles</code> is called, which copies the entire contents of the jar file to a temporary directory, so that the plugin can fetch graphics and stuff if it wants (using a path conversion method that takes a jar file path and turns it into a temporary directory path).</p>
<p>The real meat is at the very end: line 206 and on.  Here, we define a <code>ClassLoader</code> that takes as an argument to its constructor a <code>JarFile</code>, and can be used to load classes from that JarFile.  But the real beauty of the <code>ClassLoader</code> is not simply that we can load classes from a jar file, its that <em>when those classes then want to load more classes or find more resources, it is still done within the context of the jar file</em>.  Which means that we don't have to be 100% thorough, we just have to get the plugin going - Java will be happy to handle the rest for us.</p>
<p>Creating a class is simple.  We just have to read in a .class file and call the <code>ClassLoader</code>'s <code>defineClass</code> method - in this instance, using our own <code>createClass</code> method as a proxy (just for convenience).</p>]]></description>
			<content:encoded><![CDATA[<p>For a program I was writing (GCenter &#8211; a productivity tool &#8211; saves you time by minimizing the time it takes to load your games), I found it necessary to create a plugin architecture with Java and <code>ClassLoader</code>.  (I expect Scout449 to eventually use a similar system, although probably with cleaner code.)  My code has several cheap hacks, but remains an effective demonstration of a decent plugin system.</p> 
<p>Java lends itself particularly well to plugin systems, since classes are loaded dynamically anyway. The idea of a plugin system is to modify how Java loads things.  Normally, Java will load your program from the class files in its directory or jar file.  When creating a plugin architecture, you want it to also load classes from different jar files (generally the jar files in a certain directory).  The solution is to create your own version of the <code>ClassLoader</code>.</p>
<p>Most of the code below is just to navigate the jar files.  In the execution of the application, a <code>PluginReader</code> is created for each jar file in the plugin directory.  The <code>read()</code> method is then called (line 39), which first fetches a manifest file named &#8220;MANIFEST.GMF&#8221; which contains the name the actual plugin class (the class that has information like author&#8217;s name, as well as functions for starting the plugin running).  This class is then loaded, and the class itself is registered with <code>PluginUtils</code>, so that it shows up as an option on the application screen.  Then, all the other classes are loaded via the same method (but they are not registered), so that they can be used by the plugin.  Finally, <code>copyFiles</code> is called, which copies the entire contents of the jar file to a temporary directory, so that the plugin can fetch graphics and stuff if it wants (using a path conversion method that takes a jar file path and turns it into a temporary directory path).</p>
<p>The real meat is at the very end: line 206 and on.  Here, we define a <code>ClassLoader</code> that takes as an argument to its constructor a <code>JarFile</code>, and can be used to load classes from that JarFile.  But the real beauty of the <code>ClassLoader</code> is not simply that we can load classes from a jar file, its that <em>when those classes then want to load more classes or find more resources, it is still done within the context of the jar file</em>.  Which means that we don&#8217;t have to be 100% thorough, we just have to get the plugin going &#8211; Java will be happy to handle the rest for us.</p>
<p>Creating a class is simple.  We just have to read in a .class file and call the <code>ClassLoader</code>&#8217;s <code>defineClass</code> method &#8211; in this instance, using our own <code>createClass</code> method as a proxy (just for convenience).</p>
<span id="more-144"></span>
<p>The key lines of code are displayed below, followed by the whole file.</p>

<div class="geshi java"><ol start="206"><li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw2">class</span> MyClassLoader2 <span class="kw2">extends</span> <span class="kw3">ClassLoader</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">JarFile</span> jar<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> MyClassLoader2<span class="br0">&#40;</span><span class="kw3">JarFile</span> j<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">super</span><span class="br0">&#40;</span>MyClassLoader2.<span class="kw2">class</span>.<span class="me1">getClassLoader</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;jar=j<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> Class<span class="sy0">&lt;?&gt;</span> createClass<span class="br0">&#40;</span><span class="kw3">String</span> name,<span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> b<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">return</span> defineClass<span class="br0">&#40;</span>name,b,<span class="nu0">0</span>,b.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> Class<span class="sy0">&lt;?&gt;</span> findClass<span class="br0">&#40;</span><span class="kw3">String</span> oname<span class="br0">&#41;</span> <span class="kw2">throws</span> <span class="kw3">ClassNotFoundException</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">String</span> name=oname.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\\</span>.&quot;</span>,<span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span>.<span class="me1">concat</span><span class="br0">&#40;</span><span class="st0">&quot;.class&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>oname<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="kw2">throw</span> <span class="kw2">new</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">else</span> name=oname<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">JarEntry</span> mainClass=<span class="br0">&#40;</span><span class="kw3">JarEntry</span><span class="br0">&#41;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">InputStream</span> stream=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>mainClass<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> bytes=<span class="kw2">new</span> <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;bytes<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#41;</span>stream.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; Class<span class="sy0">&lt;?&gt;</span> c=createClass<span class="br0">&#40;</span>oname,bytes<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> c<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">Exception</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>e <span class="kw2">instanceof</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#41;</span> <span class="kw2">throw</span> <span class="br0">&#40;</span><span class="kw3">ClassNotFoundException</span><span class="br0">&#41;</span>e<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">throw</span> <span class="kw2">new</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> <span class="kw3">URL</span> findResource<span class="br0">&#40;</span><span class="kw3">String</span> name<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">new</span> <span class="kw3">URL</span><span class="br0">&#40;</span><span class="st0">&quot;jar:file:///&quot;</span>+jar.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>+<span class="st0">&quot;!/&quot;</span>+name<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span> <span class="br0">&#40;</span><span class="kw3">MalformedURLException</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">Exception</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li></ol></div>

<div class="geshi java"><ol><li class="li1"><div class="de1"><span class="kw2">package</span> edu.<span class="me1">mbhs</span>.<span class="me1">sclawren</span>.<span class="me1">gcenter</span>.<span class="me1">engine</span>.<span class="me1">plugin</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import java.io.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.net.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.util.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.util.jar.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import java.util.logging.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="co2">import edu.mbhs.sclawren.gcenter.engine.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import edu.mbhs.sclawren.gcenter.gameplugin.*;</span></div></li>
<li class="li1"><div class="de1"><span class="co2">import edu.mbhs.sclawren.gcenter.gameplugin.resources.*;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp;* A reader for a single plugin. &nbsp;Is also used by the program to store the </span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp;* plugin later on, since it neatly encapsulates everything.</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp;* @author Scott Lawrence</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp;*</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp;*/</span></div></li>
<li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> PluginReader <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw2">static</span> Logger l=Logger.<span class="me1">getLogger</span><span class="br0">&#40;</span><span class="st0">&quot;Engine&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw3">File</span> file<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> GPlugin gplugin<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * &lt;p&gt;Creates a plugin reader from a single file. &nbsp;Does not actually</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * read the plugin.&lt;/p&gt;</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @param f the file from which the plugin will be read</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> PluginReader<span class="br0">&#40;</span><span class="kw3">File</span> f<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; l.<span class="me1">finest</span><span class="br0">&#40;</span><span class="st0">&quot;PluginReader created for &quot;</span>+f.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; file=f<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * Reads the plugin</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw4">void</span> read<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; l.<span class="me1">finest</span><span class="br0">&#40;</span><span class="st0">&quot;Reading plugin: &quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">JarFile</span> jar=<span class="kw2">new</span> <span class="kw3">JarFile</span><span class="br0">&#40;</span>file<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">JarEntry</span> manifest=<span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="kw3">JarEntry</span> entry:<span class="kw3">Collections</span>.<span class="me1">list</span><span class="br0">&#40;</span>jar.<span class="me1">entries</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">equals</span><span class="br0">&#40;</span><span class="st0">&quot;MANIFEST.GMF&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> manifest=entry<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>manifest==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; l.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Plugin could not be read (no manifest): &quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;Scanner input=<span class="kw2">new</span> Scanner<span class="br0">&#40;</span>jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>manifest<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; input.<span class="me1">skip</span><span class="br0">&#40;</span><span class="st0">&quot;Main-Class: &quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">NoSuchElementException</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; l.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Plugin could not be read (invalid manifest): &quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">String</span> main=input.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;main=main.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\\</span><span class="es0">\\</span>&quot;</span>,<span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;main=main.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\\</span>.&quot;</span>,<span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;main+=<span class="st0">&quot;.class&quot;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">JarEntry</span> mainClass=jar.<span class="me1">getJarEntry</span><span class="br0">&#40;</span>main<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>mainClass==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; l.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Plugin could not be read (main class not found): &quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">InputStream</span> stream=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>mainClass<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> bytes=<span class="kw2">new</span> <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; bytes<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#41;</span>stream.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;MyClassLoader2 myClassLoader=<span class="kw2">new</span> MyClassLoader2<span class="br0">&#40;</span>jar<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;Class<span class="sy0">&lt;?&gt;</span> c=</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; myClassLoader.<span class="me1">loadClass</span><span class="br0">&#40;</span>main.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;/&quot;</span>,<span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span>.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;.class&quot;</span>,<span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">//myClassLoader.createClass(main.replaceAll(&quot;/&quot;,&quot;.&quot;).replaceAll(&quot;.class&quot;,&quot;&quot;),bytes);</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;gplugin=<span class="br0">&#40;</span>GPlugin<span class="br0">&#41;</span>c.<span class="me1">newInstance</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="co1">//now read in all of the other classes</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="kw3">JarEntry</span> entry:<span class="kw3">Collections</span>.<span class="me1">list</span><span class="br0">&#40;</span>jar.<span class="me1">entries</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">endsWith</span><span class="br0">&#40;</span><span class="st0">&quot;.class&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">equals</span><span class="br0">&#40;</span>main<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw2">continue</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">contains</span><span class="br0">&#40;</span><span class="st0">&quot;$&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw2">continue</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="co1">//load this class</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;l.<span class="me1">finest</span><span class="br0">&#40;</span><span class="st0">&quot;Loading class: &quot;</span>+entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;stream=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>entry<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;bytes=<span class="kw2">new</span> <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>entry.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>entry.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; bytes<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#41;</span>stream.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; myClassLoader.<span class="me1">createClass</span><span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;/&quot;</span>,<span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span>.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;.class&quot;</span>,<span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>,bytes<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">LinkageError</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; l.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Linkage error occured &#8211; possible duplicate class names &quot;</span>+</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;when loading &quot;</span>+entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>+<span class="st0">&quot; in &quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw2">throw</span> e<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="co1">//its some other sort of file, so we&#39;ll deal with it later.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;copyFiles<span class="br0">&#40;</span>jar<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="co1">//we can&#39;t close the jar file, because some classes might want to read from</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="co1">//it (for ResourceBundles, etc&#8230;)</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">Exception</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;l.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;An unknown error occured: &quot;</span>+e.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">return</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; l.<span class="me1">fine</span><span class="br0">&#40;</span><span class="st0">&quot;Plugin read: &quot;</span>+gplugin.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>+<span class="st0">&quot; (&quot;</span>+file.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>+<span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; gplugin.<span class="me1">initialize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; EngineUtils.<span class="me1">registerPlugin</span><span class="br0">&#40;</span><span class="kw2">this</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * Copy an entry in a {@link JarFile} to the current directory.</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @param jar the {@link JarFile} of the entry</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @param entry the file that will be copied</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @deprecated does not appropriately copy the resources&#8230;and nearly</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * deleted my development workspace. &nbsp;Use {@link #copyFiles(JarFile)}</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * instead.</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;@SuppressWarnings<span class="br0">&#40;</span><span class="st0">&quot;unused&quot;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw4">void</span> copyEntry<span class="br0">&#40;</span><span class="kw3">JarFile</span> jar,<span class="kw3">JarEntry</span> entry<span class="br0">&#41;</span> <span class="kw2">throws</span> <span class="kw3">IOException</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">InputStream</span> stream=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>entry<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> bytes=<span class="kw2">new</span> <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>entry.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>entry.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;bytes<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#41;</span>stream.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">File</span> f=<span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>f.<span class="me1">getParentFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">!</span>=<span class="kw2">null</span><span class="br0">&#41;</span> f.<span class="me1">getParentFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">mkdirs</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>f.<span class="me1">exists</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> f.<span class="me1">delete</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; f.<span class="me1">createNewFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">FileOutputStream</span> output=<span class="kw2">new</span> <span class="kw3">FileOutputStream</span><span class="br0">&#40;</span>f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; output.<span class="me1">write</span><span class="br0">&#40;</span>bytes<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; output.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; f.<span class="me1">deleteOnExit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp;<span class="co1">//so that we don&#39;t leave any residue</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * &lt;p&gt;Copies files from the specified jar file to a temporary directory specified</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * by {@link GPluginResource#getTempPath(GPlugin)}, and then schedules them for</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * deletion upon application exit.&lt;/p&gt;</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @param jar</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @throws IOException if problems are encountered while copying files from the</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * jar to the temporary directory.</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw4">void</span> copyFiles<span class="br0">&#40;</span><span class="kw3">JarFile</span> jar<span class="br0">&#41;</span> <span class="kw2">throws</span> <span class="kw3">IOException</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; l.<span class="me1">finer</span><span class="br0">&#40;</span><span class="st0">&quot;Copying files from &quot;</span>+jar.<span class="me1">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="co1">//create the relevant temporary directory</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">File</span> tmp=<span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span>GPluginResource.<span class="me1">getTempPath</span><span class="br0">&#40;</span>gplugin<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="sy0">!</span>tmp.<span class="me1">mkdir</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>tmp.<span class="me1">exists</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw2">throw</span> <span class="kw2">new</span> <span class="kw3">IOException</span><span class="br0">&#40;</span><span class="st0">&quot;Could not create temporary directory&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; tmp.<span class="me1">deleteOnExit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="kw3">JarEntry</span> entry:<span class="kw3">Collections</span>.<span class="me1">list</span><span class="br0">&#40;</span>jar.<span class="me1">entries</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;l.<span class="me1">finest</span><span class="br0">&#40;</span><span class="st0">&quot;Copying entry &quot;</span>+entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">File</span> f=<span class="kw2">new</span> <span class="kw3">File</span><span class="br0">&#40;</span>GPluginResource.<span class="me1">convertPath</span><span class="br0">&#40;</span>entry.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,gplugin<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="co1">//check parents</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">File</span> p=f.<span class="me1">getParentFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;Stack<span class="sy0">&lt;</span>File<span class="sy0">&gt;</span> files=<span class="kw2">new</span> Stack<span class="sy0">&lt;</span>File<span class="sy0">&gt;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">while</span><span class="br0">&#40;</span><span class="sy0">!</span>p.<span class="me1">exists</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; files.<span class="me1">push</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; p=p.<span class="me1">getParentFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">while</span><span class="br0">&#40;</span><span class="sy0">!</span>files.<span class="me1">empty</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; files.<span class="me1">peek</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">mkdir</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; files.<span class="me1">pop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">deleteOnExit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;f.<span class="me1">createNewFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">FileOutputStream</span> output=<span class="kw2">new</span> <span class="kw3">FileOutputStream</span><span class="br0">&#40;</span>f<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">InputStream</span> input=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>entry<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>entry.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> output.<span class="me1">write</span><span class="br0">&#40;</span>input.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;f.<span class="me1">deleteOnExit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * </span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @return a {@link GPlugin} object describing the plugin</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> GPlugin getPluginInfo<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">return</span> gplugin<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * &lt;p&gt;Not an actual class loader, just a cheat that enables {@link PluginReader}</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * to access protected {@link ClassLoader} methods.&lt;/p&gt;</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @author Scott Lawrence</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @deprecated use {@link MyClassLoader2}</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; *</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">class</span> MyClassLoader <span class="kw2">extends</span> <span class="kw3">ClassLoader</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> Class<span class="sy0">&lt;?&gt;</span> createClass<span class="br0">&#40;</span><span class="kw3">String</span> name,<span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> b<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">return</span> defineClass<span class="br0">&#40;</span>name,b,<span class="nu0">0</span>,b.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="coMULTI">/**</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * &lt;p&gt;An actual class loader, that is used to load plugins.&lt;/p&gt;</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; * @author Scott Lawrence</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; *</span></div></li>
<li class="li1"><div class="de1"><span class="coMULTI">&nbsp; */</span></div></li>
<li class="li1"><div class="de1">&nbsp;<span class="kw2">public</span> <span class="kw2">class</span> MyClassLoader2 <span class="kw2">extends</span> <span class="kw3">ClassLoader</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw3">JarFile</span> jar<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> MyClassLoader2<span class="br0">&#40;</span><span class="kw3">JarFile</span> j<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">super</span><span class="br0">&#40;</span>MyClassLoader2.<span class="kw2">class</span>.<span class="me1">getClassLoader</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;jar=j<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> Class<span class="sy0">&lt;?&gt;</span> createClass<span class="br0">&#40;</span><span class="kw3">String</span> name,<span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> b<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">return</span> defineClass<span class="br0">&#40;</span>name,b,<span class="nu0">0</span>,b.<span class="me1">length</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> Class<span class="sy0">&lt;?&gt;</span> findClass<span class="br0">&#40;</span><span class="kw3">String</span> oname<span class="br0">&#41;</span> <span class="kw2">throws</span> <span class="kw3">ClassNotFoundException</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw3">String</span> name=oname.<span class="me1">replaceAll</span><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\\</span>.&quot;</span>,<span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span>.<span class="me1">concat</span><span class="br0">&#40;</span><span class="st0">&quot;.class&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>oname<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="kw2">throw</span> <span class="kw2">new</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">else</span> name=oname<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">JarEntry</span> mainClass=<span class="br0">&#40;</span><span class="kw3">JarEntry</span><span class="br0">&#41;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw3">InputStream</span> stream=jar.<span class="me1">getInputStream</span><span class="br0">&#40;</span>mainClass<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#93;</span> bytes=<span class="kw2">new</span> <span class="kw4">byte</span><span class="br0">&#91;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="br0">&#41;</span><span class="br0">&#40;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="kw4">int</span> i=<span class="nu0">0</span><span class="sy0">;</span>i<span class="sy0">&lt;</span>mainClass.<span class="me1">getSize</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>i++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;bytes<span class="br0">&#91;</span>i<span class="br0">&#93;</span>=<span class="br0">&#40;</span><span class="kw4">byte</span><span class="br0">&#41;</span>stream.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; Class<span class="sy0">&lt;?&gt;</span> c=createClass<span class="br0">&#40;</span>oname,bytes<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> c<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">Exception</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>e <span class="kw2">instanceof</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#41;</span> <span class="kw2">throw</span> <span class="br0">&#40;</span><span class="kw3">ClassNotFoundException</span><span class="br0">&#41;</span>e<span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">throw</span> <span class="kw2">new</span> <span class="kw3">ClassNotFoundException</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw2">public</span> <span class="kw3">URL</span> findResource<span class="br0">&#40;</span><span class="kw3">String</span> name<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw1">if</span><span class="br0">&#40;</span>jar.<span class="me1">getEntry</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span>==<span class="kw2">null</span><span class="br0">&#41;</span> <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">try</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">new</span> <span class="kw3">URL</span><span class="br0">&#40;</span><span class="st0">&quot;jar:file:///&quot;</span>+jar.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>+<span class="st0">&quot;!/&quot;</span>+name<span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span> <span class="br0">&#40;</span><span class="kw3">MalformedURLException</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span> <span class="kw2">catch</span><span class="br0">&#40;</span><span class="kw3">Exception</span> e<span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; e.<span class="me1">printStackTrace</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">return</span> <span class="kw2">null</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp; <span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp;<span class="br0">&#125;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>
]]></content:encoded>
			<wfw:commentRss>http://robot.mbhs.edu/wordpress/2009/java-plugin-architecture-with-classloader/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
