2009-01-19 29 views
1

如何創建一個既有風格又有自定義字體的Java/Swing文本組件?我想用紅色突出顯示文本的一小部分,但同時使用自定義(通過Font.createFont嵌入)字體。 JLabel接受HTML文本,該文本允許我突出顯示部分文本,但在渲染HTML時會忽略字體設置。其他文本組件(如JTextArea)將使用自定義字體,但不會呈現HTML。兩種方法最簡單的方法是什麼?如何創建既風格化又具有自定義字體的Java/Swing文本組件?

這裏是不成功使用的JTextPane的例子:

JTextPane textPane = new JTextPane(); 
    textPane.setFont(myCustomFont); 
    textPane.setText(text); 
    MutableAttributeSet attributes = new SimpleAttributeSet(); 
    StyleConstants.setForeground(attributes, Color.RED); 
    textPane.getStyledDocument().setCharacterAttributes(
     text.indexOf(toHighlight), 
     toHighlight.length(), 
     attributes, true 
    ); 

這成功地顯示與「toHighlight」部分文字以紅色突出顯示,但它不使用myCustomFont。請注意,我可以使用StyleConstants.setFontFamily()設置字符串字體,但不能使用自定義字體。

回答

2

好的,我現在看到問題更好了。

在檢查了一些Swing源代碼之後,很明顯你不能使用DefaultStyledDocument,並讓它使用一個物理字體(你自己創建的一個爲createFont)開箱即用。

不過,我覺得你可以做的是實現自己的StyleContext這樣:

public class MyStyleContext extends javax.swing.text.StyleContext 
{ 
    @Override public Font getFont(AttributeSet attr) 
    { 
     Font font = attr.getAttribute("MyFont"); 
     if (font != null) 
      return font; 
     else 
      return super.getFont(attr); 
    } 
} 

,那麼你必須:

  1. 創建 一個new MyStyleContext()
  2. 一個DefaultStyledDocument「附加「它到JTextPane
  3. 請致電attributes.addAttribute("MyFont", myCustomFont);我n您的片段以上

我沒有嘗試,但我認爲它應該工作,否則它可能是一個很好的調查路徑。

0

您應該嘗試使用JEditorPane或JTextPane代替。

它們允許在更復雜的API的價格內豐富的風格。 不幸的是,如果你在尋找一個pixel-prefect的用戶界面,他們也有一個額外的問題:他們不支持基線對齊(Java 6功能)。

+0

我已經嘗試了這兩個,但仍然有同樣的問題。如果我使用StyledDocument,它會忽略任何字體設置,並堅持使用「FontFamily」設置字體,該字體只允許字符串 - 而不是自定義字體。 – Ross 2009-01-19 07:22:38

+0

您能否顯示一個代碼片斷,顯示您使用StyledDocument完成的操作,但這不起作用? – jfpoilpret 2009-01-19 07:30:18

2

jfpoilpret的解決方案工作完美!爲了後代的緣故,這裏有一個工作代碼片段:

JTextPane textPane = new JTextPane(); 
    textPane.setStyledDocument(new DefaultStyledDocument(new StyleContext() { 
     @Override 
     public Font getFont(AttributeSet attr) { 
      return myCustomFont; 
     } 
    })); 
    textPane.setText(text); 
    MutableAttributeSet attributes = new SimpleAttributeSet(); 
    StyleConstants.setForeground(attributes, Color.RED); 
    textPane.getStyledDocument().setCharacterAttributes(
     text.indexOf(toHighlight), 
     toHighlight.length(), 
     attributes, true 
    ); 

謝謝,jfpoilpret!

0

我在Clojure編寫程序時遇到了同樣的問題,使用顯示HTML文本的JEditorPane中從TTF加載的字體。這裏的解決方案合作沒事 - 我在這裏複製有趣的部分以供將來參考:

(def font1 (with-open [s (FileInputStream. "SomeFont.ttf")] 
      (.deriveFont (Font/createFont Font/TRUETYPE_FONT s) (float 14)))) 
(def font2 (Font. "SansSerif") Font/PLAIN 14) 
(let [editor (JEditorPane. "text/html" "")] 
    (.setDocument editor 
       (proxy [HTMLDocument] [] 
        (getFont [attr] 
        (if (= (.getAttribute attr StyleConstants/FontFamily) 
          "MyFont") 
         font1 
         font2))))) 

這假定HTML文檔是指FONT-FAMILY「MyFont」,例如用CSS網頁摘要

p { font-family: "MyFont" } 

請注意,這個你必須處理所有字體請求。這是因爲的限制,代理無法調用超類的成員函數。另外,如果你想處理不同的字體大小,你必須「手動」,檢查StyleConstants/FontSize屬性並相應地用deriveFont創建一個字體。

我希望這會有助於某人:)

相關問題