我很抱歉没有更好的标题,但我不知道如何进一步指定错误,因为我不了解它的性质。当问题被理解时,也许有人可以编辑它。
我正在编写一个应用程序,用户可以在其中将图标添加到文本字段中。我显然选择了一个JTextPane
来显示文本和图标。在玩了insertComponent()
这个类的功能后,我遇到了一些奇怪的布局问题,所以我决定在 oracle.com 上查找教程。在查看了示例的源代码后,我决定做同样的事情,并使用样式将组件添加到底层StyledDocument
. 当我开始第一次测试运行时,我发现布局问题保持不变。
那么,究竟发生了什么?
我希望文本窗格显示的是“abcOdefO”,但正如您从屏幕截图中看到的那样,这两个图标(圆圈)在它们的右侧有一些空间。我希望将图标视为稍大的字符,因此它应该只占用它需要的空间,而不是 (availableSpace / numberOfIcons),这似乎是它实际占用的空间。
在插入符号位置键入另一个字符时:
这更奇怪了。如果图标有MouseListeners
,则所有 4 个可见圆圈都会触发该事件。如果我将框架拖到另一个窗口或最小化并恢复它,奇怪的部分就会消失,框架看起来就像第一个图像(除了附加字符)。所以我想,我的这部分问题是通过repaint()
在正确的位置调用来解决的——但是在哪里呢?
这是生成上面看到的图像的代码:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class TextPaneTestPanel extends JPanel {
private class myIcon extends JPanel {
private final int side;
private final int padding = 1;
public myIcon(int size) {
this.side = size - 2 * padding;
this.setSize(size, size);
this.setPreferredSize(getSize());
this.setMinimumSize(getSize());
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.setStroke(new BasicStroke(2));
g2d.drawOval(padding, padding, side, side);
}
}
private final JTextPane textPane;
public TextPaneTestPanel() {
textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
StyleConstants.setFontFamily(def, "Monospaced");
Style regular = doc.addStyle("regular", def);
try {
doc.insertString(0, "abc", regular);
Style s1 = doc.addStyle("icon1", regular);
StyleConstants.setComponent(s1, new myIcon(20));
doc.insertString(3, " ", s1);
doc.insertString(4, "def", regular);
Style s2 = doc.addStyle("icon2", regular);
StyleConstants.setComponent(s2, new myIcon(20));
doc.insertString(7, " ", s2);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
this.setLayout(new GridBagLayout());
this.add(textPane, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(4, 4, 4, 4), 0, 0));
}
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
TextPaneTestPanel panel = new TextPaneTestPanel();
frame.getContentPane().add(panel);
frame.setSize(300, 100);
frame.setVisible(true);
}
}
总结一下我的问题:
是什么导致图标后出现空格?
我在哪里添加
repaint()
orrevalidate()
来解决图片 #2 中出现的问题?
PS:我知道,我的“图标”没有实现Icon
,但它不应该是必要的,因为JTextPanes
可以处理各种Components
.