简体   繁体   中英

Word Wrap in Java Swing with Hard Wrap Pixel Limit

I am having issues implementing a word wrap in java in a swing enviroment. I have a hard limit in pixels that I can't go over. I feel like I am close as I have found a solution that wraps, but it lets the last word run over the limit before going to the next line.

'ni' is a buffered image that this is all being drawn to.

'theSettings' custom class that contains variables for the text.

'theText' is the string that needs to be wrapped.

This is what is getting passed to the method:

FontMetrics fm = ni.createGraphics().getFontMetrics(theSettings.getFont());
//Get pixel width of string and divide by # of characters in string to get estimated width of 1 character
int charPixelWidth = fm.stringWidth(theText) / theText.length();
int charWrap = theSettings.getPixelsTillWrap() / charPixelWidth;
List<String> textList = testWordWrap(theText, charWrap);

I am using this method to test:

//Custom String Wrapper as StringUtils.wrap keeps cutting words in half
public static List<String> testWordWrap(String wrapMe, int wrapInChar) {
    StringBuilder sb = new StringBuilder(wrapMe);

    int count = 0;
    while((count = sb.indexOf(" ", count + wrapInChar)) != -1) {
        sb.replace(count, count + 1, "\n");
    }

    String toArray = sb.toString();
    String[] returnArray = toArray.split("\\n");

    ArrayList<String> returnList = new ArrayList<String>();
    for(String s : returnArray) {
        returnList.add(s);
    }

    return returnList;
}

Example in use: 在此处输入图片说明 在此处输入图片说明

I also replace images in the middle of the text, but the size of the image is exactly the size of the text that it is replacing; so that shouldn't be an issue. The blue lines are bounding boxes that show where the wrap should be ending. It shows that the text continues to draw. I need the function to wrap 'succeeded' to the next line; as the wrap can't run over in any situation.

EDIT: The arrays of the image run as .toString();

[Resolution: +|FT| if you succeeded, and matched a |EA|]

[Any: +|MT| when you gain any number, of |QT|]

I was able to identify an answer. I split the string on spaces and then try adding each word one at a time. If it is too long, jump to the next line. Here it is over commented to help anyone else with this same issue. Cheers!

//@Author Hawox
//split string at spaces
//for loop checking to see if adding that next word moves it over the limit, if so go to next line; repeat
public static List<String> wordWrapCustom(String wrapMe, FontMetrics fm, int wrapInPixels){
    //Cut the string into bits at the spaces
    String[] split = wrapMe.split(" ");

    ArrayList<String> lines = new ArrayList<String>(); //we will return this, each item is a line
    String currentLine = ""; //All contents of the currentline

    for(String s : split) {
        //Try to add the next string
        if( fm.stringWidth(currentLine + " " + s) >= wrapInPixels ) {
            //Too big
            if(currentLine != "") { //If it is still bigger with an empty string, still add at least 1 word
                lines.add(currentLine); //Add the line without this string 
                currentLine = s; //Start next line with this string in it
                continue;
            }
        }
        //Still have room, or a single word that is too big
        //add a space if not the first word
        if(currentLine != "")
            currentLine = currentLine + " ";

        //Append string to line
        currentLine = currentLine + s;
    }
    //The last line still may need to get added
    if(currentLine != "") //<- Should not get called, but just in case
        lines.add(currentLine);

    return lines;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM