3

我有一个JTextPane其型号为DefaultStyledDocument. 我注意到,如果显示文本,然后我将setCharacterAttributes一行上的每个字符更改为更大的字体,则该行上字符的字体在显示中会按照我的预期进行更改,但它下面的行不要移动,以使线条在显示中重叠。

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

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

编辑 2:当 JTextPane 添加到 JPanel 并且 JPanel 设置为BoxLayoutand时,会出现问题BoxLayout.X_AXIS。一个样品:

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);
    }
}
4

2 回答 2

0

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

于 2013-11-01T18:07:50.053 回答
0

我刚刚发现它也可以添加对以下的setMinimumSize调用JTextPane

        .......
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
            // problem goes away if above line is removed
        panel.add(textPane);
        textPane.setMinimumSize(new Dimension(1000, 500));  // NEW
        // These also work:
        // textPane.setMinimumSize(new Dimension(1, 1));   or
        // textPane.setMinimumSize(new Dimension(0, 0));
        panel.setPreferredSize(new Dimension(1000, 500));
        textPane.setCaretPosition(0);
        .......

JTextPane这比包裹内部 a的解决方案稍微好一点JScrollPane,因为后者即使在没有显示滚动条的情况下也会在边框附近显示一些额外的行。

于 2013-11-04T01:50:16.880 回答