<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Craig Castelaz&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/" />
<modified>2008-01-02T17:42:16Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/castelaz/21</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2004, castelaz</copyright>
<entry>
<title>Noted Cocoa Programmer Contemplates Switch to Java</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/12/noted_cocoa_pro.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-12-17T04:50:57Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.1861</id>
<created>2004-12-17T04:50:57Z</created>
<summary type="text/plain">Cocoa isn&apos;t the only beverage for the holidays.  Java can also really hit the spot.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img alt="Santa.jpg" src="http://weblogs.java.net/blog/castelaz/archive/Santa.jpg" width="503" height="366" />
<p>
North Pole - Claus, Inc. has announced they are exploring the cross-platform possibilities of Java.  Santa, founder and CEO of Claus, Inc. was an early adopter of Apple computers beginning with VisiCalc on an Apple II.  "It's been a natural progression from those early days to now", says Santa.  "While it took tens of thousands of diskettes to hold the first Naughty-and-Nice List, and processing was none too speedy because of a 64K memory limitation, we've always enjoyed using and programming Apple computers."
</p>
<p>
"Originally, we were primarily a Basic shop, but as the demands increased, we moved into C. From there, Cocoa was the next step in our development efforts", Santa's Chief Scientist, G. Nome says with a grin, using his fingers to motion quotation marks around the words "next step".  When asked about this stranger mannerism, Nome suggested everyone should return to their respective "jobs", and walked away laughing.
</p>
<p>
Contrary to popular understanding, Santa's workshop is state-of-the-art.  In fact, it is the recent adoption of wireless handhelds on the shop floor that has precipitated the interest in Java.  Santa's web-presence has long been outsourced to a number of externally hosted sites, so Java was not a potentially big player until now.  "A JVM is available for nearly every device we have in our production facility", stated Santa.  "The big hurdle is gaining the acceptance of our employees.  Wireless is nice, but we do know a thing or two about mass production without it" Santa noted with evident pride.
</p>
<p>
The only cloud that darkened the otherwise illuminating visit occurred when the topic of Java 5 and Mac OS X came up.  Santa's brows furrowed, and he reached for a rather imposing PDA.  It was difficult to see clearly, but it appears he placed coal icons next to several names.
</p>
<p>
Cocoa will continue to play an important role according to Santa.  It  is clearly his personal favorite.  However, he concedes that "Java has its place" and that he isn't "afraid to indulge so to speak".  When asked about alternatives, Santa reiterated his long time affinity to Apple, and that Apple believes Cocoa and Java to be the preferred tools for serious development.
</p>
<p>
Java will be slowly rolled into place.  An important production scheduling application is already available, but its audience is limited to line supervisors.  Depending upon the further acceptance of several key Java-based applications, the shop floor could ultimately become a Java only environment.  IT staff is continuing to monitor the situation as each new piece is rolled out.  They feel confident they will be able to reach a firm decision within a year.
</p>
<p>
It is hoped that future opportunities to report on progress will be made.  The cookies were delicious.
</p>]]>

</content>
</entry>
<entry>
<title>Help maximize screen space with a small UI trick</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/10/ui_trick.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-10-20T03:32:34Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.1656</id>
<created>2004-10-20T03:32:34Z</created>
<summary type="text/plain">A dropdown combobox is an extremely useful control, but its associated  button isn&apos;t really needed until the control has focus.  A small UI trick can help you maximize precious screen space by hiding the dropdown button until it&apos;s needed.  You can size the combobox control to show all of the selected item text without wasting space on the button.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img alt="Janus2.JPG" src="http://weblogs.java.net/blog/castelaz/archive/Janus2.JPG" width="569" height="404" />
<p>
Way back in the primordial ooze stage of our new product, it was decided that we needed a custom control rather than use the standard combobox to handle dropdown lists.  So, instead of using a JComboBox, we created our own LookupField control that combined a JTextField with a JButton to simulate the more traditional component.  There were several reasons for this decision.  Two of the more compelling ones had to do with the ability to control the dropdown button.  First, it was felt that the standard button on the JComboBox was too wide.  We could easily set a narrower width for the button in our custom control.  Second, we could completely hide the custom controlâ€™s dropdown button whenever we desired.  One of the key features of the product is that users can design their own forms.  Frequently, screen space on these forms becomes extremely limited.  However, if the user sizes the custom control correctly, they can see the entire text of the item they selected from the dropdown list whenever focus is off the custom control because we hide the dropdown button.   The button only becomes visible when the LookupField control gains focus.  In other words, the full text is only hidden when the user is on the field, most likely because they wish to set or change the controlâ€™s value from the dropdown list.  Since the user doesnâ€™t have to account for the extra space of the dropdown button when designing their forms, they can maximize the available screen space.
</p>
<p>
The LookupField served us well for quite some time, but as we migrated to other platforms, and as the look-and-feel of Windows continued to evolve, the custom component began to stick out like the proverbial sore thumb.  After collecting samples of what the standard combobox looked like on several target platforms, it was decided that we couldnâ€™t realistically make the LookupField match all them, and that we needed to use the JComboBox.  Of course, that meant we would lose our control of the dropdown button.  However, as cool as the ability to hide the button was, it wasnâ€™t felt to be critical, and we got the OK to replace the LookupField with the JComboBox control.
</p>
<p>
Now, many of you are going to be able to guess the rest of this story.  Development and Testing were fine with the substitution, but Support and Sales nearly stroked.  Everyone agreed that the JComboBox looked way better, but Sales and Support were adamant that hiding the dropdown button was extremely important.  Fortunately, this story has a happy ending.  After a fair amount time fooling around in the debugger, and writing small experimental snippets of code, we were able to hide the dropdown button on a JComboBox. 
</p>
<p>
As you can see in the example below, Field 2 is somewhat limited in space.  However, the control is able to display the full text of the item selected from the dropdown list since the button associated with the combobox is not visible.
</p>
<img alt="comboboxunfocued.JPG" src="http://weblogs.java.net/blog/castelaz/archive/comboboxunfocued.JPG" width="450" height="70" />
<p>
Once Field 2 has focus, the dropdown button becomes visible, and the   selection list is just a click away.  Note, Field 2 did not increase in size to accommodate the button.
</p>
<img alt="comboboxfocused.JPG" src="http://weblogs.java.net/blog/castelaz/archive/comboboxfocused.JPG" width="450" height="70" />
<p>
Finally, once the user has made their selection, and moved to another field, the dropdown button disappears, once again revealing the full text of the item selected from the dropdown list.
</p>
<img alt="comboboxnewvalue.JPG" src="http://weblogs.java.net/blog/castelaz/archive/comboboxnewvalue.JPG" width="450" height="70" />
<p>
Like our custom LookupField control, the JComboBox is actually made up of several separate controls.  While I havenâ€™t confirmed it across all platforms and look-and-feels, the JComboBox appears to have three underlying components: a rendering pane, a button, and a text field if the combobox has been set to editable.  Our small UI trick involves adjusting the widths of the underlying button and text field   during the control's focus events.  The initialization code in the over-ridden paint method records the original sizes for the button and text field, and then adjusts the widths of the two underlying controls so that the combobox does not have a visible dropdown button when the screen is first painted.  In other words, the button doesn't appear until the control gains focus.  Usage of the custom control isn't any different than that of a standard JComboBox as shown in the QuickTest code.  The setting of the preferred height and width in the QuickTest is to simulate a "tight squeeze" on one of the fields.
</p>
<pre>
//CustomComboBox.java
import javax.swing.*;
import java.awt.*;

