As the question states, how do I successfully place multiple icons on the same line of text in a JTextPane
? Every time I try to change the value of actio
Check out Auto Replace Smiles Text With Appropriate Images. Probably not exactly what you are looking for but it should give you some ideas
Try adding
outputStrings.add(" "); // this is ignored, but cannot be empty
outputStyles.add("regular");
After each new "adventurer" style
outputStrings.add(" "); // this is ignored, but cannot be empty
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;
}
outputStrings.add(" "); // this is ignored, but cannot be empty
outputStyles.add("regular");
Updated
I had a bit of a play around, seeing if I could get the formatting to look a little better, this is basically what I came up with...
Instead of using styles, I basically insert the text and images directly to the text pane. There seems to be issues with like styles been set next to each other, so that instead what happens, they are basically merged into a single entry in the document, this would explain why you had issues with your styles. I had a similar issue with the icons for some reason, hence the reason why I had to create a new instance each time...
This is a bit rough and ready, but the basic idea is there. It basically uses the Regular Expression API to find all the matches of the "keywords", inserts the text before it and then inserts a special icon depending on the keyword...
public static JTextPane createActionTextPane(String actionText) {
JTextPane actionTextPane = new JTextPane();
actionTextPane.setOpaque(false);
StyledDocument doc = actionTextPane.getStyledDocument();
Pattern pattern = Pattern.compile("<FIGHTER>|<CLERIC>|<GOLD>");
Matcher matcher = pattern.matcher(actionText);
int previousMatch = 0;
while (matcher.find()) {
int startIndex = matcher.start();
int endIndex = matcher.end();
String group = matcher.group();
String subText = actionText.substring(previousMatch, startIndex);
if (!subText.isEmpty()) {
actionTextPane.replaceSelection(subText);
}
switch (group) {
case "<FIGHTER>":
actionTextPane.insertIcon(new ImageIcon("fifight.gif"));
break;
case "<CLERIC>":
actionTextPane.insertIcon(new ImageIcon("mage.gif"));
break;
case "<GOLD>":
actionTextPane.insertIcon(new ImageIcon("Gold.png"));
break;
}
previousMatch = endIndex;
}
String subText = actionText.substring(previousMatch);
if (!subText.isEmpty()) {
actionTextPane.replaceSelection(subText);
}
actionTextPane.setEditable(false);
return actionTextPane;
}
Now, frankly, I've not bothered about line widths or the like, and instead, used a JScrollPane
and the JTextComponent
's wrapping capabilities instead...but that's up to you...