3

我很抱歉没有更好的标题,但我不知道如何进一步指定错误,因为我不了解它的性质。当问题被理解时,也许有人可以编辑它。

我正在编写一个应用程序,用户可以在其中将图标添加到文本字段中。我显然选择了一个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);
    }

}

总结一下我的问题:

  1. 是什么导致图标后出现空格?

  2. 我在哪里添加repaint()orrevalidate()来解决图片 #2 中出现的问题?

PS:我知道,我的“图标”没有实现Icon,但它不应该是必要的,因为JTextPanes可以处理各种Components.

4

1 回答 1

2

1.是什么原因导致图标后出现空格?

好吧,您有以下代码:

this.setMinimumSize(getSize());

最大尺寸是多少?

如何解决图片 #2 中出现的问题?

自定义绘画是通过覆盖paintComponent() 方法而不是paint() 方法完成的,并且不要忘记调用super.paintComponent。

一个图标在这里会更合适,因为你所做的只是自定义绘画。甚至是 JComponent,但不是 JPanel,它是用于容纳其他组件的容器。另外,您使用的图标没有面板或 JComponent 的大小问题,因为该方法是作为界面的一部分专门实现的。

于 2013-03-25T22:02:27.647 回答