public class CustomComboBox extends JComboBox  implements FocusListener {

	private boolean initialization;
	private int textFieldWidth;
	private int textFieldHeight;
	private int buttonWidth;
	private int buttonHeight;
	private Component tf;
	private Component bt;

	public CustomComboBox() {
		super();
		initialization = true;
		setEditable(true);
		bt = getComponent(0);
		tf = getComponent(2);
		tf.addFocusListener(this);
	}

	 public void paint(Graphics g){
	 	super.paint(g);
	 	if (initialization) {
			textFieldWidth = tf.getWidth();
			textFieldHeight = tf.getHeight();
			buttonWidth = bt.getWidth();
			buttonHeight = bt.getHeight();
			bt.setSize(0, 0);
			tf.setSize(textFieldWidth + buttonWidth, textFieldHeight);
	 		initialization = false;
	 	}
	 }

	public void focusGained(FocusEvent e) {
		bt.setSize(buttonWidth, buttonHeight);
		tf.setSize(textFieldWidth, textFieldHeight);
	}

	public void focusLost(FocusEvent e) {
		bt.setSize(0, 0);
		tf.setSize(textFieldWidth + buttonWidth, textFieldHeight);
	}
}

// QuickTest.java
import javax.swing.*;
import java.awt.*;

public class QuickTest extends JFrame {

	public QuickTest(String title) {
		super(title);
		setSize(450, 75);
		Container pane = getContentPane();
		pane.setLayout(new FlowLayout());
		JLabel label1 = new JLabel("Field1");
		pane.add(label1);
		JTextField tf1 = new JTextField(10);
		pane.add(tf1);
		JLabel label2 = new JLabel("Field2");
		pane.add(label2);
		CustomComboBox ccb = new CustomComboBox();
		ccb.setPreferredSize(new Dimension(50, ccb.getPreferredSize().height));
		ccb.addItem("ABCDE");
		ccb.addItem("EDCBA");
		pane.add(ccb);
		JLabel label3 = new JLabel("Field3");
		pane.add(label3);
		JTextField tf2 = new JTextField(10);
		pane.add(tf2);
		show();
	}

	public static void main(String[] args) {
		QuickTest qt = new QuickTest("QuickTest");
	}
}
</pre>
<p>
As far as UI tricks go, this one is pretty small potatoes.  On the other hand, it has redeemed Development in the eyes of Sales and Support, while preserving a nice feature for the users.
</p>
<p>
P.S.  In case you're wondering, the opening illustration started with a vague intention of showing the somewhat pliable nature of most requirements.  Obviously, it missed the mark.  Then again, I was pretty happy with it on its own terms, and it cracked up a friend, so I decided to go with it.
</p>]]>

