1

I need to split a String that is going to be displayed in a box using java.awt.Graphics. The problem is, I need the string to automatically be split when it reaches the rectangles width in pixels. For example,

"This is an example string. What goes into the string does not matter" 
[----------------------------------------] <-- Hypothetical width of box/rect

I need the string to be split between "goes" and "into" so I can then have the rest of the text on a new line:

"This is an example string. What goes
into the string does not matter" 
[----------------------------------------] <-- Hypothetical width of box/rect

I know how to get the width of a string, but I do not know how to go about splitting it.

ntalbs
  • 28,700
  • 8
  • 66
  • 83
  • https://stackoverflow.com/questions/18327825/how-do-i-calculate-the-width-of-a-string-in-pixels – BackSlash Apr 08 '19 at 14:00
  • Depends on the font used (if it is not always a fixed sized font). Java swing and JavaFX would use a bit different code. Best would be to let a GUI component take care of it, with word-wrap. – Joop Eggen Apr 08 '19 at 14:03
  • @BackSlash I stated that I already know how to find the width of a string in pixels. Its splitting it at a certain width that I am looking for – Pneuma Official Apr 08 '19 at 14:03
  • @PneumaOfficial Once you know how to do that, you can either calculate the with of single letters and sum them up until you reach your maximum width, or you can try going with a percentage comparison. – BackSlash Apr 08 '19 at 14:06
  • Seems that try-and-error is needed. Create a substring at some index and calculate its width, adjust as needed. Use linear interpolation to calculate the initial and all following guesses. – Mark Schäfer Apr 08 '19 at 14:08
  • @BackSlash true, I could use a for- loop and create a new string using each word, then when that string width reaches the rectangles width, create a new one... – Pneuma Official Apr 08 '19 at 14:09
  • @PneumaOfficial Or, better IMO, use percentages. If your entire string is 25 characters long, 500px wide and you need to break at 100px, you know that you likely need to break something near `100/500px = 20% length = 5 characters`, you can then go back until you find a blank space and use substring. Of course each character has its own width, so this calculation must be tried and adjusted, but it's a valid starting point. – BackSlash Apr 08 '19 at 14:11
  • Can't you just use JTextArea, which already supports text wrapping? https://docs.oracle.com/javase/7/docs/api/javax/swing/JTextArea.html#setLineWrap(boolean) – NeplatnyUdaj Apr 08 '19 at 14:24
  • @NeplatnyUdaj I would like to keep everything in Graphics – Pneuma Official Apr 08 '19 at 16:03

2 Answers2

0

I know I am super late to stating if I figured it out or not, but I managed to do it myself without a 3rd party API. It isn't super efficient as if the string length gets too long, the last word is cut off. (You can look at the code if you wish, but I can no longer explain how it works as I have not looked at it in a long time.

public class ConsoleLog {
private static Color c = Color.WHITE;
public static Color getC() {
    return c;
}

public static void setC(Color c) {
    ConsoleLog.c = c;
}

private static int pos;
private static List<String[]> logs;
private static List<Point>linesPos = new ArrayList<Point>();
private static Rectangle r = Main.Main.screenSize;
public static void log(List <String[]> logs, Graphics g) {
    g.setColor(c);
    ConsoleLog.logs = logs;
    splitConsole(g);
}

public static void splitConsole(Graphics g){
    pos = 0;
    for(int i = 0; i < (r.height / 2) / 10 - 10; i++) {
        linesPos.add(new Point(10, (i * (r.height / (50 + 3) + 5) + 15)));
    }
    for(int i = 0; i < logs.size(); i++) {
        for(int ie = 0; ie < logs.get(i).length || pos < logs.get(i).length; ie++) {
            g.drawString(logs.get(i)[ie], linesPos.get(pos).x, linesPos.get(pos).y);
            pos++;
        }
    }
}

To be clear, I was developing a small game engine and decided to scrap it as it was getting too messy, inefficient, and was built around a clicker game. I am working on a second one that will be able to create any 2D game the user wants and it is very user friendly. It is almost ready for its first version and I am excited to see what can be made out of it!

0

A simple solution to "ellipsing" a string to fit a Swing control using Apache Commons StringUtils.

This uses the pixel width of both the target and the string. Most Swing controls have getWidth().

 String status = num + " of " + numToCopy + ", " + size + ", " + name;

 FontMetrics metrics = myTextField.getFontMetrics(myTextField.getFont());
 int width = metrics.stringWidth(status);
 int max = myTextField.getWidth();

 if (width > max)
 {
     String ext = Utils.getFileExtension(status);
     int extLen = metrics.stringWidth(ext);
     // remove file extension
     status = status.substring(0, status.length() - ext.length());
     max = max - extLen;
     // remove end characters until it fits
     while (width > max)
     {
         status = StringUtils.abbreviate(status, status.length() - 1);
         width = metrics.stringWidth(status);
     }
     // add file extension
     status += ext;
 }
 myTextField.setText(status);
Todd Hill
  • 51
  • 1
  • 3