Search code examples
javaswingprintinggraphics2d

Java 7 - Graphics2D.setFont() and Graphics2D.setColor() is being overridden by defaults when Printing.


I have a program that draws to the a panel and also prints. When drawing to the Canvas the renderer produces the correct output. However when drawing to the print method the font is overridden with a default font. Please see below two images displaying the out put. Canvas or Screen Output

Printed PDF output

The code to the specific areas are in my Visualise2D.class The Renderers for the Canvas and the Print are the same they both call the Visualise2D.class.

Some Code from Visualise2D

    public void paintSurfaceTimes(Graphics2D gTimes, SurfaceConnector s, Dummy d, Color c, Rectangle2D bounds,double scale, double enhanceTie, double enhance ){
    gTimes.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    FontMetrics fm = gTimes.getFontMetrics();
    double hEdge = (UnitConvert.pixelsToMeters(LiteTieTRIAL.averageSize));
    double x1 =((d.getEasting() - bounds.getX()));
    double y1 = (bounds.getHeight() + bounds.getY() - d.getNorthing());

    if (d instanceof Hole) {
        hEdge = (UnitConvert.pixelsToMeters(((Hole) d).getDiameter()* enhance)/2);
    }
    else
        hEdge = (UnitConvert.pixelsToMeters(LiteTieTRIAL.averageSize * enhance)/2);

    x1 =((d.getEasting() - bounds.getX()));
    y1 = (bounds.getHeight() + bounds.getY() - d.getNorthing());

    gTimes.setColor(c);
    gTimes.setFont(DEFAULT_FONT);
    fm = gTimes.getFontMetrics();
    gTimes.drawString((dec0P.format(s.getTime())), 
            (int)((x1+hEdge*Math.cos(180))*scale - fm.getStringBounds(dec0P.format(s.getTime()), gTimes).getWidth()),
            (int)((y1 - hEdge*Math.sin(0))*scale+ fm.getStringBounds(dec0P.format(s.getTime()), gTimes).getHeight()));
}

And some Code from paintComponent(Graphics g) in my getCanvas() method

                    //Draws SurfaceTimes
                if(surfaceTimesOnOffButton.isSelected())    {
                    try {
                        getSurfaceTimes();
                    } catch (NegativeNumberException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    for(Pattern tempPat: world.getPatternList().values()){
                        for(SurfaceConnector sc: tempPat.getSurfaceList().values()){
                            //                          boolean isSelected = sc == selected || (selected instanceof Collection<?> && ((Collection<?>)selected).contains(sc));   

                            if(sc.getTo() instanceof Dummy ){
                                renderer.paintSurfaceTimes(g2, sc, sc.getTo(), colourTimes, bounds, Zoom.getScalingFactor()* UnitConvert.metersToPixels(1), enhanceTie, enhance);
                            }

                        }
                    }
                }

The only differences between the canvas drawing code and the printable is: getCanvas() code below...

Visualise2D renderer = new Visualise2D();
            @Override public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;

LiteTiePrinter.class

public class LiteTiePrinter implements Printable {

public int print(Graphics g, PageFormat pf, int page) throws PrinterException {

// We have only one page, and 'page'
// is zero-based
if (page > 0) {
     return NO_SUCH_PAGE;
}

Graphics2D g2d = (Graphics2D)g;

g2d.translate(pf.getImageableX(), pf.getImageableY());

// Now we perform our rendering
Visualise2D renderer = new Visualise2D();

Any help is appreciated as to why the output on fonts is different. Thank you in advance.


Solution

  • Hello to anyone reading this. I thought I'd share my 15hrs of searching the internet and stack overflow to find an answer to my own question. I just found one and tested a suggestion out. And it worked.

    I choose to use the answer supplied by user456837. If I had enough points I'd up vote this user.

    The answer was to supplement the drawString() with drawGlyphVector(). It worked!

    //GET THE FONTMETRICS
            FontMetrics fm = h2.getFontMetrics();
            //GET THE DIAMETER OF THE HOLE
            double hEdge = (UnitConvert.pixelsToMeters(hole.getDiameter()));
            // GET THE LOCATION OF THE HOLE
            double x1 =((hole.getEasting() - bounds.getX()));
            double y1 = (bounds.getHeight() + bounds.getY() - hole.getNorthing());
            //SET THE COLOUR OF THE TEXT
            h2.setColor(AMETHYST);
            //SET THE FONT TO USE
            h2.setFont(new Font("Monaco", Font.BOLD, 8));
            //USING - DRAWGLYPHVECTOR() TO OVERCOME THE PRINTING ISSUE RELATED TO THE OSX PORT OF JAVA7 - MAY NOT NEED THIS WITH FUTURE UPDATES.
            h2.drawGlyphVector(
                    h2.getFont().createGlyphVector(h2.getFontRenderContext(), 
                    dec1P.format(hole.getHoleLength())),
                    (int)((x1+hEdge*Math.cos(300))*scale)- (fm.stringWidth(dec1P.format(hole.getHoleLength()))/2),  
                    (int)((y1 + (hEdge *enhance*1.1)/2)*scale) +(fm.getHeight()/2) +pixelOffset
                    );
            
            /*//USING - DRAWSTRING() DOESN'T WORK IN JAVA 7 ON MAC OSX
            h2.drawString(
                    (dec1P.format(hole.getHoleLength())),   
                    (int)((x1+hEdge*Math.cos(300))*scale)- (fm.stringWidth(dec1P.format(hole.getHoleLength()))/2),  
                    (int)((y1 + (hEdge *enhance*1.1)/2)*scale) +(fm.getHeight()/2) +pixelOffset
                    );
    */
    

    I hope that this helps anyone searching for the same issue. Also I suggest you read Stephane Grenier's blog on the issue. It mentions in one of the blog comments that this is not evident in Java 7u40... so maybe I'd be best to upgrade…?

    PLEASE READ THE LINK BELOW

    Printing issue on osx