</content>
</entry>
<entry>
<title>Pair programming:  Everyone&apos;s favorite argument</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/09/pair_programmin.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-09-17T11:42:48Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.616</id>
<created>2004-09-17T11:42:48Z</created>
<summary type="text/plain">Pair programming may be the most controversial part of extreme programming.   If you have any doubt, start a conversation on extreme programming, and see where it ends up.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/6793/PairProgramming.JPG"  width="550" height="280">
<p>
I don&#146;t know how it is for you, but nearly every conversation I&#146;ve ever had about extreme programming eventually works its way to pair programming, which pretty much kills the dialog part of the conversation.  Pair programming is apparently best discussed in monologue format.  For most of the developers I&#146;ve listened to, it is &#147;The&#148; extreme in extreme programming.  It is either the single greatest advance in Western Civilization since the windowed envelop, or it is the spawn of the Netherworld.
</p>
<p>
Briefly, Pair Programming is what it sounds like, two programmers working together on the same computer.  One is the pilot who does the actual coding.  The other is the navigator who serves as both guide and companion.  The programmers collaborate during the development session.  They occasionally switch roles, so no one gets to monopolize the process.   Its advocates claim pair programming results in higher quality code and increased programmer confidence.  In addition, some experts believe these gains can be achieved with little or loss in productivity, while others go further, and hold that the pairs are substantially more productive than a single programmer working alone.
</p>
<p>
There have been a number of studies examining these claims.  The current issue of <i>IEEE Software</i> has the latest, &#147;A Field Study of Developer Pairs:  Productivity Impacts and Implications&#148;.  The article is a reexamination of data collective during a previous study conducted by the authors.  In the prior study, the researchers found that &#147;&#133;teams are more productive when their members work independently.&#148;  These findings where published just as agile development techniques with their promises of higher quality and increased productivity were gaining attention and serious study.   Several subsequently published papers substantiated pair programming&#146;s claims, hence the desire to reexamine the data.
</p>
<p>
In the new study, the authors have to resort to a notion of concurrency.  Since the data was originally collected prior to general knowledge of pair programming, it does not record when programmers actually worked together as a pair.  However, the researchers could determine when developers worked on the same module on the same day.  They called this concurrency, &#147;collaboration potential&#148;.  Although the authors recognize the measure doesn&#146;t directly reflect pair programming, they argue concurrency is &#147;&#133;a necessary precursor, positively correlated with collaboration&#133;.&#148;  In other words, it&#146;s the closest measure of pair programming the data will yield.
</p>
<p>
As to the findings, the researchers report that low-concurrency pairs (those working most independently of one another) were four times more productive than the potentially more collaborative high-concurrency pairs.  That is, the reexamination of the existing data does not substantiate the productivity claims of the other studies.  The authors then go onto propose that the difference might lie with the pair programming protocol itself, i.e. the pilot/navigator roles, and the switching between them that occurs during the development session.  
</p>
<p>
Perhaps there is something within the pair programming protocol that would account for the productivity gains reported in the other studies mentioned by the authors.  Then again, the difference may lie within the environments examined by the different researchers.  One of the earlier studies looked into the productivity of experienced developers who participated in a short 45-minute pair programming exercise, while the other concerned itself with undergraduate Computer Science students who were paired during a semester.  This latest study, however, was based upon data collected during a port of a legacy system which involved 3000 screens and a million lines of code.  Without criticizing the earlier studies, you can still ask how well they translate to the &#147;real world&#148;.
</p>
<p>
So, the controversy remains unresolved.  There are indeed studies that back up the claims of pair programming&#146;s proponents, especially in terms of higher code quality and programmer satisfaction/confidence.  However, the jury is still out on the cost in productivity.   It looks like conversations about extreme programming will continue to devolve into monologues.
</p>
<br>
___________________
<br>
&#147;A Field Study of Developer Pairs:  Productivity Impacts and Implications&#148;, Allen Parrish, Randy Smith, David Hale, and Joanne Hale, IEEE Software, September/October 2004.
<br><br>
&#147;The Case for Collaborative Programming&#148;, John T. Nosek, Communications of the ACM, March 1998/Vol 41. No. 3.
<br><br>
&#147;Building Pair Programming Knowledge through a Family of Experiments&#148;, Laurie Williams, Charlie McDowell, Nachiappan Nagappan, Julian Fernald, and Linda Werner,
Proceedings of the 2003 International Symposium on Empirical Software Engineering.



]]>

</content>
</entry>
<entry>
<title>Ambiguity</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/08/ambiguity.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-09-01T05:13:53Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.1026</id>
<created>2004-09-01T05:13:53Z</created>
<summary type="text/plain">As developers, we frequently concentrate on resolving misunderstandings between users and ourselves.  So much so, we tend to forget that ambiguities can exist between programmers. Standard practices and Java idioms can go a long way in keeping this problem at bay. Patterns and practices are more than ways to implement solutions. They are also an important way for programmers to convey intent.
</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/6495/Squash2.JPG"  width="550" height="280">
<p>
I believe nearly every developer eventually creates their own metaphor for programming.  Some are rather tame, such as &#147;building bridges between users and systems&#148;.  Others can be quite aggressive.  One of my coworkers will often say he&#146;s spent his day &#147;mangling bits&#148; when things have not gone particularly well.  As for me, I frequently picture myself with a large sledgehammer, squashing ambiguities.  The gap between users and their systems isn&#146;t so much bridged, as it is filled with the remains of ambiguities laid to rest.
</p>
<p>
Like a lot of programmers, I work hard to resolve misunderstandings between what is desired and what is delivered.  In my opinion, it&#146;s the hardest part of the job.  At the same time, I&#146;m thankful for the standard practices and idioms commonly found throughout the Java community.  I wish I could say that the wonderful source level comments we write one another dispel all questions about intent, but the reality is that the idioms are sometimes our only guide to what the code was meant to do.   This is especially true in terms of the public interface of a class or component.   Even the best JavaDocs in the world will not solve the problems associated with a sloppy and contrary mix of common patterns and practices in a public interface.  Ambiguities between developer and user are bad enough.  It becomes extremely frustrating when they exist between programmers.
</p>
<p>
For instance, I recently came across a class that I couldn&#146;t decide if it was a bean gone bad, or a singleton with an split-personality. I&#146;ve changed the actual implementation to shield the guilty, but the sample below retains much of original class' flavor.
<pre>
public class Foobar  {
 
	public static String attribute1;
	public String attribute2;
        public String attribute3;
	private static Fooobar instance;

	private Foobar() {
	}

	public static getInstance() {
		if (instance == null) {
			instance = new Foobar();
		}
		return instance;
	}

