As the question says, how to successfully place multiple icons in one line of text in JTextPane? Every time I try to change a value actionText, the results are very unpredictable. As an example, this is what I am trying to achieve:

If I transfer only badges to create badges (for example, "), they simply stack together (or maybe not so hard to say). If I put", "or" and ", then the first first icon is the fighter will appear in the first line, and the fighter icon will appear in the second line.
I am currently trying to use an oracle textbook solution for JTextPane: JTextPane tutorial . Here is a piece of my code that creates my custom text panels.
public final class GameTextPaneFactory {
private static final String[] ADVENTURER_TOKENS = {"<FIGHTER>", "<CLERIC>", "<WIZARD>", "<ROGUE>"};
private static final int TEXT_PANE_WIDTH = 30;
public static JTextPane createActionTextPane(String actionText) {
ArrayList<String>[] wordsAndStyles = parseActionText(actionText);
JTextPane actionTextPane = new JTextPane();
StyledDocument doc = actionTextPane.getStyledDocument();
addStylesToDocument(doc);
try {
for (int i=0; i < wordsAndStyles[0].size(); i++) {
doc.insertString(doc.getLength(), wordsAndStyles[0].get(i),
doc.getStyle(wordsAndStyles[1].get(i)));
}
} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
}
actionTextPane.setEditable(false);
return actionTextPane;
}
private static void addStylesToDocument(StyledDocument doc) {
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style regular = doc.addStyle("regular", def);
Style icons = doc.addStyle("fighterIcon", regular);
StyleConstants.setAlignment(icons, StyleConstants.ALIGN_CENTER);
ImageIcon fighterIcon = new ImageIcon("images/fighter_image.png", "fighter");
StyleConstants.setIcon(icons, fighterIcon);
icons = doc.addStyle("clericIcon", regular);
StyleConstants.setAlignment(icons, StyleConstants.ALIGN_CENTER);
ImageIcon clericIcon = new ImageIcon("images/cleric_image.png", "cleric");
StyleConstants.setIcon(icons, clericIcon);
icons = doc.addStyle("wizardIcon", regular);
StyleConstants.setAlignment(icons, StyleConstants.ALIGN_CENTER);
ImageIcon wizardIcon = new ImageIcon("images/wizard_image.png", "wizard");
StyleConstants.setIcon(icons, wizardIcon);
icons = doc.addStyle("rogueIcon", regular);
StyleConstants.setAlignment(icons, StyleConstants.ALIGN_CENTER);
ImageIcon rogueIcon = new ImageIcon("images/rogue_image.png", "rogue");
StyleConstants.setIcon(icons, rogueIcon);
}
private static ArrayList<String>[] parseActionText(String text) {
String[] words = text.split(" ");
ArrayList<String> outputStrings = new ArrayList<String>();
ArrayList<String> outputStyles = new ArrayList<String>();
StringBuilder nextStringBuilder = new StringBuilder();
int currentLineLength = TEXT_PANE_WIDTH;
for(String word : words) {
if(Arrays.asList(ADVENTURER_TOKENS).contains(word)) {
if(nextStringBuilder.length() != 0) {
outputStrings.add(nextStringBuilder.toString());
outputStyles.add("regular");
nextStringBuilder = new StringBuilder();
}
outputStrings.add(" ");
switch(word) {
case "<FIGHTER>":
outputStyles.add("fighterIcon");
break;
case "<CLERIC>":
outputStyles.add("clericIcon");
break;
case "<WIZARD>":
outputStyles.add("wizardIcon");
break;
case "<ROGUE>":
outputStyles.add("rogueIcon");
break;
}
currentLineLength += 3;
} else {
if(currentLineLength + word.length() + 1 > TEXT_PANE_WIDTH) {
nextStringBuilder.append("\n");
currentLineLength = 0;
}
nextStringBuilder.append(" " + word);
currentLineLength += word.length() + 1;
}
}
if(nextStringBuilder.length() != 0) {
outputStrings.add(nextStringBuilder.toString());
outputStyles.add("regular");
}
@SuppressWarnings("unchecked")
ArrayList<String>[] output = new ArrayList[2];
output[0] = outputStrings;
output[1] = outputStyles;
return output;
}
}
If anyone has a better solution, I'm all ears. Thank!