我有JTextPane
,其模型为DefaultStyledDocument
。我注意到如果显示文本,然后我使用setCharacterAttributes
将一行中的每个字符更改为更大的字体,那么该行上字符的字体会在我期望的显示中更改,但它下方的线条不会移动,因此线条在显示屏上重叠。
有没有办法强制JTextPane
重新计算文本位置并重新显示自身(或其自身的一部分)?我尝试使用DocumentListener
设置changedUpdate
,确实调用了changedUpdate
,但我无法找到重绘JTextPane
的方法。 revalidate()
没有用。
编辑:这些线路确实随着一个较小的测试用例自行移动,所以显然我在程序中正在做的其他事情是干扰,但我还没弄清楚是什么。无论如何,如果我无法确定导致问题的功能以及如何绕过它,repaint()
没有revalidate()
就可以正常工作。
编辑2:当JTextPane添加到JPanel并且JPanel设置为BoxLayout
和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);
}
}
答案 0 :(得分:0)
调用repaint()
它将重绘容器。 DocumentListener
反映了对文本文档的更改,因此在您的情况下是不合适的。您可以使用DefaultStyledDocument.getStyle().addChangeListener()
来处理属性的更改。
答案 1 :(得分: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
包裹在JScrollPane
内的解决方案略胜一筹,因为即使没有显示滚动条,后者也会在边框附近显示一些额外的行。