	public static String getAttribute1() {
		return attribute1;
	}

	public static void setAttribute1(String attribute) {
		attribute1 = attribute;
                notifyObservers();
	}

	public static viod setAttribute1NoNotify(String attribute) {
		attribute1 = attribute1;
        }

        public String getAttribute2() {
               return this.attribute2;
        }

        public void setAttribute2(String attribute) {
                this.attribute2 = attribute2;
       }

       public String getAttribute3() {
                return this.attribute3;
       }
}
</pre>
Now, I'm not about to critique the entire class, but even a quick glance shows there's something not quite right with it. The class begins by looking like a singleton with a private constructor and a <code>getInstance</code> method to control the single instance of the class. However, nearly all the other methods of the class are marked public static which makes the <code>getInstance</code> method unnecessary. Furthermore, the <code>public static</code> methods are mostly getters and setters for publicly available attributes which can be accessed from outside the getters and setters. Then, there is the problem of mixing bean-like behaviour with public getters and setters within the singleton. There may be a need for a singleton bean, but then you wouldn't mark the attributes public, nor would you make them instance rather than class variables. Even the experienced developers that I asked to review the code were hard-pressed to know what to make of the class. Is it a bean, a singleton, a bean-gleton? Finally, when you consider the class in the context of a large application, and the fact that the original is both much larger and more complex that the sample shown, you begin to realize that you have just meet the boss ambiguity for this level of the development game. 
</p>
<p>
Standard practices, idioms, and programming conventions are important in that they help to minimize the number of ambiguities that exist between developers.   Although we can argue endlessly what the conventions should be, our lives as programmers would be a lot tougher without them.
</p>

]]>

</content>
</entry>
<entry>
<title>The best laid plans</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/08/the_best_laid_p.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-08-10T15:47:00Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.712</id>
<created>2004-08-10T15:47:00Z</created>
<summary type="text/plain">You&apos;ve done the research.  You&apos;ve reviewed the specs.  The technology appears to fit  your needs like a glove.  Then, you find it doesn&apos;t work as specified, or it exhibits weird and contrary behavior.  The project goes poof, and you find yourself back at square one.  Perhaps it would have been better to let the mice do the planning.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/6260/SmBestLaidPlans.JPG"  width="550" height="280">
<p>
I recently started a new assignment at work to improve field validation in our primary Swing application.  Like many older GUI based applications, our product relies heavily upon the lost focus event to trigger field validation.  In other words, we verify the value of a component, such as a JTextField, inside its lost focus event.  The problem, as you might guess, is that the verfication occurs too late.  We've already lost focus. While it is easy enough to request that focus return to the offending component if it contains invalid data, the new focus owner may be unable to relinquish it for some reason.  In addition, lost focus events will frequently cascade which makes managing the validation process difficult.  For instance, there may be times when we need to ignore validation errors.  The best example of this is the Cancel button.  Since we&#146;re about to throw away all the changes the user made, it is safe to disregard any validation errors.  Correctly turning on and off the validation flag can become a real challenge, especially in a blizzard of lost focus events.  
</p>
<p>
As I investigated alternatives, I quickly came upon the <code>InputVerifier</code> class.  The basic idea behind the class is to validate the component before relinquishing focus.  If the component is valid, then focus may move.  If it isn't, then focus remains on the invalid component.  Not only is the basic idea quite simple, but using the class is extremely easy.  For each type of validation you wish to perform, you extend the <code>InputVerifier</code> class and implement its <code>verify()</code> method.  Then, create an instance of the validation subclass and register it with the component(s) you wish to validate using the <code>setInputVerifier</code> method.  The <code>verify()</code> method is automatically called as needed.  There is even a way to suppress validation when desired, as in the case of the Cancel button.  I was very pleased with finding the class, and it looked like this was the way to go.  However, as I was all set to proceed, a co-worker told me about some bug reports she had found about the class.
</p>
<p>
Without  belaboring the point, <code>InputVerifier</code> has some problems.  A good summary can be found at <a href="http://www.mycgiserver.com/~Kleopatra/swing/button/buttonverify.html ">Make Buttons Respect InputVerifier</a>.  In addition to describing the problem and linking to the specific Java bug report  <a href="http://developer.java.sun.com/developer/bugParade/bugs/4533820.html">#4533820</a>, the author provides a solution.  Unfortunately, the solution involves extending the Metal Look and Feel, and a future requirement for our product is to allow users to select from several Look and Feels.  Extending all of them isn't practical.
</p>
<p>
Although I couldn't use the solution directly, it did give me another idea.  Basically, the problem is that the button gets the "click" before it calls the other component's <code>verify()</code> method.   I recalled Joshua Marinacci's <a href="http://weblogs.java.net/pub/wlg/537">Swing Hack 4</a> and thought about using the GlassPane to monitor "clicks" in terms of mouse events. By determining the current and target components within the mouse event handler, I can assure that the <code>verify()</code> method is called before focus is shifted.  In the case where the current component is not verified, the MouseEvent is simply eaten by the GlassPane.  In most all other cases, the MouseEvent is redirected to the target component.   Essentially, the idea is to insure that the <code>verify()</code> method is always called before any focus event is fired.  Standard keyboard focus traversal appears to handle verify correctly on its own, and the GlassPane does not need to listen for keyboard events. 
</p>
<p>
I already know that this technique does not work with JInternalFrames, which maintain their own GlassPane components.  In addition,  I have not tested either default button processing or mnemonic traversal.  While the solution may not address everyone's needs, it does appear to work in plain vanilla JFrames and JDialogs.
</p>
<pre>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GlassPaneDemo extends JComponent implements MouseListener {

    Container contentPane;

    public GlassPaneDemo(Container contentPane) {
	addMouseListener(this);
	this.contentPane = contentPane;
    }
	
    public void mousePressed(MouseEvent me) {
	redispatchMouseEvent(me, false);
    }
	
    public void mouseReleased(MouseEvent me) {
	//buttons appear depressed until they receive mouse release
	redispatchMouseEvent(me, false);
    }
	
    public void mouseClicked(MouseEvent me) {
    }
	
    public void mouseEntered(MouseEvent me) {
    }
	
    public void mouseExited(MouseEvent me) {
    }
	
    private void redispatchMouseEvent(MouseEvent me, boolean repaint) {
	Point containerPoint = SwingUtilities.convertPoint(this, me.getPoint(), contentPane);
	JComponent targetComponent = 
            (JComponent)SwingUtilities.getDeepestComponentAt(contentPane, containerPoint.x, containerPoint.y);
	if (targetComponent == null) {
	    return;
	}
	if (targetComponent.isFocusOwner()) {
	    redispatchEvent(targetComponent, me);
	    return;
	}

	else {
	    JComponent currentComponent =
                  (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
	    if ((currentComponent != null) 
                && (currentComponent.getInputVerifier() != null) 
                && (targetComponent.getVerifyInputWhenFocusTarget())) {
		if (! currentComponent.getInputVerifier().verify(currentComponent)) {
		    // not verified, so eat the mouse event

		}
		else {
		    redispatchEvent(targetComponent, me);
		}
	    }
	    else {
		redispatchEvent(targetComponent, me);
	    }
	}
    }

    private void redispatchEvent(Component component, MouseEvent me) {
	Point componentPoint = SwingUtilities.convertPoint(this, me.getPoint(), component);
	component.dispatchEvent(new MouseEvent(component, 
            me.getID(), 
            me.getWhen(),  
            me.getModifiers(), 
            componentPoint.x, 
            componentPoint.y, 
            me.getClickCount(), 
            me.isPopupTrigger()));
	return;
    }
	
    public static void main(String[] args) {
	JFrame frame = new JFrame("GlassPane Demo");
	JTextField textField = new JTextField("this is a textfield");
	textField.setInputVerifier(new TextVerifier());
	JButton cancelButton = new JButton("Cancel");
	cancelButton.setVerifyInputWhenFocusTarget(false);
	JButton saveButton = new JButton("Save");
	JPanel mainPanel = new JPanel();
	mainPanel.add(textField);
	mainPanel.add(cancelButton);
	mainPanel.add(saveButton);
	frame.getContentPane().add(mainPanel);
	GlassPaneDemo gpd = new GlassPaneDemo(frame.getContentPane());
	frame.setGlassPane(gpd);
	gpd.setVisible(true);
	frame.pack();
	frame.setSize(400, 200);
	frame.show();
    }
}

class TextVerifier extends InputVerifier {
    public boolean verify(JComponent component) {
	if (component instanceof JTextField) {
	    return ((JTextField)component).getText().equalsIgnoreCase("pass");
	}
	return true;
    }
}
</pre>

]]>

