Example usage for java.awt Graphics drawString

List of usage examples for java.awt Graphics drawString

Introduction

In this page you can find the example usage for java.awt Graphics drawString.

Prototype

public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);

Source Link

Document

Renders the text of the specified iterator applying its attributes in accordance with the specification of the java.awt.font.TextAttribute TextAttribute class.

Usage

From source file:com.lfv.lanzius.server.WorkspaceView.java

@Override
protected void paintComponent(Graphics g) {
    int w = getWidth();
    int h = getHeight();

    Document doc = server.getDocument();

    Color storedCol = g.getColor();
    Font storedFont = g.getFont();

    // Fill workspace area
    g.setColor(getBackground());//from w  w  w.j  av  a  2s. c om
    g.fillRect(0, 0, w, h);

    // Should the cached version be updated?
    int updateDocumentVersion = server.getDocumentVersion();
    boolean update = (documentVersion != updateDocumentVersion);

    // Check if we have cached the latest document version, otherwise cache the terminals
    if (update) {
        log.debug("Updating view to version " + updateDocumentVersion);
        terminalMap.clear();
        groupList.clear();
        if (doc != null) {
            synchronized (doc) {

                // Clear the visible attribute on all groups
                // except the started or paused ones
                Element egd = doc.getRootElement().getChild("GroupDefs");
                Iterator iter = egd.getChildren().iterator();
                while (iter.hasNext()) {
                    Element eg = (Element) iter.next();
                    boolean isVisible = !DomTools.getAttributeString(eg, "state", "stopped", false)
                            .equals("stopped");
                    eg.setAttribute("visible", String.valueOf(isVisible));
                }

                // Gather information about terminals and cache it
                Element etd = doc.getRootElement().getChild("TerminalDefs");
                iter = etd.getChildren().iterator();
                while (iter.hasNext()) {
                    Element et = (Element) iter.next();
                    int tid = DomTools.getAttributeInt(et, "id", 0, false);
                    if (tid > 0) {
                        // Create terminal and add it to list
                        Terminal t = new Terminal(tid, DomTools.getAttributeInt(et, "x", 0, false),
                                DomTools.getAttributeInt(et, "y", 0, false),
                                DomTools.getChildText(et, "Name", "T/" + tid, false),
                                DomTools.getAttributeBoolean(et, "online", false, false),
                                DomTools.getAttributeBoolean(et, "selected", false, false));
                        terminalMap.put(tid, t);

                        // Is the terminal monitored?
                        t.isMonitored = DomTools.getAttributeBoolean(et, "monitored", false, false);

                        // Examine the Player element under PlayerSetup
                        t.groupColor = null;
                        Element ep = DomTools.getElementFromSection(doc, "PlayerSetup", "terminalid",
                                String.valueOf(tid));

                        // Has linked player for this terminal
                        if (ep != null) {
                            StringBuffer sb = new StringBuffer();

                            // Append player name
                            sb.append(DomTools.getChildText(ep, "Name", "P/?", true));
                            sb.append(" (");

                            // Append role list
                            boolean hasRoles = false;
                            Element ers = ep.getChild("RoleSetup");
                            if (ers != null) {
                                Iterator iterr = ers.getChildren().iterator();

                                while (iterr.hasNext()) {
                                    Element er = (Element) iterr.next();
                                    String id = er.getAttributeValue("id");
                                    er = DomTools.getElementFromSection(doc, "RoleDefs", "id", id);
                                    if (er != null) {
                                        sb.append(DomTools.getChildText(er, "Name", "R/" + id, false));
                                        sb.append(", ");
                                        hasRoles = true;
                                    }
                                }
                                if (hasRoles) {
                                    // Trim last comma
                                    int len = sb.length();
                                    sb.setLength(Math.max(len - 2, 0));
                                }
                                sb.append(")");
                            }
                            t.roles = sb.toString();

                            // Is the player relocated?
                            t.isRelocated = DomTools.getAttributeBoolean(ep, "relocated", false, false);

                            // Get group name and color
                            Element eg = DomTools.getElementFromSection(doc, "GroupDefs", "id",
                                    DomTools.getAttributeString(ep, "groupid", "0", true));
                            t.groupColor = Color.lightGray;
                            if (eg != null) {
                                String sc = DomTools.getChildText(eg, "Color", null, false);
                                if (sc != null) {
                                    try {
                                        t.groupColor = Color.decode(sc);
                                    } catch (NumberFormatException ex) {
                                        log.warn("Invalid color attribute on Group node, defaulting to grey");
                                    }
                                }
                                //t.name += "  "+DomTools.getChildText(eg, "Name", "G/"+eg.getAttributeValue("id"), false);
                                t.groupName = DomTools.getChildText(eg, "Name",
                                        "G/" + eg.getAttributeValue("id"), false);

                                // This group should now be visible
                                eg.setAttribute("visible", "true");
                            } else
                                log.warn("Invalid groupid attribute on Player node, defaulting to grey");
                        }
                    } else
                        log.error("Invalid id attribute on Terminal node, skipping");
                }

                // Gather information about groups and cache it
                iter = egd.getChildren().iterator();
                while (iter.hasNext()) {
                    Element eg = (Element) iter.next();
                    if (DomTools.getAttributeBoolean(eg, "visible", false, false)) {
                        int gid = DomTools.getAttributeInt(eg, "id", 0, true);
                        if (gid > 0) {
                            Group grp = new Group(gid, DomTools.getChildText(eg, "Name", "G/" + gid, false),
                                    DomTools.getAttributeBoolean(eg, "selected", false, false));
                            groupList.add(grp);

                            // group color
                            String sc = DomTools.getChildText(eg, "Color", null, false);
                            if (sc != null) {
                                try {
                                    grp.color = Color.decode(sc);
                                } catch (NumberFormatException ex) {
                                    log.warn("Invalid color attribute on Group node, defaulting to grey");
                                }
                            }

                            // state color
                            grp.stateColor = Color.red;
                            String state = DomTools.getAttributeString(eg, "state", "stopped", false);
                            if (state.equals("started"))
                                grp.stateColor = Color.green;
                            else if (state.equals("paused"))
                                grp.stateColor = Color.orange;
                        }
                    }
                }
            }
        }
    }

    if (doc == null) {
        g.setColor(Color.black);
        String text = "No configuration loaded. Select 'Load configuration...' from the file menu.";
        g.drawString(text, (w - SwingUtilities.computeStringWidth(g.getFontMetrics(), text)) / 2, h * 5 / 12);
    } else {
        g.setFont(new Font("Dialog", Font.BOLD, 13));

        Iterator<Terminal> itert = terminalMap.values().iterator();
        while (itert.hasNext()) {
            Terminal t = itert.next();

            // Draw box
            int b = t.isSelected ? SERVERVIEW_SELECTION_BORDER : 1;
            g.setColor(Color.black);
            g.fillRect(t.x + SERVERVIEW_SELECTION_BORDER - b, t.y + SERVERVIEW_SELECTION_BORDER - b,
                    SERVERVIEW_TERMINAL_WIDTH + 2 * b, SERVERVIEW_TERMINAL_HEIGHT + 2 * b);
            g.setColor(t.groupColor == null ? Color.white : t.groupColor);
            g.fillRect(t.x + SERVERVIEW_SELECTION_BORDER, t.y + SERVERVIEW_SELECTION_BORDER,
                    SERVERVIEW_TERMINAL_WIDTH, SERVERVIEW_TERMINAL_HEIGHT);

            // Inner areas
            Rectangle r = new Rectangle(t.x + SERVERVIEW_SELECTION_BORDER + SERVERVIEW_TERMINAL_BORDER,
                    t.y + SERVERVIEW_SELECTION_BORDER + SERVERVIEW_TERMINAL_BORDER,
                    SERVERVIEW_TERMINAL_WIDTH - 2 * SERVERVIEW_TERMINAL_BORDER,
                    g.getFontMetrics().getHeight() + 4);

            g.setColor(Color.white);
            g.fillRect(r.x, r.y, r.width, r.height);
            g.fillRect(r.x, r.y + r.height + SERVERVIEW_TERMINAL_BORDER + 2, r.width,
                    SERVERVIEW_TERMINAL_HEIGHT - 3 * SERVERVIEW_TERMINAL_BORDER - r.height - 2);
            g.setColor(Color.black);
            g.drawRect(r.x, r.y, r.width, r.height);
            g.drawRect(r.x, r.y + r.height + SERVERVIEW_TERMINAL_BORDER + 2, r.width,
                    SERVERVIEW_TERMINAL_HEIGHT - 3 * SERVERVIEW_TERMINAL_BORDER - r.height - 2);

            // Name of terminal and group
            if (server.isaClient(t.tid)) {
                g.drawImage(indicatorIsa.getImage(), r.x + r.width - 20, r.y + SERVERVIEW_TERMINAL_HEIGHT - 26,
                        null);
            }
            g.drawString(t.name + " " + t.groupName, r.x + 4, r.y + r.height - 4);

            double px = r.x + 4;
            double py = r.y + r.height + SERVERVIEW_TERMINAL_BORDER + 5;

            // Draw monitored indicator
            if (t.isMonitored) {
                g.drawImage(indicatorMonitored.getImage(), r.x + r.width - 9, r.y + 3, null);
            }

            // Draw relocated indicator
            if (t.isRelocated) {
                g.drawImage(indicatorRelocated.getImage(), r.x + r.width - 9, r.y + 13, null);
            }

            // Draw online indicator
            r.setBounds(r.x, r.y + r.height, r.width, 3);
            g.setColor(t.isOnline ? Color.green : Color.red);
            g.fillRect(r.x, r.y, r.width, r.height);
            g.setColor(Color.black);
            g.drawRect(r.x, r.y, r.width, r.height);

            // Roles
            if (t.roles.length() > 0) {
                LineBreakMeasurer lbm = new LineBreakMeasurer(new AttributedString(t.roles).getIterator(),
                        new FontRenderContext(null, false, true));

                TextLayout layout;
                while ((layout = lbm
                        .nextLayout(SERVERVIEW_TERMINAL_WIDTH - 2 * SERVERVIEW_TERMINAL_BORDER)) != null) {
                    if (py < t.y + SERVERVIEW_TERMINAL_HEIGHT) {
                        py += layout.getAscent();
                        layout.draw((Graphics2D) g, (int) px, (int) py);
                        py += layout.getDescent() + layout.getLeading();
                    }
                }
            }
        }

        // Draw group indicators
        int nbrGroupsInRow = w
                / (2 * Constants.SERVERVIEW_SELECTION_BORDER + 2 + Constants.SERVERVIEW_GROUP_WIDTH);
        if (nbrGroupsInRow < 1)
            nbrGroupsInRow = 1;
        int nbrGroupRows = (groupList.size() + nbrGroupsInRow - 1) / nbrGroupsInRow;

        int innerWidth = Constants.SERVERVIEW_GROUP_WIDTH;
        int innerHeight = g.getFontMetrics().getHeight() + 5;

        int outerWidth = innerWidth + 2 * Constants.SERVERVIEW_SELECTION_BORDER + 2;
        int outerHeight = innerHeight + 2 * Constants.SERVERVIEW_SELECTION_BORDER + 2;

        int x = 0;
        int y = h - outerHeight * nbrGroupRows;

        g.setColor(Color.white);
        g.fillRect(0, y, w, h - y);
        g.setColor(Color.black);
        g.drawLine(0, y - 1, w - 1, y - 1);

        Iterator<Group> iterg = groupList.iterator();
        while (iterg.hasNext()) {
            Group grp = iterg.next();

            // Group box
            grp.boundingRect.setBounds(x, y, outerWidth, outerHeight);
            int b = grp.isSelected ? Constants.SERVERVIEW_SELECTION_BORDER : 1;
            g.setColor(Color.black);
            g.fillRect(x + Constants.SERVERVIEW_SELECTION_BORDER - b + 1,
                    y + Constants.SERVERVIEW_SELECTION_BORDER - b + 1, innerWidth + 2 * b, innerHeight + 2 * b);
            g.setColor(grp.color);
            g.fillRect(x + Constants.SERVERVIEW_SELECTION_BORDER + 1,
                    y + Constants.SERVERVIEW_SELECTION_BORDER + 1, innerWidth, innerHeight);

            g.setColor(Color.black);
            g.drawString(grp.name, x + Constants.SERVERVIEW_SELECTION_BORDER + 4,
                    y + Constants.SERVERVIEW_SELECTION_BORDER + innerHeight - 4 + 1);

            // Draw started indicator
            g.setColor(grp.stateColor);
            g.fillRect(x + Constants.SERVERVIEW_SELECTION_BORDER + 1,
                    y + Constants.SERVERVIEW_SELECTION_BORDER + 1, innerWidth, 2);
            g.setColor(Color.black);
            g.drawLine(x + Constants.SERVERVIEW_SELECTION_BORDER + 1,
                    y + Constants.SERVERVIEW_SELECTION_BORDER + 3,
                    x + Constants.SERVERVIEW_SELECTION_BORDER + 1 + innerWidth,
                    y + Constants.SERVERVIEW_SELECTION_BORDER + 3);

            x += outerWidth;
            if ((x + outerWidth) > w) {
                x = 0;
                y += outerHeight;
            }
        }
    }

    // Store cached version
    documentVersion = updateDocumentVersion;

    g.setColor(storedCol);
    g.setFont(storedFont);
}

