2013-07-20 66 views
1

我試圖找到一種方法來更改JTextArea組件中的行距。在JTextArea(而不是JTextPane)中更改行距

有點搜索似乎總是顯示相同的答案:「改用JTextPane然後調用setParagraphAttributes」。

但我想知道是否有可能只通過一個JTextArea來實現這一點,例如,混亂的字體。

使用deriveFont(...)方法,可以更改字體的跟蹤和字距調整,即字符之間的水平間距,但我無法找到改變垂直間距(可能是上升,下降, 領導)。我在那裏錯過了什麼?

+1

需要1.所有的JTextPane方法添加到您自己的JTextArea,2.使用HTML和需要另外的技巧,力JTextArea中呈現HTML正確 – mKorbel

+1

'一直在尋找一點點似乎透露出了相同的答案:' - 究竟什麼是錯JTextPane中?你爲什麼試圖重新發明一個JTextArea? – camickr

+0

:)我期望這些評論...有時我只是對學習新東西感興趣,並想出可能的東西。這個'deriveFont(...)'函數有十億個選項,包括應用基於矩陣的幾何變換等等。我只是想知道是否可以用這個來做一些魔術。它的記錄很差,所以一些用例示例會很好。順便說一句:輕量級編碼有什麼問題?如果一個簡單的JTextArea可以做到這一點,爲什麼要使用完整的富文本JTextPane? –

回答

4

正如camickr指出的,JTextArea不提供直接更改線高度的方法。它只是使用相應的FontMetrics提供的字體高度。

但是,這留下使用下面的幫助級攻擊型開放點:

public class FontMetricsWrapper extends FontMetrics { 

    private final FontMetrics target; 

    public FontMetricsWrapper(FontMetrics target) { 
     super(target.getFont()); 
     this.target = target; 
    } 

    @Override 
    public int bytesWidth(byte[] data, int off, int len) { 
     return target.bytesWidth(data, off, len); 
    } 

    @Override 
    public int charWidth(char ch) { 
     return target.charWidth(ch); 
    } 

    @Override 
    public int charWidth(int codePoint) { 
     return target.charWidth(codePoint); 
    } 

    // ... tons more @Override's, all of the same form: 
    // 
    // @Override 
    // public baz foo(bar, ...) { 
    //  return target.foo(bar, ...); 
    // } 

} 

然後,就可以創建JTextArea中是這樣的:

JTextArea myTextArea = new JTextArea("Some text") { 
    @Override 
    public FontMetrics getFontMetrics(Font font) { 
     return new FontMetricsWrapper(super.getFontMetrics(font)) { 
      @Override 
      public int getHeight() { 
       return 10; // Gives line height in pixels 
      } 
     }; 
    } 
}; 

這絕對不是最乾淨的解決方案,僅僅是作爲概念證明。例如,一個問題是getFontMetrics(...)經常被調用,並且在給定示例中,每次都創建一個包裝類的新實例。所以,至少,爲每個給定的字體緩存創建的FontMetricsWrapper的HashMap將是...

但是,我真正希望的是一種玩Font的方法,或者可能將關聯的FontRenderContext傳遞到JTextArea來修改行高。例如,是否有某種方法可以影響字體報告的上升,下降和主導值?似乎很奇怪,你可以更改字體的外觀幾乎任何其他方面,除了這一個...

1

輕量級編碼有什麼問題?

什麼都沒有,你應該使用最簡單的工作組件。但是,如果簡單組件不支持需求,通常是因爲需求更復雜,並且需要更復雜的組件來實現功能。在設置一個類的屬性時很少會這麼簡單。

有時候我只是對學習新東西感興趣,並找出可能性。

Swing文本組件使用View來繪製文本。格式和文本的位置是視圖的責任。因此,每個視圖都會確定何時換行以及放置下一行的位置。

對於JTextArea,它使用Plainview或WrappedPlanView。對於普萊恩維尤的繪畫代碼是:

drawLine(line, g, x, y); 
y += fontHeight; 

其中fontHeight是通過使用FontMetrics.getHeight()方法確定的。

所以這個值基本上是在視圖中硬編碼的。您始終可以爲文本區域提供自定義視圖,但覆蓋視圖通常不是一件容易的事情。

+0

正確的...這就是爲什麼我希望的一種方式可能與給予的JTextArea而不是文本區的字體混亂。我找到了一種方法來做到這一點(參見我的答案),但可能會做得更好。 –

+0

順便說一句:這個小冒險教給我很多關於Swing的知識。我對Swing有點新,並不知道它有多複雜。有時候打開Pandora的盒子可能會很有趣,並且實際上可以潛入所有可以使所有工作正常的彈簧和齒輪。即使我從來沒有真正應該/需要與它的任何亂七八糟的,我還是喜歡學習的概念(這裏:組件,用戶界面,RenderContexts,訪問量,指標,...)。對於如何構造代碼並優雅地解決某些問題,通常會有一些聰明的想法,儘管在這種情況下,看起來像是一團糟......;) –