</content>
</entry>
<entry>
<title>Hesitant Acrobats</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/07/hesitant_acroba.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-07-21T20:15:57Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.782</id>
<created>2004-07-21T20:15:57Z</created>
<summary type="text/plain">You can&amp;#146;t stand on the shoulders of giants, if you never climb up.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/5963/shoulders.jpg"  width="550" height="280">
<p>
Last week, Daniel Steinberg <a href="http://weblogs.java.net/pub/wlg/1658">wrote</a> that he attended a local JUG meeting to hear Bruce Tate speak about his book &#147;Better, Faster, Lighter Java&#148;.  I was fortunate enough to be at the same meeting.  Bruce's presentation was interesting, and sparked a fair amount of interaction between him and the audience.  Of course, this made the time fly by all too quickly, but Bruce was still able to squeeze in a little time for questions and comments before he had to leave.
</p>
<p>
As Daniel noted in his blog, one of the comments at the end concerned EJB/J2EE&#146;s ability to address complex problems.  Light-weight techologies are all well-and-good, but complex problems require complex solutions.  And in a follow-up remark, the same person held that technologies like Hibernate simply shift complexity, they don't eliminate it.  His belief is that it would take it him as long to feel competent with Hibernate as it took him to feel the same with EJBs.  
</p>
<p>
Another set of the comments came from a person who identified himself as a maintenance programmer.  When something breaks, he&#146;s the guy who&#146;s responsible for fixing it.  In order to do that, he needs access to the code.  His primary concern is that technologies such as Hibernate and Spring may hide too much.  Hidden code is a barrier to him. He doesn&#146;t want to be held responsible for code he can&#146;t touch.
</p>
<p>
While I understand and sympathize with these concerns, I believe both sets of comments reflect an all too common desire by programmers to bury themselves in a morass of details.  Of course, I&#146;m just as guilty as the rest.  As I mentioned in my <a href="http://weblogs.java.net/pub/wlg/1651">last blog</a>, the first thing I did when I got an assignment to support digest authentication  was to sniff the packets going to and from the secured web site.  Now, how detail-centric is that?
</p>
<p>
One of the traits of a good programmer is a love of details. but there is a point where it simply gets in the way.  Light-weight technologies like JDO, Hibernate, Pico, and Spring are designed to leverage reflection,  code generation, and dependency injection.   They're intended to not only introduce flexibility into a system, but to also relieve the programmer of a lot of mundane coding.  You'll certainly want to dig a bit under the hood to see how they work, but detailed understanding is not required.  If you spend too much time examining the giant's shoe size, you'll never have the time to actually climb up to his shoulders.
</p>

]]>

