Search code examples
javaspringaopgraphics2d

Change text of a Graphics2D object


I have the below code, and I want to change text of Graphics2D object (g2D) from "Java" to a new String for example "Pascal".

import java.awt.Graphics2D;
import java.awt.font.TextLayout;    

public void paint(Graphics2D g2D) {

    FontRenderContext frc = g2D.getFontRenderContext();
    Font font1 = new Font("Courier", Font.BOLD, 24);
    String str1 = new String("Java");
    TextLayout tl = new TextLayout(str1, font1, frc);

    g2D.setColor(Color.gray);
    tl.draw(g2D, 50, 150);
}

Note that I have no access to the method body (this methodis part of a Jar file and so I have no access to the method paint), but I have access to the Graphics2D object (g2D) returned by method.

I am goint to use Spring AOP and use @After – Run to extract Graphics2D object (g2D) and then replace the text with a new one. However, I do not know how to do that. In one try, after I create a new TextLayout object with new text, but it adds new text on the previous text without replacing that (now I can see both text - Java and Pascal).

Please let me know how can I change text of a TextLayout object added to a Graphics2D object.


Solution

  • Finally, I solved the problem using Javassist. Because TextLayout is immutable, it is not possible to change its value. Therefore, the best solution (I think) is to rename the current paint method and create a new one using Javassist. Therefore, in run time, my new method is called instead of the original one. The code is as below:

    CtClass clas = ClassPool.getDefault().get("classFullName");
    
    CtMethod mold = clas.getMethod("MethodName", "MethodParameters");
    
    //Rename the original method name
    String nname = mname+"$impl";
    mold.setName(nname);
    CtMethod mnew = CtNewMethod.copy(mold, mname, clas, null);
    
    String bodyText = "New Method body";
    
     StringBuffer body = new StringBuffer();
     body.append(bodyText);
    
    //Replace the body of the intercepter method with generated code block and add it to class.
    mnew.setBody(body.toString());
    clas.addMethod(mnew);
    
    clas.writeFile();
    clas.toClass();