(Java Swing) Как мне создать JTextPane с несколькими значками на одной строке?
Как говорится в вопросе, как мне успешно разместить несколько значков на одной строке текста вJTextPane
? Каждый раз, когда я пытаюсь изменить значениеactionText
Результаты очень непредсказуемы. В качестве примера, я пытаюсь достичь такой вещи:
Если я передаю только значки-токены для создания значков (например, ""), они просто накладываются друг на друга (или, может быть, нет, трудно сказать). Если я поставлю «,» или «и», то первая иконка истребителя появится в первой строке, а запятая и другая иконка истребителя появится во второй строке.
В настоящее время я пытаюсь использовать решение, основанное на руководстве по оракулу дляJTextPane
: Учебник по JTextPane, Вот фрагмент моего кода, который создает мои собственные текстовые панели.
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) {
// TODO add images (styles) here
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(" "); // 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;
}
currentLineLength += 3; // an icon is about 3 characters in length
} 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;
}
}
Если у кого-то есть лучшее решение, я весь в ушах. Спасибо!