2013-11-01 20 views
3

我有一個JTextPane,其型號爲DefaultStyledDocument。我注意到,如果顯示文本,然後我使用setCharacterAttributes將一行上的每個字符更改爲更大的字體,那麼該行上的字符的字體會按照我的預期在顯示中更改,但下面的行它不會移動,以便顯示中的線條重疊。如何在一行更改爲較大字體時重繪JTextPane

是否有辦法強制JTextPane重新計算文本位置並重新顯示自身(或其本身的一部分)?我試圖設置一個DocumentListenerchangedUpdate,和changedUpdate確實被稱爲,但我找不到一種方法,使其重繪JTextPanerevalidate()沒有工作。

編輯:這些行自己移動一個較小的測試用例,所以顯然我在程序中做的其他事情是干涉,但我還沒有弄清楚什麼。無論如何,repaint()沒有revalidate()工程,如果我不能確定哪些功能導致問題以及如何解決它。

編輯2:將JTextPane添加到JPanel並將JPanel設置爲BoxLayoutBoxLayout.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

不知道沒有SSCCE – mKorbel

+0

我根本無法重現您的問題 – Sage

+0

既然我正在嘗試創建一個小例子,我也無法重現該問題。我的更大的例子使用'DefaultStyledDocument'和其他各種東西的子類;我不確定他們中的哪一個導致了問題。要弄清楚這一點需要一些研究。 – ajb

回答

0

致電repaint()它將重繪容器。 DocumentListener反映對文本文檔的更改,因此在您的情況下不合適。您可以使用DefaultStyledDocument.getStyle().addChangeListener()來處理屬性的更改。

+0

好的,謝謝。有趣的是,在我嘗試'revalidate()'之後,我添加了'repaint()',以便它調用'revalidate',後面跟着'repaint',但那不起作用。但是,在沒有'revalidate'的情況下調用'repaint'確實有效。我沒有使用'樣式',所以你的其他建議沒有幫助,無論如何,爲了我的目的,我希望能夠改變任何我想改變的字符的字體,而不僅僅是一個特定的'樣式' 。 – ajb

+0

如果你沒有使用樣式,那麼你所做的改變隻影響容器,唯一的辦法是讓它重繪自己而不是特定的組件。 – 2013-11-01 19:48:17

+0

我不認爲這是真的。正如我在我的問題中所說的,字體變化**在視圖中反映出來;問題是它下面的行是否被移位。我已經找到更多信息並將編輯該問題。它與'Style'無關。 – ajb

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); 
     ....... 

這是稍有最好包裝一JScrollPaneJTextPane的解決方案,因爲後者顯示了一些額外的即使沒有滾動條顯示,也可以使用邊界附近的線條。