</content>
</entry>
<entry>
<title>Buried treasure can be found nearly anywhere</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2004/07/buried_treasure.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2004-07-14T12:30:06Z</issued>
<id>tag:weblogs.java.net,2004:/blog/castelaz/21.713</id>
<created>2004-07-14T12:30:06Z</created>
<summary type="text/plain">There are nuggets of useful code to be found all around, if  you take a moment to scratch beneath the surface.  A particularly rich treasure can be found in the Jakarta Commons.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/5819/pirate.jpg"  width="550" height="280">
<p>
It started as a typical morning.  I was three days behind schedule on a one day project, but hoping to finish it by late afternoon.  Of course, I&#146;d no sooner gotten into the code, trying to recapture yesterday&#146;s flow, when the phone rang.  The next minute, I was off to my project manager&#146;s office, no doubt to receive yet another reason to delay my current assignment even more.  
</p>
<p>
Now, don&#146;t get me wrong.  I&#146;m not complaining.  I happen to have a great project manager.  He understands that the to-do list is infinitely expandable, but the workday isn&#146;t.  He recognizes that if he pulls me from one task to work another, the one left behind isn&#146;t going to magically complete itself.  His attitude keeps us both sane.  Besides, I like variety, and enjoy having several projects to switch to when I grow stale on one.
</p>
<p>
Sure enough, I did indeed get a new assignment.  I had to write code to login to a web site protected by digest authentication.  Fortunalely, I had worked on a fairly large and reasonably sophisticated authentication/authorization component in the past, and was familiar with the various web login methods.  While I had never actually implemented digest authentication before, I had some understanding of how it worked.  So, after meeting with one of our network administrators, who helped me setup a secured site, we did a bit of packet sniffing of the digest authenticated site we just created.  The packet exchange pretty much matched my general understanding of how authentication process worked, and it didn&#146;t look like it would be all that difficult to implement.
</p>
<p>
Fortunately, before writing any code, my innate laziness asserted itself, if laziness can ever assert itself, and I took a little time to look for something I could use as a starting point.  Things were looking pretty grim, until I hit upon Jakarta Commons&#146; HttpClient.  While Simon Brown has already blogged on this same subject, <a href="http://weblogs.java.net/pub/wlg/544">HttpClient - another great Jakarta Commons component</a>, his discussion was limited to the component&#146;s Post method.  Additionally, HttpClient is such a useful gem, it bears mentioning again-and-again.
</p>
<p>
As I just said, HttpClient is part of the <a href="http://jakarta.apache.org/commons">Jakarta Commons</a>.  The primary goal of the Commons is to create and maintain a repository of reusable Java components which are free and open source.  Although I haven't had a wide exposure to all the components the Commons offers, the ones I have used have been a real pleasure.  This was particularly true for HttpClient.  Unlike a lot of open source, HttpClient has a fairly extensive <a href="http://jakarta.apache.org/commons/httpclient/userguide.html"> User Guide</a>, and between it and a few samples, I was able to put together a digest authentication method in relatively short order.  Certainly, faster than I would have been able to write a bare-bones, untested implementation myself. 
</p>
<p>
<pre>
public void access(HttpURL httpURL) throws Exception {
	try {
		String siteUsername = httpURL.getUser();
		String sitePassword = httpURL.getPassword();
		HttpClient client = new HttpClient();
		if ((siteUsername != null ) && (sitePassword != null)) {
			client.getState().setCredentials("Realm", jnlpURL.getHost(), 
                            new UsernamePasswordCredentials(siteUsername, sitePassword));
		}
		HttpMethod method = new GetMethod(httpURL.getURI());
		try {
			int statusCode = client.executeMethod(method);
			String statusStr = HttpStatus.getStatusText(statusCode);
			if (statusStr.equalsIgnoreCase("unauthorized")) {
				throw new Exception("Not authorized for realm");
			}
			if (statusStr.equalsIgnoreCase("not found")) {
				throw new Exception("Webapp and/or file not found");
			}
			doSomethingUseful(method.getResponseBodyAsStream());
			method.releaseConnection();
		}
		catch (HttpRecoverableException hre) {
			throw new Exception("Exception '" + hre.toString() + "');
		}
		catch (UnknownHostException uhe) {
			throw new Exception("Exception '" + uhe.toString() + "');
		}
	}
	catch (URIException urie) {
		throw new Exception("Exception '" + urie.toString() + "');
	}
	catch (IOException e) {
		throw new Exception("Exception '" + e.toString() + "');
	}
}
</pre>
</p>
There really isn't much to say about the code.  The HttpURL object passed into the <code>access</code> method can be based upon a URL which has an embedded username and password.  If you've never seen the syntax for such a URL, <code>http://craig:foobar@host.com/webapp</code> has an embedded username of <code>craig</code> and password of <code>foobar</code>.  If the username and password are available, the <code>access</code> method establishes credentials based upon the username and password pulled from the URL.  It then performs a standard HTTP GET.   This is where the authentication magic occurs.  Without going into a lot of detail, the web server detects the presence of the credentials and attempts to authenticate the client.  If all goes well, and the credentials are accepted, the client is silently admitted to the protected site.  The various status checks and exception catches throughout the access method are there to give you an indication of what can go wrong.
</p>
<p>
The only warning I need to give regarding the authentication process is that the password needs to be digested prior to being embedded in the URL.   Since the site is protected by digest authentication, it stands to reason that the password needs to be digested before being transmitted to the web server.  The encryption of the password is typically based the MD5 Digest.  A short article explaining Java 2 Security with sample code using MD5 can be found at  <a href="http://www.javaworld.com/javaworld/jw-07-2000/jw-0728-security.html"> Java security evolution and concepts, Part 2</a>.
</p>
<p>
Compared to all that I would have had to write, HttpClient  saved me a considerable amount of time and grief.  Jakarta Commons offers many other useful components.  Check it out !
</p>]]>

</content>
</entry>
<entry>
<title>The Catastrophe Cycle</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2003/12/the_catastrophe.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2003-12-19T05:32:38Z</issued>
<id>tag:weblogs.java.net,2003:/blog/castelaz/21.976</id>
<created>2003-12-19T05:32:38Z</created>
<summary type="text/plain">Sometimes an iterative development process sorta happens on its own.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/1876/steps.jpg" width="500" height="350">
<p>
</p>
<p>
Like Joshua Marinacci <a href="http://weblogs.java.net/pub/wlg/835">How do you develop?</a>, a number of programmers, including myself, have adopted a fairly iterative development style.  For the most part, this has been a conscious decision.  However, there are times when this isn't always so.  Occasionally, the style has more to do with the nature of the work than with the desires of the developer.
</p>
<p>
I was recently preparing for a short presentation when I came across a paper* with a couple of graphs that really caught my eye.  The paper had to do with the requirements gathering process, and how it can be monitored and managed.  Tthe first graph that caught my eye described a straight-forward linear relationship between the time spent gathering requirements and mastering the complexities of a system.  In other words, the more time you spend gathering, the more you understand.  This certainly seems intuitive, and it is how most of us model the process in our heads.  Unfortunately, the model has little to do with reality.  What the researchers actually found is reflected in the graph below.
</p>
<p>
<img src="https://bloggers.dev.java.net/files/documents/84/1878/catastrophe-cycle.JPG" width="500" height="350">
</p>
<p>
Essentially, there are periodic breakdowns in the requirements gathering process.  The researchers call these breakdowns, "catastrophe cycles", and largely attributed them to a form of information or complexity overload.  That is, requirements engineers apparently gather until they go catatonic over the details.  When they reach this point, they need to sit back and digest before they are ready for the next round.  Slippage is inevitable, and there is a sense of three-steps-forward, one-step-back to it all.  However, what I found paricularly interesting besides the discountinuities themselves was the researchers' belief that any requirements gathering process that doesn't experience these catastrophic breakdowns may actually be in trouble.  There is a strong implication that it is impossible to have one without the other.
</p>
<p>
I don't believe it takes much imagination to apply a similar understanding to most phases of development.  We've all experienced catastrophic breakdowns in our projects, and they haven't been limited to just the reguirements phase.  Applying time to mastering complexity works.  It just doesn't work as smoothly as we expect.
</p>
<p>
Perhaps, I should rephrase my earlier statement about adopting an iterative style as a conscious choice.  Maybe it would be truer to say, at least in my case, that I've come to realize that development isn't a straight, upbroken line from start to finish, and that trying to make it so isn't worth the effort.  Like Dr. Strangelove who came to love the bomb, I've come to love the catastrophe cycle.  I've come to accept an iterative style not only as a personal choice, but also as a reflection of the nature of the development process itself.
</p>
--------------------------------------<br>
*<a href="http://citeseer.nj.nec.com/cache/papers/cs/27163/http:zSzzSzwww.deakin.edu.auzSzmiszSzpageszSzstaffzSzpswatmanzSzpdfzSzC_NguyenCarrollAndSwatman_HICSS2000.pdf/supporting-and-monitoring-the.pdf">Supporting and Monitoring the Creativity of IS Personnel during the Requirements Enginerring Process", Nguyen, L., Carroll, J., and Swatman P.A., Proceedings of the 33rd Hawaii International Conference on System Sciences, 2000.</a>
]]>

