HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Changing the foreground and background colors of substrings based on ANSI escape codes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
substringsthebackgroundforegroundansicolorscodesbasedandchanging

Problem

I am checking for particular keywords in a string, and then changing the foreground and background colors of substrings based on the keywords. Following is the snippet for checking the background code:

if(string.contains("[30;42m") || string.contains("[31;42m") || string.contains("[32;42m") ||
    string.contains("[33;42m") || string.contains("[34;42m") || string.contains("[35;42m")
    || string.contains("[36;42m") || string.contains("[37;42m")){
        //the parameter of indexOf and replaceAll will be one from the above
        //using [30;42m as an example
        index = string.indexOf("[30;42m"); 
        string = string.replaceAll("\\[30;42m", "");
        backgroundColor = Color.GREEN;
        //foreground is already set using separate conditions for 30,32,32...37m
     }


Is there any way that I can do something as I have shown above? Currently, I have separate conditions for each substring, which doesn't incorporates "DRY" principle. My code is working, but I am looking for a way to reduce these if statements.

Edit:
The if blocks are for setting the background and foreground colors. For example if I have "34;42" code, this means text foreground color is Blue and background color is Green, and so on.

Solution

You can do it a little more generic but I'm afraid you still have to test each.

I don't know if your case is always changing to green or not.

If not I suggest the following enum :

/**
 *
 * @author chillworld
 */
public enum ColorMapperEnum {
    GREEN("[30;42m",Color.GREEN) ,
    RED("[31;42m",Color.RED) ,
    BLACK("[32;42m", Color.BLACK) ,
    BLUE("[33;42m", Color.BLUE); // and so on

    private String textToFind;
    private Color targetColor;

    private ColorMapperEnum(String textToFind, Color targetColor) {
        this.textToFind = textToFind;
        this.targetColor = targetColor;
    }

    public String getTextToFind() {
        return textToFind;
    }

    public Color getTargetColor() {
        return targetColor;
    }
}


Now you can do a whole lot more generic in your java code :

for (ColorMapperEnum colorMapper : ColorMapperEnum.values()) {
    if(string.contains(colorMapper.getTextToFind()){
        index = string.indexOf(colorMapper.getTextToFind()); 
        string = string.replaceAll("\\" + colorMapper.getTextToFind(), "");
        backgroundColor = colorMapper.getTextToFind();
    }
 }


I did use the same naming as yo but I advice to take better naming.

String string => very bad, for what stands it?

Now I don't know if there could be a case that multiple conditions are true and what there must be done when multiple conditions are true.

An enum values() has always the same result in the same order.
Use that in your advantage when tackling that problem.

Code Snippets

/**
 *
 * @author chillworld
 */
public enum ColorMapperEnum {
    GREEN("[30;42m",Color.GREEN) ,
    RED("[31;42m",Color.RED) ,
    BLACK("[32;42m", Color.BLACK) ,
    BLUE("[33;42m", Color.BLUE); // and so on

    private String textToFind;
    private Color targetColor;

    private ColorMapperEnum(String textToFind, Color targetColor) {
        this.textToFind = textToFind;
        this.targetColor = targetColor;
    }

    public String getTextToFind() {
        return textToFind;
    }

    public Color getTargetColor() {
        return targetColor;
    }
}
for (ColorMapperEnum colorMapper : ColorMapperEnum.values()) {
    if(string.contains(colorMapper.getTextToFind()){
        index = string.indexOf(colorMapper.getTextToFind()); 
        string = string.replaceAll("\\" + colorMapper.getTextToFind(), "");
        backgroundColor = colorMapper.getTextToFind();
    }
 }

Context

StackExchange Code Review Q#49301, answer score: 5

Revisions (0)

No revisions yet.