java - 当一行更改为较大字体时如何重绘 JTextPane

标签 java swing jtextpane

我有一个 JTextPane,其模型是 DefaultStyledDocument。我注意到,如果显示文本,然后使用 setCharacterAttributes 将一行上的每个字符更改为更大的字体,则该行上的字符的字体在显示中更改为我期望如此,但它下面的线条不会移动,因此这些线条在显示中重叠。

有没有办法强制JTextPane重新计算文本位置并重新显示自身(或自身的一部分)?我尝试使用 changedUpdate 设置一个 DocumentListener ,并且确实调用了 changedUpdate ,但我找不到一种方法让它重绘 JTextPanerevalidate() 不起作用。

编辑:这些行确实会在较小的测试用例中自行移动,所以显然我在程序中所做的其他事情正在干扰,但我还没有弄清楚是什么。无论如何,如果我无法确定哪个功能导致了问题以及如何解决它,则不使用 revalidate()repaint() 也可以工作。

编辑2:将 JTextPane 添加到 JPanel 并使用 BoxLayoutBoxLayout.X_AXIS 设置 JPanel 时会出现问题。示例:

public class Demo extends JFrame {
    JPanel panel;
    JTextPane textPane;
    DefaultStyledDocument doc;

    SimpleAttributeSet smallText, bigText;

    public Demo() {
        super("Demo");
        doc = new DefaultStyledDocument ();
        textPane = new JTextPane(doc);
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
            // problem goes away if above line is removed
        panel.add(textPane);
        panel.setPreferredSize(new Dimension(1000, 500));
        textPane.setCaretPosition(0);
        textPane.setMargin(new Insets(5,5,5,5));
        getContentPane().add(panel, BorderLayout.CENTER);

        smallText = new SimpleAttributeSet();
        StyleConstants.setFontFamily(smallText, "SansSerif");
        StyleConstants.setFontSize(smallText, 16);

        bigText = new SimpleAttributeSet();
        StyleConstants.setFontFamily(bigText, "Times New Roman");
        StyleConstants.setFontSize(bigText, 32);

        initDocument();
        textPane.setCaretPosition(0);
    }

    protected void initDocument() {
        String initString[] =
                { "This is the first line.",
                  "This is the second line.",
                  "This is the third line." };

        for (int i = 0; i < initString.length; i ++) {
            try {
                doc.insertString(doc.getLength(), initString[i] + "\n",
                        smallText);
            } catch (BadLocationException e) {
            }
        }
    }

    private void createAndShowGUI() throws InterruptedException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        new Demo().runMain();
    }

    private void runMain() throws Exception {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                UIManager.put("swing.boldMetal", Boolean.FALSE);
                try {
                    createAndShowGUI();
                } catch (InterruptedException e) {
                }
            }
        });
        Thread.sleep(2000);
        doc.setCharacterAttributes(24, 24, bigText, false);
    }
}

最佳答案

调用repaint()它将重绘容器。 DocumentListener 反射(reflect)对文本文档的更改,因此在您的情况下是不合适的。您可以使用 DefaultStyledDocument.getStyle().addChangeListener() 来处理属性的更改。

关于java - 当一行更改为较大字体时如何重绘 JTextPane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19732510/

相关文章:

java - 使用 Scanner 类解析文本文件并通过多个循环计数模式出现次数

java - 如何在pom.xml中设置部署存储库

java - 如何在数据库中保存样式文本并在 JEditor Pane 中检索相同样式的文本

java - 如何判断JTextPane中所选文本的大小是否不同?

java - 在jTextPane中显示doc文件的内容

java - JEdi​​torPane 显示带有 Google Docs 的原始 HTML

java - 我是否需要在实现 MessageListener 类的类的 onMessage 方法中关闭执行器?

java - 与 Mongo 的版本化对象/JSON 映射?

Java 单选按钮提交

java - Jdialog 在 IE9 中没有获得焦点