</content>
</entry>
<entry>
<title>Are Encapsulation, Polymorphism, and Inheritance peers?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2003/09/are_encapsulati.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2003-09-24T18:20:23Z</issued>
<id>tag:weblogs.java.net,2003:/blog/castelaz/21.220</id>
<created>2003-09-24T18:20:23Z</created>
<summary type="text/plain">The three principle features of object-oriented languages are encapsulation, polymorphism, and inheritance.  How we rank them in importance influences our use of OO.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="https://bloggers.dev.java.net/files/documents/84/1070/OOville.jpg" width="350" height="200">
<p>
I spend most of my time as a Java developer happily writing code without explicitly thinking about encapsulation, polymorphism, and inheritance as underlying principles.  I mean those things are given.  It would be like noticing wheels are round each time I get in my car.  Just like I exploit the roundness of my tires as I tool down the street, I make use of the object-oriented features of Java without necessarily being consciously aware that is what I'm doing.
</p>
<p>
This isn't to say I drive with my head stored in the trunk, or that I have it shoved somewhere else when I code.  Although my family and co-workers may have other opinions, I like to believe I'm concentrating on the things that matter most whether I'm driving or programming.  In the case of programming this would include things like fulfilling the spec, designing a system that is maintainable, and writing code that is readable.  I don't set out to create a program that exploits polymorphism.  I create a program to solve a problem.  Encapsulation, polymorphism, and inheritance are means towards that end.  They are not the goals.
</p>
<p>
On the other hand, I'm not neutral in my use of these object-oriented features.  When I reflect upon past work, I detect a strong pattern in my code.  My greatest concern seems to be with encapsulation.  I like to keep as much as I can private.  I'm pretty stingy with the public keyword, and rarely, if ever, use protected.  Polymorphism creeps silently into a number of my projects, but mostly as separate implementations of a common interface, rather than through extension of another class.  In other words, my code tends to emphasis polymorphism over inheritance.
</p>
<p>
I suspect most of these inclinations date back to my years as a C programmer.  I originally encountered the ideas behind The Big Three of OO while coding in that language.  I was already doing both encapsulation and polymorphism through the use of module-level variables and function pointers, but without the cool names for the practice.  When I migrated over to a true OO language, those two concepts traveled with me.  Perhaps I've been damaged somewhere along the line, but I fear inheritance will always come up third in my personal OO lexicon.
</p>
<p>
Then again, isn't that the real beauty of a rich language like Java.  While we can discuss and debate the relative merits of one approach over another, the language is open and flexible enough to allow different interpretations of what is important, and how it should be used.
</p>]]>

