Search code examples
javaawtshapesglyphimageicon

Can I use a number as the shape icon used to display points on an XYPlot in JFreeChart?


I have three time series that I'm plotting, and I would like to use the numbers 1, 3, and 5 as the actual shapes that the XYLineAndShapeRenderer use to display the series.

Even if you have no experience using JFreeChart, if I could figure out how to do any of the following, I think I could accomplish my task:

  1. Convert a character / glyph to a java.awt.Shape
  2. Convert a character / glyph to an ImageIcon

Solution

  • You can obtain glyph outlines using Font.createGlyphVector and GlyphVector.getGlyphOutline.

    The method below retrieves a GlyphVector for the specified String and retrieves their outlines, applying an AffineTransform in the process.

    static Shape[] getGlyphShapes(Font font, String strGlyphs, AffineTransform transform) {
    
        FontRenderContext frc = new FontRenderContext(null, true, true);
        GlyphVector glyphs = font.createGlyphVector(frc, strGlyphs);
    
        int count = glyphs.getNumGlyphs();
        Shape[] shapes = new Shape[count];
        for (int i = 0; i < count; i ++) {
    
            // get transformed glyph shape
            GeneralPath path = (GeneralPath) glyphs.getGlyphOutline(i);
            shapes[i] = path.createTransformedShape(transform);
        }
        return shapes;
    
    }
    

    By default the returned glyph shapes are of font size 1, hence the AffineTransform. An example transform would be:

                AffineTransform transform = new AffineTransform();
                transform.translate(-20, 20);
                transform.scale(40, 40);
    

    Which should roughly center each glyph (which I presume you'll need) at a font-size of 40. For more accurate centering, you could use GlyphMetrics, obtained through GlyphVector.getGlyphMetric and calculate the exact translation you need.