JTextPane、StyledDocument:根据原始输入索引设置插入符位置
JTextPane, StyledDocument: setting caret position from raw input index
我有一个 JTextPane,其中 html 内容是我从文件中加载的。一些评论标签是占位符,我想在它们之前插入组件。我正在使用正则表达式匹配器查找这些标签,我可以使用 matcher.start() 获取这些标签的索引。问题是我无法将插入符号位置放置到 html 标记的索引中,因为插入符号位置需要用户界面插入符号。标签将被忽略,图像仅计入一个插入符号。所以我需要一种在指定索引处插入组件的方法。
这是我的代码。
package me.winter.trapgame.client.menu;
import me.winter.trapgame.client.ResourceManager;
import me.winter.trapgame.client.SimpleLayout;
import me.winter.trapgame.server.TrapGameServer;
import me.winter.trapgame.util.ColorTransformer;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>A pane displayed when clicked the button "How to play" in the menu</p>
*
* <p>Created by Alexander Winter on 2016-04-20.</p>
*/
public class TutorialPane extends JPanel
{
private TrapGameMenu menu;
public TutorialPane(TrapGameMenu menu)
{
try
{
this.menu = menu;
JTextPane textPane = new JTextPane()
{
@Override
public void paint(Graphics graphics)
{
Graphics2D g2draw = (Graphics2D)graphics;
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.drawImage(menu.getClient().getResourceManager().getImage("background"), -TutorialPane.this.getX() - getX(), -TutorialPane.this.getY() - getY(), menu.getClient().getWidth(), menu.getClient().getHeight(), null);
g2draw.setColor(new Color(0, 0, 0, 20));
g2draw.fillRoundRect(0, 0, getWidth(), getHeight(), getWidth() / 8, getHeight() / 8);
super.paint(graphics);
}
};
setBackground(ColorTransformer.TRANSPARENT);
textPane.setBackground(ColorTransformer.TRANSPARENT);
textPane.setContentType("text/html");
textPane.setEditable(false);
ResourceManager res = menu.getClient().getResourceManager();
String page = res.getText("tutorial-page-" + menu.getClient().getLang().getName());
page = page.replace("<!--style-->", res.getText("tutorial-style"));
textPane.setText(page);
Pattern regex = Pattern.compile("<!--([^<>]+)-->");
Matcher matcher = regex.matcher(page);
while(matcher.find() && !matcher.hitEnd())
{
Image image;
switch(matcher.group(1).toLowerCase())
{
case "blank_button":
image = res.getImage("game-button");
break;
case "color_button":
BufferedImage button = (BufferedImage)res.getImage("game-button");
image = new BufferedImage(button.getWidth(), button.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2draw = ((BufferedImage)image).createGraphics();
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.setColor(new ColorTransformer(TrapGameServer.COLORS[0], 200));
g2draw.fillRoundRect(0, 0, button.getWidth(), button.getHeight(), button.getWidth() / 4, button.getHeight() / 4);
g2draw.drawImage(button, 0, 0, button.getWidth(), button.getHeight(), null);
g2draw.dispose();
break;
default:
image = null;
}
textPane.setCaretPosition(matcher.start());
if(image != null)
textPane.insertComponent(new JLabel(new ImageIcon(image)));
}
setLayout(new SimpleLayout());
add(textPane, SimpleLayout.constraints(8, 9, 0.25, 0.75, 7.5, 7.5));
revalidate();
repaint();
}
catch(Throwable debug)
{
debug.printStackTrace(System.out);
}
}
@Override
public void paint(Graphics graphics)
{
Graphics2D g2draw = (Graphics2D) graphics;
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.drawImage(menu.getClient().getResourceManager().getImage("background"), -getX(), 0, menu.getClient().getWidth(), menu.getClient().getHeight(), null);
super.paint(graphics);
}
}
提前感谢您的回答。
The problem is I can't place the caret position to the index of the html tag because the caret position is expecting a user-interface caret.
int offset = textpane.modelToView(modelOffset);
textPane.setCaretPosition( offset );
我认为这不是最好的方法。我会使用带有 ID 的元素作为占位符。然后,我将使用 HtmlDocument.getElement 获取占位符元素,然后使用 Element.getElementStart 获取 "user interface" 位置。
我有一个 JTextPane,其中 html 内容是我从文件中加载的。一些评论标签是占位符,我想在它们之前插入组件。我正在使用正则表达式匹配器查找这些标签,我可以使用 matcher.start() 获取这些标签的索引。问题是我无法将插入符号位置放置到 html 标记的索引中,因为插入符号位置需要用户界面插入符号。标签将被忽略,图像仅计入一个插入符号。所以我需要一种在指定索引处插入组件的方法。
这是我的代码。
package me.winter.trapgame.client.menu;
import me.winter.trapgame.client.ResourceManager;
import me.winter.trapgame.client.SimpleLayout;
import me.winter.trapgame.server.TrapGameServer;
import me.winter.trapgame.util.ColorTransformer;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>A pane displayed when clicked the button "How to play" in the menu</p>
*
* <p>Created by Alexander Winter on 2016-04-20.</p>
*/
public class TutorialPane extends JPanel
{
private TrapGameMenu menu;
public TutorialPane(TrapGameMenu menu)
{
try
{
this.menu = menu;
JTextPane textPane = new JTextPane()
{
@Override
public void paint(Graphics graphics)
{
Graphics2D g2draw = (Graphics2D)graphics;
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.drawImage(menu.getClient().getResourceManager().getImage("background"), -TutorialPane.this.getX() - getX(), -TutorialPane.this.getY() - getY(), menu.getClient().getWidth(), menu.getClient().getHeight(), null);
g2draw.setColor(new Color(0, 0, 0, 20));
g2draw.fillRoundRect(0, 0, getWidth(), getHeight(), getWidth() / 8, getHeight() / 8);
super.paint(graphics);
}
};
setBackground(ColorTransformer.TRANSPARENT);
textPane.setBackground(ColorTransformer.TRANSPARENT);
textPane.setContentType("text/html");
textPane.setEditable(false);
ResourceManager res = menu.getClient().getResourceManager();
String page = res.getText("tutorial-page-" + menu.getClient().getLang().getName());
page = page.replace("<!--style-->", res.getText("tutorial-style"));
textPane.setText(page);
Pattern regex = Pattern.compile("<!--([^<>]+)-->");
Matcher matcher = regex.matcher(page);
while(matcher.find() && !matcher.hitEnd())
{
Image image;
switch(matcher.group(1).toLowerCase())
{
case "blank_button":
image = res.getImage("game-button");
break;
case "color_button":
BufferedImage button = (BufferedImage)res.getImage("game-button");
image = new BufferedImage(button.getWidth(), button.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2draw = ((BufferedImage)image).createGraphics();
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.setColor(new ColorTransformer(TrapGameServer.COLORS[0], 200));
g2draw.fillRoundRect(0, 0, button.getWidth(), button.getHeight(), button.getWidth() / 4, button.getHeight() / 4);
g2draw.drawImage(button, 0, 0, button.getWidth(), button.getHeight(), null);
g2draw.dispose();
break;
default:
image = null;
}
textPane.setCaretPosition(matcher.start());
if(image != null)
textPane.insertComponent(new JLabel(new ImageIcon(image)));
}
setLayout(new SimpleLayout());
add(textPane, SimpleLayout.constraints(8, 9, 0.25, 0.75, 7.5, 7.5));
revalidate();
repaint();
}
catch(Throwable debug)
{
debug.printStackTrace(System.out);
}
}
@Override
public void paint(Graphics graphics)
{
Graphics2D g2draw = (Graphics2D) graphics;
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2draw.drawImage(menu.getClient().getResourceManager().getImage("background"), -getX(), 0, menu.getClient().getWidth(), menu.getClient().getHeight(), null);
super.paint(graphics);
}
}
提前感谢您的回答。
The problem is I can't place the caret position to the index of the html tag because the caret position is expecting a user-interface caret.
int offset = textpane.modelToView(modelOffset);
textPane.setCaretPosition( offset );
我认为这不是最好的方法。我会使用带有 ID 的元素作为占位符。然后,我将使用 HtmlDocument.getElement 获取占位符元素,然后使用 Element.getElementStart 获取 "user interface" 位置。