From source file:ucar.unidata.idv.ui.ImageGenerator.java

/**
 * Process the image//from   ww  w  .jav  a 2  s  .c  om
 *
 * @param image The image
 * @param filename File to write the image to
 * @param node Node to process
 * @param props Extra properties
 * @param viewManager The viewmanager this image came from
 * @param imageProps  the image properties
 *
 *
 * @return The processed image
 * @throws Throwable On badness
 */
protected BufferedImage processImage(BufferedImage image, String filename, Element node, Hashtable props,
        ViewManager viewManager, Hashtable imageProps) throws Throwable {

    if (node == null) {
        return image;
    }

    if (props == null) {
        props = new Hashtable();
    }
    if (viewManager != null) {
        Animation animation = viewManager.getAnimation();
        props.put(PROP_ANIMATIONTIME, "");
        if (animation != null) {
            if (animation.getAniValue() != null) {
                props.put(PROP_ANIMATIONTIME, animation.getAniValue());
            }
        }
    }
    getProperties().putAll(props);

    NodeList elements = XmlUtil.getElements(node);
    Hashtable seenColorTable = new Hashtable();
    for (int childIdx = 0; childIdx < elements.getLength(); childIdx++) {
        boolean shouldIterateChildren = true;
        BufferedImage newImage = null;
        int imageWidth = image.getWidth(null);
        int imageHeight = image.getHeight(null);
        Element child = (Element) elements.item(childIdx);
        String tagName = child.getTagName();

        if (tagName.equals(TAG_RESIZE)) {
            newImage = ImageUtils.toBufferedImage(resize(image, child));
        } else if (tagName.equals(TAG_FILESET)) {
            //ignore
        } else if (tagName.equals(TAG_OUTPUT)) {
            processTagOutput(child);
        } else if (tagName.equals(TAG_DISPLAYLIST)) {
            if (viewManager != null) {
                newImage = ImageUtils.toBufferedImage(image, true);
                Graphics g = newImage.getGraphics();
                String valign = applyMacros(child, ATTR_VALIGN, VALUE_BOTTOM);
                Font font = getFont(child);
                if (XmlUtil.hasAttribute(child, ATTR_MATTEBG)) {
                    int height = viewManager.paintDisplayList((Graphics2D) g, null, imageWidth, imageHeight,
                            valign.equals(VALUE_BOTTOM), null, font);

                    int top = (valign.equals(VALUE_TOP) ? height : 0);
                    int bottom = (valign.equals(VALUE_BOTTOM) ? height : 0);
                    newImage = ImageUtils.matte(image, top, bottom, 0, 0,
                            applyMacros(child, ATTR_MATTEBG, Color.white));
                    g = newImage.getGraphics();
                    imageHeight += height;
                }

                Color c = applyMacros(child, ATTR_COLOR, (Color) null);
                viewManager.paintDisplayList((Graphics2D) g, null, imageWidth, imageHeight,
                        valign.equals(VALUE_BOTTOM), c, font);
            }
        } else if (tagName.equals(TAG_COLORBAR) || tagName.equals(TAG_KML_COLORBAR)) {
            // only do one colorbar if we are writing to kml
            Integer index = (Integer) props.get(PROP_IMAGEINDEX);
            if ((index != null) && (index.intValue() > 0) && tagName.equals(TAG_KML_COLORBAR)) {
                continue;
            }

            boolean showLines = applyMacros(child, ATTR_SHOWLINES, false);

            List<DisplayControlImpl> controls = (List<DisplayControlImpl>) ((viewManager != null)
                    ? viewManager.getControls()
                    : new ArrayList());

            if (XmlUtil.hasAttribute(child, ATTR_DISPLAY)) {
                DisplayControlImpl display = ((controls.size() > 0)
                        ? findDisplayControl(XmlUtil.getAttribute(child, ATTR_DISPLAY), controls)
                        : findDisplayControl(child));
                if (display == null) {
                    error("Could not find display:" + XmlUtil.toString(node));
                    return null;
                }
                controls = Misc.newList(display);
            }

            int width = applyMacros(child, ATTR_WIDTH, 150);
            int height = applyMacros(child, ATTR_HEIGHT, 20);
            int ticks = applyMacros(child, ATTR_TICKMARKS, 0);
            double interval = applyMacros(child, ATTR_INTERVAL, -1.0);
            String valuesStr = applyMacros(child, ATTR_VALUES, (String) null);
            Color c = applyMacros(child, ATTR_COLOR, Color.black);

            Color lineColor = applyMacros(child, ATTR_LINECOLOR, c);

            Rectangle imageRect = new Rectangle(0, 0, imageWidth, imageHeight);

            Point pp = ImageUtils.parsePoint(applyMacros(child, ATTR_PLACE, "ll,10,-10"), imageRect);
            Point ap = ImageUtils.parsePoint(applyMacros(child, ATTR_ANCHOR, "ll"),
                    new Rectangle(0, 0, width, height));

            String orientation = applyMacros(child, ATTR_ORIENTATION, VALUE_BOTTOM);
            boolean vertical = orientation.equals(VALUE_RIGHT) || orientation.equals(VALUE_LEFT);
            int baseY = pp.y - ap.y + (vertical ? 0 : height);
            int baseX = pp.x - ap.x;

            List colorTables = new ArrayList();
            List ranges = new ArrayList();
            List units = new ArrayList();

            boolean forKml = tagName.equals(TAG_KML_COLORBAR);

            for (int i = 0; i < controls.size(); i++) {
                DisplayControlImpl control = (DisplayControlImpl) controls.get(i);
                ColorTable colorTable = control.getColorTable();
                if (colorTable == null) {
                    continue;
                }
                Range range = control.getRangeForColorTable();
                //only do unique color tables
                Object[] key = { colorTable, range };
                if (seenColorTable.get(key) != null) {
                    continue;
                }
                seenColorTable.put(key, key);
                colorTables.add(colorTable);
                ranges.add(range);
                units.add(control.getDisplayUnit());
            }

            for (int i = 0; i < colorTables.size(); i++) {
                ColorTable colorTable = (ColorTable) colorTables.get(i);
                Range range = (Range) ranges.get(i);
                Unit unit = (Unit) units.get(i);
                Image imageToDrawIn;
                if (forKml) {
                    if (vertical) {
                        baseX = 0;
                        baseY = 0;
                    } else {
                        baseX = 0;
                        baseY = height;
                    }
                    int space = applyMacros(child, ATTR_SPACE, (vertical ? width : height));
                    imageToDrawIn = new BufferedImage(width + (vertical ? space : 0),
                            height + (vertical ? 0 : space), BufferedImage.TYPE_INT_RGB);
                } else {
                    imageToDrawIn = newImage = ImageUtils.toBufferedImage(image);
                }
                Graphics g = imageToDrawIn.getGraphics();
                if (forKml) {
                    Color bgColor = applyMacros(child, ATTR_BACKGROUND, Color.white);
                    g.setColor(bgColor);
                    g.fillRect(0, 0, imageToDrawIn.getWidth(null), imageToDrawIn.getHeight(null));
                }
                boolean includeAlpha = applyMacros(child, ATTR_TRANSPARENCY, true);

                float[][] ctValues;

                if (includeAlpha) {
                    ctValues = colorTable.getAlphaTable();
                } else {
                    ctValues = colorTable.getNonAlphaTable();
                }
                ColorMap colorMap = new BaseRGBMap(ctValues);
                ColorPreview preview = new ColorPreview(colorMap, (vertical ? width : height));
                if (vertical) {
                    preview.setSize(new Dimension(height, width));
                } else {
                    preview.setSize(new Dimension(width, height));
                }
                Image previewImage = ColorTableCanvas.getImage(colorTable, (vertical ? height : width),
                        (vertical ? width : height), includeAlpha);

                if (vertical) {
                    int imageType = includeAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;

                    BufferedImage tmpImage = new BufferedImage(width, height, imageType);

                    Graphics2D tmpG = (Graphics2D) tmpImage.getGraphics();
                    tmpG.rotate(Math.toRadians(90.0));
                    tmpG.drawImage(previewImage, 0, 0 - width, null);
                    previewImage = tmpImage;
                }
                if (forKml) {
                    g.drawImage(previewImage, 0, 0, null);
                } else {
                    g.drawImage(previewImage, baseX, (vertical ? baseY : baseY - height), null);
                }
                if (showLines) {
                    g.setColor(lineColor);
                    g.drawRect(baseX, (vertical ? baseY : baseY - height), width - 1,
                            height - (vertical ? 1 : 0));
                }
                setFont(g, child);
                FontMetrics fm = g.getFontMetrics();
                List values = new ArrayList();
                String suffixFrequency = XmlUtil.getAttribute(child, ATTR_SUFFIXFREQUENCY,
                        XmlUtil.getAttribute(child, ATTR_SHOWUNIT, "false")).toLowerCase();
                String unitDefault = (!suffixFrequency.equals("false")) ? " %unit%" : "";
                String labelSuffix = applyMacros(child, ATTR_SUFFIX, unitDefault);
                if (unit != null) {
                    labelSuffix = labelSuffix.replace("%unit%", "" + unit);
                } else {
                    labelSuffix = labelSuffix.replace("%unit%", "");
                }
                if (valuesStr != null) {
                    double[] valueArray = Misc.parseDoubles(valuesStr, ",");
                    for (int valueIdx = 0; valueIdx < valueArray.length; valueIdx++) {
                        values.add(new Double(valueArray[valueIdx]));
                    }
                } else if (ticks > 0) {
                    int spacing = ((ticks == 1) ? 0 : (vertical ? height : width) / (ticks - 1));
                    for (int tickIdx = 0; tickIdx < ticks; tickIdx++) {
                        double percent = ((ticks > 1) ? (double) tickIdx / (double) (ticks - 1) : 0.0);
                        values.add(new Double(range.getValueOfPercent(percent)));
                    }
                } else if (interval > 0) {
                    double value = range.getMin();
                    double max = range.getMax();
                    while (value <= max) {
                        values.add(new Double(value));
                        value += interval;
                    }
                }
                for (int valueIdx = 0; valueIdx < values.size(); valueIdx++) {
                    double value = ((Double) values.get(valueIdx)).doubleValue();
                    int x;
                    int y;
                    if (vertical) {
                        if (orientation.equals(VALUE_RIGHT)) {
                            x = baseX + width;
                        } else {
                            x = baseX;
                        }
                        y = baseY + (int) (range.getPercent(value) * height);
                        if (y > baseY + height) {
                            break;
                        }
                    } else {
                        if (orientation.equals(VALUE_BOTTOM)) {
                            y = baseY;
                        } else {
                            y = baseY - height;
                        }

                        if (range != null) {
                            x = baseX + (int) (range.getPercent(value) * width);
                        } else {
                            x = baseX;
                        }

                        if (x > baseX + width) {
                            break;
                        }
                    }
                    String tickLabel = getIdv().getDisplayConventions().format(value);
                    if (suffixFrequency.equals(VALUE_LAST) && (valueIdx == values.size() - 1)) {
                        tickLabel += labelSuffix;
                    } else if (suffixFrequency.equals(VALUE_FIRST) && (valueIdx == 0)) {
                        tickLabel += labelSuffix;
                    } else if (suffixFrequency.equals(VALUE_ALL) || suffixFrequency.equals("true")) {
                        tickLabel += labelSuffix;
                    }

                    Rectangle2D rect = fm.getStringBounds(tickLabel, g);
                    g.setColor(lineColor);
                    if (orientation.equals(VALUE_RIGHT)) {
                        g.drawLine(x + 1, y, x, y);
                        if (showLines) {
                            g.drawLine(x, y, x - width, y);
                        }
                    } else if (orientation.equals(VALUE_LEFT)) {
                        g.drawLine(x - 1, y, x, y);
                        if (showLines) {
                            g.drawLine(x, y, x + width, y);
                        }
                    } else if (orientation.equals(VALUE_BOTTOM)) {
                        g.drawLine(x, y + 1, x, y);
                        if (showLines) {
                            g.drawLine(x, y, x, y - height);
                        }
                    } else {
                        g.drawLine(x, y - 1, x, y);
                        if (showLines) {
                            g.drawLine(x, y, x, y + height);
                        }
                    }
                    g.setColor(c);
                    if (orientation.equals(VALUE_RIGHT)) {
                        int yLoc = y + (int) (rect.getHeight() / 2) - 2;
                        if (forKml) {
                            if (valueIdx == 0) {
                                yLoc = y + (int) (rect.getHeight()) - 2;
                            } else if (valueIdx == values.size() - 1) {
                                yLoc = y - (int) (rect.getHeight()) + 6;
                            }
                        }
                        g.drawString(tickLabel, x + 2, yLoc);
                    } else if (orientation.equals(VALUE_LEFT)) {
                        int xLoc = x - 2 - (int) rect.getWidth();
                        g.drawString(tickLabel, xLoc, y + (int) (rect.getHeight() / 2) - 2);
                    } else if (orientation.equals(VALUE_BOTTOM)) {
                        int xLoc = x - (int) (rect.getWidth() / 2);
                        if (forKml) {
                            if (valueIdx == 0) {
                                xLoc = x + 2;
                            } else if (valueIdx == values.size() - 1) {
                                xLoc = x - (int) rect.getWidth() + 2;
                            }
                        }
                        g.drawString(tickLabel, xLoc, y + (int) rect.getHeight() + 2);
                    } else {
                        g.drawString(tickLabel, x - (int) (rect.getWidth() / 2), y - 2);
                    }
                }
                if (vertical) {
                    baseX += width + 30;
                } else {
                    baseY += height + 30;
                }
                if (forKml) {
                    String tmpImageFile = applyMacros(child, ATTR_FILE,
                            getIdv().getStore().getTmpFile("testcolorbar${viewindex}.png"));
                    String template = "<ScreenOverlay><name>${kml.name}</name><Icon><href>${icon}</href></Icon>\n"
                            + "<overlayXY x=\"${kml.overlayXY.x}\" y=\"${kml.overlayXY.y}\" xunits=\"${kml.overlayXY.xunits}\" yunits=\"${kml.overlayXY.yunits}\"/>\n"
                            + "<screenXY x=\"${kml.screenXY.x}\" y=\"${kml.screenXY.y}\" xunits=\"${kml.screenXY.xunits}\" yunits=\"${kml.screenXY.yunits}\"/>\n"
                            + "<size x=\"${kml.size.x}\" y=\"${kml.size.y}\" xunits=\"${kml.size.xunits}\" yunits=\"${kml.size.yunits}\"/>\n"
                            + "</ScreenOverlay>\n";
                    String[] macros = { "kml.name", "kml.overlayXY.x", "kml.overlayXY.y",
                            "kml.overlayXY.xunits", "kml.overlayXY.yunits", "kml.screenXY.x", "kml.screenXY.y",
                            "kml.screenXY.xunits", "kml.screenXY.yunits", "kml.size.x", "kml.size.y",
                            "kml.size.xunits", "kml.size.yunits" };
                    String[] macroValues = { "", "0", "1", "fraction", "fraction", "0", "1", "fraction",
                            "fraction", "-1", "-1", "pixels", "pixels" };

                    for (int macroIdx = 0; macroIdx < macros.length; macroIdx++) {
                        template = template.replace("${" + macros[macroIdx] + "}",
                                applyMacros(child, macros[macroIdx], macroValues[macroIdx]));
                    }
                    template = template.replace("${icon}", IOUtil.getFileTail(tmpImageFile));
                    imageProps.put("kml", template);
                    List kmlFiles = (List) imageProps.get("kmlfiles");
                    //TODO: Only do the first one for now
                    if (kmlFiles == null) {
                        kmlFiles = new ArrayList();
                        imageProps.put("kmlfiles", kmlFiles);
                    }
                    kmlFiles.add(tmpImageFile);

                    //                        System.out.println(template);
                    ImageUtils.writeImageToFile(imageToDrawIn, tmpImageFile);
                }
            }

        } else if (tagName.equals(TAG_TRANSPARENT) || tagName.equals(TAG_BGTRANSPARENT)) {
            Color c = null;
            if (tagName.equals(TAG_BGTRANSPARENT)) {
                c = viewManager.getBackground();
            } else {
                c = applyMacros(child, ATTR_COLOR, (Color) null);
            }
            //                System.err.println ("c:" + c);
            int[] redRange = { 0, 0 };
            int[] greenRange = { 0, 0 };
            int[] blueRange = { 0, 0 };
            if (c != null) {
                //                    System.err.println("got color");
                redRange[0] = redRange[1] = c.getRed();
                greenRange[0] = greenRange[1] = c.getGreen();
                blueRange[0] = blueRange[1] = c.getBlue();
            } else {
            }
            newImage = ImageUtils.makeColorTransparent(image, redRange, greenRange, blueRange);
        } else if (tagName.equals(TAG_SHOW)) {
            JComponent contents = new JLabel(new ImageIcon(image));
            String message = applyMacros(child, ATTR_MESSAGE, (String) null);
            if (message != null) {
                contents = GuiUtils.topCenter(new JLabel(message), contents);
            }
            if (!GuiUtils.askOkCancel("Continue?", contents)) {
                throw new MyQuitException();
            }
        } else if (tagName.equals(TAG_MATTE)) {
            newImage = doMatte(image, child, 0);
        } else if (tagName.equals(TAG_LATLONLABELS)) {
            newImage = doLatLonLabels(child, viewManager, image, imageProps);
        } else if (tagName.equals(TAG_WRITE)) {
            ImageUtils.writeImageToFile(image, getImageFileName(applyMacros(child, ATTR_FILE)));

        } else if (tagName.equals(TAG_PUBLISH)) {
            getIdv().getPublishManager().publishIslImage(this, node, image);
        } else if (tagName.equals(TAG_CLIP)) {
            int[] ul;
            int[] lr;
            if (XmlUtil.hasAttribute(child, ATTR_DISPLAY)) {
                //                    System.err.println("Clipping from display");
                DisplayControlImpl dc = findDisplayControl(child);
                if (dc == null) {
                    throw new IllegalArgumentException("Could not find display:" + XmlUtil.toString(node));
                }
                NavigatedDisplay display = (NavigatedDisplay) viewManager.getMaster();
                MapProjection mapProjection = dc.getDataProjection();
                java.awt.geom.Rectangle2D rect = mapProjection.getDefaultMapArea();
                LatLonPoint llplr = mapProjection.getLatLon(new double[][] { { rect.getX() + rect.getWidth() },
                        { rect.getY() + rect.getHeight() } });
                LatLonPoint llpul = mapProjection
                        .getLatLon(new double[][] { { rect.getX() }, { rect.getY() } });
                EarthLocation ulEl = new EarthLocationTuple(llpul, new Real(RealType.Altitude, 0));
                EarthLocation lrEl = new EarthLocationTuple(llplr, new Real(RealType.Altitude, 0));
                ul = display.getScreenCoordinates(display.getSpatialCoordinates(ulEl, null));
                lr = display.getScreenCoordinates(display.getSpatialCoordinates(lrEl, null));
                //System.err.println("ul:" + ulEl + " lr:" + lrEl);
                if (ul[0] > lr[0]) {
                    int tmp = ul[0];
                    ul[0] = lr[0];
                    lr[0] = tmp;
                }
                if (ul[1] > lr[1]) {
                    int tmp = ul[1];
                    ul[1] = lr[1];
                    lr[1] = tmp;
                }
                imageProps.put(ATTR_NORTH, new Double(ulEl.getLatitude().getValue()));
                imageProps.put(ATTR_WEST, new Double(ulEl.getLongitude().getValue()));
                imageProps.put(ATTR_SOUTH, new Double(lrEl.getLatitude().getValue()));
                imageProps.put(ATTR_EAST, new Double(lrEl.getLongitude().getValue()));
            } else if ((viewManager != null) && XmlUtil.hasAttribute(child, ATTR_NORTH)) {
                NavigatedDisplay display = (NavigatedDisplay) viewManager.getMaster();
                EarthLocation el1 = DisplayControlImpl.makeEarthLocation(toDouble(child, ATTR_NORTH),
                        toDouble(child, ATTR_WEST), 0);
                EarthLocation el2 = DisplayControlImpl.makeEarthLocation(toDouble(child, ATTR_SOUTH),
                        toDouble(child, ATTR_EAST), 0);
                ul = display.getScreenCoordinates(display.getSpatialCoordinates(el1, null));
                lr = display.getScreenCoordinates(display.getSpatialCoordinates(el2, null));
                imageProps.put(ATTR_NORTH, new Double(el1.getLatitude().getValue()));
                imageProps.put(ATTR_WEST, new Double(el1.getLongitude().getValue()));
                imageProps.put(ATTR_SOUTH, new Double(el2.getLatitude().getValue()));
                imageProps.put(ATTR_EAST, new Double(el2.getLongitude().getValue()));
            } else if (XmlUtil.hasAttribute(child, ATTR_LEFT)) {
                ul = new int[] { (int) toDouble(child, ATTR_LEFT, imageWidth),
                        (int) toDouble(child, ATTR_TOP, imageHeight) };
                lr = new int[] { (int) toDouble(child, ATTR_RIGHT, imageWidth),
                        (int) toDouble(child, ATTR_BOTTOM, imageHeight) };
            } else if (viewManager != null) {
                //TODO: Clip on visad coordinates
                NavigatedDisplay display = (NavigatedDisplay) viewManager.getMaster();
                ul = display.getScreenCoordinates(new double[] { -1, 1, 0 });
                lr = display.getScreenCoordinates(new double[] { 1, -1, 0 });
                int space = applyMacros(child, ATTR_SPACE, 0);
                int hspace = applyMacros(child, ATTR_HSPACE, space);
                int vspace = applyMacros(child, ATTR_VSPACE, space);
                ul[0] -= applyMacros(child, ATTR_SPACE_LEFT, hspace);
                ul[1] -= applyMacros(child, ATTR_SPACE_TOP, vspace);
                lr[0] += applyMacros(child, ATTR_SPACE_RIGHT, hspace);
                lr[1] += applyMacros(child, ATTR_SPACE_BOTTOM, vspace);
            } else {
                continue;
            }

            for (String attr : (List<String>) Misc.newList(ATTR_NORTH, ATTR_SOUTH, ATTR_EAST, ATTR_WEST)) {
                String kmlAttr = "kml." + attr;
                if (XmlUtil.hasAttribute(child, kmlAttr)) {
                    imageProps.put(attr, new Double(applyMacros(child, kmlAttr, 0.0)));
                }
            }

            ul[0] = Math.max(0, ul[0]);
            ul[1] = Math.max(0, ul[1]);

            lr[0] = Math.min(lr[0], imageWidth);
            lr[1] = Math.min(lr[1], imageHeight);

            newImage = ImageUtils.clip(image, ul, lr);
        } else if (tagName.equals(TAG_SPLIT)) {
            shouldIterateChildren = false;
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            int cols = applyMacros(child, ATTR_COLUMNS, 2);
            int rows = applyMacros(child, ATTR_ROWS, 2);
            String file = applyMacros(child, ATTR_FILE);
            int cnt = 0;
            int hSpace = width / cols;
            int vSpace = height / rows;
            for (int row = 0; row < rows; row++) {
                for (int col = 0; col < cols; col++) {
                    pushProperties();
                    Hashtable myprops = new Hashtable();
                    putProperty("row", new Integer(row));
                    putProperty("column", new Integer(col));
                    putProperty("count", new Integer(++cnt));
                    String realFile = applyMacros(file, myprops);
                    Image splitImage = image.getSubimage(hSpace * col, vSpace * row, hSpace, vSpace);
                    processImage(ImageUtils.toBufferedImage(splitImage), realFile, child, myprops, viewManager,
                            new Hashtable());
                    popProperties();
                }
            }
        } else if (tagName.equals(TAG_THUMBNAIL)) {
            shouldIterateChildren = false;
            BufferedImage thumbImage = ImageUtils.toBufferedImage(resize(image, child));
            String thumbFile = applyMacros(child, ATTR_FILE, (String) null);
            if (thumbFile == null) {
                thumbFile = IOUtil.stripExtension(filename) + "_thumb" + IOUtil.getFileExtension(filename);
            }
            processImage(thumbImage, thumbFile, child, null, viewManager, new Hashtable());
        } else if (tagName.equals(TAG_KML)) {
            //NOOP
        } else if (tagName.equals(TAG_KMZFILE)) {
            //NOOP
        } else if (tagName.equals(TAG_OVERLAY)) {
            double transparency = applyMacros(child, ATTR_TRANSPARENCY, 0.0);
            Graphics2D g = image.createGraphics();
            String imagePath = applyMacros(child, ATTR_IMAGE, (String) null);

            float scale = (float) applyMacros(child, ATTR_SCALE, 1.0);

            Rectangle imageRect = new Rectangle(0, 0, imageWidth, imageHeight);
            Point pp = ImageUtils.parsePoint(applyMacros(child, ATTR_PLACE, "lr,-10,-10"), imageRect);
            String text = applyMacros(child, ATTR_TEXT, (String) null);
            Color bg = applyMacros(child, ATTR_BACKGROUND, (Color) null);
            if (text != null) {
                double angle = Math.toRadians(applyMacros(child, ATTR_ANGLE, 0.0));
                text = applyMacros(text);
                Color c = applyMacros(child, ATTR_COLOR, Color.white);
                if ((c != null) && (transparency > 0)) {
                    c = new Color(c.getRed(), c.getGreen(), c.getBlue(), ImageUtils.toAlpha(transparency));
                }
                //Color bg = applyMacros(child, ATTR_BACKGROUND,
                //                       (Color) null);
                if ((bg != null) && (transparency > 0)) {
                    bg = new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), ImageUtils.toAlpha(transparency));
                }
                setFont(g, child);
                FontMetrics fm = g.getFontMetrics();
                Rectangle2D rect = fm.getStringBounds(text, g);
                int width = (int) rect.getWidth();
                int height = (int) (rect.getHeight());

                Point ap = ImageUtils.parsePoint(applyMacros(child, ATTR_ANCHOR, "lr,-10,-10"),
                        new Rectangle(0, 0, width, height));

                g.rotate(angle);

                if (bg != null) {
                    g.setColor(bg);
                    g.fillRect(pp.x - ap.x - 1, pp.y - ap.y - 1, (int) width + 2, (int) height + 2);
                }
                g.setColor(c);
                g.drawString(text, pp.x - ap.x, pp.y - ap.y + height);
            }

            if (imagePath != null) {
                Image overlay = ImageUtils.readImage(imagePath);
                if (overlay != null) {
                    if (transparency > 0) {
                        overlay = ImageUtils.setAlpha(overlay, transparency);
                    }

                    int width = overlay.getWidth(null);
                    int height = overlay.getHeight(null);
                    int scaledWidth = Math.round(width * scale);
                    int scaledHeight = Math.round(height * scale);

                    Image scaled = getScaledImage(overlay, scaledWidth, scaledHeight);
                    Rectangle overlayRect = new Rectangle(0, 0, scaledWidth, scaledHeight);
                    Point ap = ImageUtils.parsePoint(applyMacros(child, ATTR_ANCHOR, "lr,-10,-10"),
                            overlayRect);
                    g.drawImage(scaled, pp.x - ap.x, pp.y - ap.y, bg, null);
                }
            }
        } else {
            error("Unknown tag:" + tagName);
        }
        if (newImage != null) {
            String newFileName = applyMacros(child, ATTR_FILE, (String) null);
            if (shouldIterateChildren) {
                logger.trace("newFileName='{}' viewManager={} newImage={}", newFileName, viewManager, newImage);
                newImage = processImage(newImage, newFileName, child, null, viewManager, new Hashtable());
                logger.trace("finished processImage; result: {}", newImage);
            }
            if (newFileName != null) {
                logger.trace("calling writeImageToFile...");
                ImageUtils.writeImageToFile(newImage, getImageFileName(newFileName));
                logger.trace("finished writeImageToFile");
                debug("Writing image:" + newFileName);
            }
            if (!applyMacros(child, ATTR_COPY, false)) {
                image = newImage;
            }
        }
    }

    if (filename != null) {
        float quality = (float) applyMacros(node, ATTR_QUALITY, 1.0);
        List<String> fileToks = StringUtil.split(filename, ",", true, true);
        for (String file : fileToks) {
            file = getImageFileName(file);
            debug("Writing image:" + file);
            if (file.endsWith(FileManager.SUFFIX_KMZ) || file.endsWith(FileManager.SUFFIX_KML)) {
                GeoLocationInfo bounds = null;
                if (viewManager != null) {
                    bounds = viewManager.getVisibleGeoBounds();
                    ImageSequenceGrabber.subsetBounds(bounds, imageProps);
                    String tmpImageFile = getOutputPath(file);
                    ImageUtils.writeImageToFile(image, tmpImageFile, quality);
                    ImageWrapper imageWrapper = new ImageWrapper(tmpImageFile, null, bounds, null);
                    imageWrapper.setProperties(imageProps);
                    new ImageSequenceGrabber(file, getIdv(), this, node,
                            (List<ImageWrapper>) Misc.newList(imageWrapper), null, 1);
                }
            } else {
                logger.trace("another writeImageToFile call...");
                ImageUtils.writeImageToFile(image, file, quality);
                logger.trace("and it's done.");
            }
        }
    }
    logger.trace("result: {}", image);
    return image;
}