next up previous contents
Next: Updating the coordinate display Up: The Viewer: Getting and Previous: The ImageDisplayMap Class

Configuring the ImageDisplayMap Object

Turning back to our example, the PosTrackerViewer maintains an ImageDisplayMap object which must updated everytime a new Slice is displayed. Here is that first section of code from the displaySlice(Slice sl) that we showed above but with a few more lines:

    if (newViewable) {

        // this is a new data set, so we need to update our coordinate
        // system 
        coordSys = data.getCoordSys();

        // we also need to reset our ImageDisplayMap object that defines
        // the mapping between display and data pixels.
        setPixelMap(slice, null);
        newViewable = false;
    } 
    else {

        // this is just a new slice from an already attached Viewable;
        // thus, we need only update the pixel mapper.
        updatePixelMap();
    }
The setPixelMap() and updatePixelMap() methods keep the ImageDisplayMap object in sync with what is being viewed, so let's have a look at them. Here's the code for the method that sets up the ImageDisplayMap when a new Viewable is attached to the Viewer:
protected synchronized void setPixelMap(Slice dataSlice, 
                                        Rectangle displayRegion) {

    Boolean xaxisReversed, yaxisReversed;
    if (data != null) {

        pixelMap = new ImageDisplayMap();

        // the attached viewable may give some hints on how the 
        // data is ordered in the form of "xaxisReversed" and
        // "yaxisReversed" metadata
        // 
        Metadata md = data.getMetadata();
        if (md != null) {
            try {
                xaxisReversed = (Boolean) md.getMetadatum("xaxisReversed");
            } catch (ClassCastException ex) { xaxisReversed = null; }
            try {
                yaxisReversed = (Boolean) md.getMetadatum("yaxisReversed");
            } catch (ClassCastException ex) { yaxisReversed = null; }
        }

        if (xaxisReversed != null) 
            pixelMap.xaxisReversed = xaxisReversed.booleanValue();
        if (yaxisReversed != null) 
            pixelMap.yaxisReversed = yaxisReversed.booleanValue();
    }

    // now set the mapping appropriate for a slice of requested size
    updatePixelMap(dataSlice, displayRegion);
}
Note that we have consulted the Viewable's metadata for the values xaxisReversed and yaxisReversed. If values are found there, they are passed to the ImageDisplayMap object; otherwise, the default value of false is kept.

Now let's look at updatePixelMap which is called whenever a new slice is displayed:

    protected synchronized void updatePixelMap(Slice dataSlice, 
                                               Rectangle displayRegion) {
        int dwd=-1, dht=-1;

        if (pixelMap == null) {
            setPixelMap(dataSlice, displayRegion);    
            return;                 // this calls updatePixelMap(),
                                    //   so we should return
        }
        if (dataSlice == null && displayRegion == null) return;

        if (displayRegion == null) {
            dwd = dataSlice.getTrueLength(slice.getXaxis());
            dht = dataSlice.getTrueLength(slice.getYaxis());

            // this is how much space an image with an unscaled size of 
            // wd x ht will take up on the screen
            //
            Dimension dispdim = display.viewSize(dwd, dht);
            displayRegion = new Rectangle(0, 0, dispdim.width, dispdim.height);
        }

        if (dataSlice != null) pixelMap.setSlice(dataSlice);
        if (displayRegion != null) pixelMap.setDisplay(displayRegion);
    }
As it turns out in our implementation, the value of displayRegion is always null, so the default--as much as the display area as possible--is used instead.



Ray Plante
Mon Aug 25 15:16:12 CDT 1997