</content>
</entry>
<entry>
<title>Robogrammer 2303</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2003/08/robogrammer_230.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2003-08-07T03:36:53Z</issued>
<id>tag:weblogs.java.net,2003:/blog/castelaz/21.1447</id>
<created>2003-08-07T03:36:53Z</created>
<summary type="text/plain">Even it&apos;s not particularly useful, it&apos;s always fun to speculate about the future of programming.</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="/images/weblogs/robogrammer2303.jpg" width="250" height="188">
<p>
Predictions do little for me.  If they're in the near term, they're just stating the obvious, and if they're far into the future, they seem pointless.  On the other hand, it is fun to speculate.  In a recent blog, James Gosling mentioned he still dips into C on occassion.  What this says about the language is interesting, but what it says about programming is even more so.  C is 30 years old!  What will coding be like in another 30?  What languages will programmers use?  Will there still be IDEs?  What sort of platforms will they write against?
</p>
<p>
If we jump 300 years into the future, maybe only androids will code.  As Chris Adamson mentioned in his blog, <a href="http://weblogs.java.net/pub/wlg/303">Widgets follow form follows function</a>, Data's fingers fly across the control panel in STNG.  (The mechanical speed of his typing is blinding, just think of his productivity if he used a USB!)  While we can't assume the computer Data is controlling operates on a series of zeros and ones streaming through a set of processors, we should be able to assume that at the heart of it there is some form of source code which defined it's kernel.  Where did it come from?  Who created it?  What does its syntax look like?  Is it compiled, interpreted, or something entirely different?
</p>
<p>
Java is a fairly young language with hopefully a long life ahead of it.  Perhaps it will outlive us all.  Who knows, it could be the first language some real-life Data cuts his teeth on as a cub programmer.
</p>

]]>

</content>
</entry>
<entry>
<title>Development Tug-o-War</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2003/07/development_tug.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2003-07-09T23:52:33Z</issued>
<id>tag:weblogs.java.net,2003:/blog/castelaz/21.130</id>
<created>2003-07-09T23:52:33Z</created>
<summary type="text/plain">Rave may have some interesting consequences</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="/images/weblogs/tug.jpg" width="350" height="138">
<p>
Sun wants to dramatically increase the number of Java developers with Rave.  They believe a significant portion of this increase will be accomplished by broadening the audience rather than converting existing developers.  Many of these new faces will be end-users, or domain-experts.  Rave promises to introduce a significant number of non-traditional programmers to the ranks of Java developers.
</p>
<p>
This isn't necessarily a bad thing.  Amateur and professional developers tend to inhabit different areas of the programming spectrum.  Each group experiences development from different perspectives and responsibilities.  There is little overlap between them.  Yet, there is tension between the groups.  Wizard-enabled amateurs create applications quickly and easily, and wonder why the professionals are sooooo slooooow, and always act like they're overburdened. The professionals, on the other hand, roll their eyes and sigh as they attempt to scale a quick-and-dirty application, or pick up the pieces of a brittle one-off turned mission critical. 
</p>
<p>
Rave will not be alone in helping to foster this tug-o-war, there are currently plenty of tools that allow the two groups to clash.  Nor, is it like the tug-o-war is a recent phenomenon.  The roots of the tension can be traced back to early spreadsheets like VisiCalc, and can be found in the old engineers vs. hobbyists debate surrounding Turbo Pascal.</p>
<p>
There are interesting days ahead for Java, and it isn't just in terms of technology.
</p>
]]>

</content>
</entry>
<entry>
<title>When GOTOs roamed the land</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/castelaz/archive/2003/06/when_gotos_roam.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2003-06-13T21:21:29Z</issued>
<id>tag:weblogs.java.net,2003:/blog/castelaz/21.578</id>
<created>2003-06-13T21:21:29Z</created>
<summary type="text/plain">Are the green fields of development gone?
</summary>
<author>
<name>castelaz</name>

<email>ccastelaz@hotmail.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/castelaz/">
<![CDATA[<img src="/images/weblogs/gotos_46.jpg" width="350" height="142">
<p>Perhaps its just me, but it seems I’ve recently been encountering quite a few  pronouncements declaring the end of green field development.  I'm not exactly sure what many of the authors necessarily mean, but most make it sound like the party's over.</p>
<p> However, when I think about it, I don't feel any different, certainly not like an era has ended.  Actually, what I suspect is that the green fields they're speaking of died around the same time GOTOs ceased to roam the land.  Not that I'm advocating for a return of the GOTO.  Besides the obvious fact that resurrecting them wouldn't bring back the green fields, they were messy, difficult beasts that produced enormous piles of dung that needed to be dealt with.  Yet, the question remains, is the party over?</p>
<p>For myself, I don’t believe it is.  While the green fields others speak of may indeed be gone, they’ve been gone for far longer than most of us believe.  My work, and the profession at large, continues to be fun, intriguing, and challenging.  Additionally, the beauty of working in the virtual world of programming is that new green fields are constantly sprouting.</p>]]>

</content>
</entry>

</feed>