COMP 310
Fall 2012

Problems Viewing UML Diagrams

Home  Info  Owlspace  Java Resources  Eclipse Resources

A number of students have reported problems viewing their UML diagrams.   A typical error message is a blank diagram tab with something along the lines of the "could not open the editor:  Node is not a child of a methodDeclaration or initializer block".   Other signs are a spurious dependency line in the upper left corner of the diagram.   If you are experiencing any sort of problems, be sure to let the staff know right away!

The problem seems to be traceable to a bug in Green UML relating to how it handles static fields, especially those that reference arrays or those that are initialized using a factory method.   If you see any additional possible causes, please let the Comp310 staff know right away.  

In general, the only place you should be using a static field is for a Singleton object.

 

A Common Scenario

Here is a scenario that I have seen a couple of times:

public class MyCompositePaintStrategy extends MultiPaintStrategy {
 
    private statics APaintStrategy[] myPStrats = {new EllipsePaintStrategy(), new RectanglePaintStrategy()};
    
    public  MyCompositePaintStrategy() {
       super(new AffineTransform(), myPStrats);
    }
 
// etc …
}

 

public class MultiPaintStrategy  extends APaintStrategy {
 
    public APaintStrategy[] pStrats;
 
    public MultiPaintStrategy(AffineTransform at, APaintStrategy[] pStrats) {
         super(at); 
         this.pStrats = pStrats;
    }
 
// etc …
}

 

There are two fixes to the above code, one fast and the other better.   Both involve getting rid of the static field in MyComposite:

Quick fix:   dynamically allocate the array without using a field or variable.

public class MyCompositePaintStrategy extends MultiPaintStrategy {
 
    public  MyCompositePaintStrategy() {
       super(new AffineTransform(), new APaintStrategy[]{new EllipsePaintStrategy(), new RectanglePaintStrategy()});
    }
 
…etc
}

 

Better fix:   Change MultiPaintStrategy to take a vararg

public class MultiPaintStrategy  extends APaintStrategy {
 
    public APaintStrategy[] _pStrats;
 
    public MultiPaintStrategy(AffineTransform at, APaintStrategy… pStrats) {
         super(at); 
         _pStrats = pStrats;
    }
 
// etc …
}

Notice that that the only change is to replace a “[]” with “” in the MultiPaintStrategy constructor's signature.  Nothing else changes because the type of pStrats was and still is APaintStrategy[].    See the discussion on vararg parameters at the bottom of Lec12.

The effect of this is to simplify MyCompositePaintStrategy considerably:

public class MyCompositePaintStrategy extends MultiPaintStrategy {
 
    public  MyCompositePaintStrategy() {
       super(new AffineTransform(), new EllipsePaintStrategy(), new RectanglePaintStrategy());
    }
 
//etc… 
}

 

Another Common Scenario

This scenario seems to be less associated with UML diagram issues but is worth fixing anyway.

A number of people have been using a static field to hold the options for classes that randomly choose an image or the like, for example like such:

public class BirdSheepImagePaintStrategy extends ImagePaintStrategy {

	private static String[] imageFiles = {"images/humbird_animate.gif","images/sheep_animate.gif"}; // array of file names.

	public BirdSheepImagePaintStrategy() {
		super(imageFiles [Randomizer.Singleton.randomInt(0, 2)], 0.5);
	}
}

The solution is to use Java's "ternary conditional operator" or simply, the "?" operator:

public class BirdSheepImagePaintStrategy extends ImagePaintStrategy {

	public BirdSheepImagePaintStrategy() {
		super( ((Math.random() < 0.5)?"images/humbird_animate.gif" : "images/sheep_animate.gif") , 0.5);
	}
}

For the more general case, where more than 2 choices are desired, use a dynamically created array as was done above:

public class BirdSheepImagePaintStrategy extends ImagePaintStrategy {

	public BirdSheepImagePaintStrategy() {
		super( (new String[]{"images/humbird_animate.gif", "images/sheep_animate.gif", "images/Mario_animate.gif", "images/Sonic_animate.gif"})[Randomizer.Singleton.randomInt(0, 4)], 0.5);
	}
}

 

 

 


© 2012 by Stephen Wong