2011-10-15 141 views
7

我試圖創建一個特定的目的,一些特殊的組件,該組件我需要畫一個HTML串上,這裏是一個示例代碼:搖擺HTML drawString之

public class MyComponent extends JComponent{ 
    public MyComponent(){ 
     super(); 
    } 

    protected void paintComponent(Graphics g){ 
     //some drawing operations... 
     g.drawString("<html><u>text to render</u></html>",10,10); 
    } 
} 

不幸的拉繩方法似乎是不認識HTML格式,它愚蠢地繪製字符串就像它。

有什麼辦法可以做到這一點嗎?

+3

爲什麼不使用JLabel?它支持HTML標籤。 –

+0

我的組件不只是繪製一個html字符串,還有很多其他的繪圖操作,我不想在示例代碼中顯示,只關注真正的問題。 –

+0

'特'如何? '具體'是什麼?這個問題的答案表明,包含更多細節而不是更少是個好主意。 –

回答

5

我已經找到了一個短和清潔的方式來模擬paintHtmlString;這裏是代碼:

public class MyComponent extends JComponent { 

    private JLabel label = null; 

    public MyComponent() { 
     super(); 
    } 

    private JLabel getLabel() { 
     if (label == null) { 
      label = new JLabel(); 
     } 
     return label; 
    } 

    /** 
    * x and y stand for the upper left corner of the label 
    * and not for the baseline coordinates ... 
    */ 
    private void paintHtmlString(Graphics g, String html, int x, int y) { 
     g.translate(x, y); 
     getLabel().setText(html); 
     //the fontMetrics stringWidth and height can be replaced by 
     //getLabel().getPreferredSize() if needed 
     getLabel().paint(g); 
     g.translate(-x, -y); 
    } 

    protected void paintComponent(Graphics g) { 
     //some drawing operations... 
     paintHtmlString(g, "<html><u>some text</u></html>", 10, 10); 
    } 
} 

感謝每一個人的幫助,我非常感激,非常。

+0

+1進行跟蹤。 – trashgod

+0

+1不錯,從來不知道可以這樣做:-) –

4

使用JLabel作爲您的基類。 Graphics.drawString()只能畫一個字符串。

+0

我的組件不只是繪製一個html字符串,還有很多其他的繪圖操作,我不想在示例代碼中顯示,只關注真正的問題。我知道JLabel和其他所有支持文本的Swing組件都支持html格式。
我只是想知道是否有任何方式通過圖形實例呈現HTML文本。 –

+0

謝謝你的有用答案。 –

6

您的問題的答案是不支持HTML。

簡單的解決方案是使用Swing組件並正確佈置它們。

如果你想自己做,那麼你需要操縱用於drawString()方法的字體。您可以使用斜體,粗體等字體。

+0

非常感謝您的回答,它幫助我以正確的方式思考。 –

5

這不是實施的方式。

drawString(String str, int x, int y)僅使用此圖形上下文的當前字體和顏色繪製由指定字符串給出的文本。

,您可以得到更多的信息,你的問題在這裏,How to Use HTML in Swing Components

+0

謝謝你的回答,它幫助我以正確的方式前進。 –

2

沒有渲染HTML與圖形繪製,去與一個JLabel一個簡單的方法。

但是,通過HTML創建一個JLabel和畫它的圖形組件來完成這一個有趣的方式:

private JLabel label; 

public MyComponent() { 
    label = new JLabel("Before Red"); 
    label.setText("<html><u>test</u></html>"); 
    this.add(label); 
} 

public void repaint(Graphics g){ 
    g = label.getGraphics(); 
} 

來完成,這將是爲您的圖形字體的最簡單方法,例如:

public void repaint(Graphics g){  
    Font f = new Font("Courier", Font.BOLD, 12); 
    g.setFont(f); 
    g.drawString("Bolded Courier", 5, 15); 
} 
9

正如其他人所評論的,Swing組件支持HTML 3.2和基本樣式。

有關如何在paintComponent(Graphics)方法中利用該功能的詳細信息,請參見this thread上的LabelRenderTest.java源。

的方法是將標籤渲染的圖像,然後將圖像呈現到Graphics對象。

+0

我已經找到了一種使用JLabel繪製htmlString的方法,但不需要渲染圖像(看看我的文章)。非常感謝你的幫助。 –

10

如果是Java2D的粉絲;但爲了充分利用Swing組件和佈局中的HTML,我鼓勵您使用@camickr建議的組件方法。如有必要,您可以使用在JTable,中看到的輕量級renderer approach,其中單個組件重複用於繪圖。下面的示例是非常簡單的輪廓技術,只更改顏色和位置。

附錄:更新示例;另請參閱CellRendererPaneMake your apps fly: Implement Flyweight to improve performance

enter image description here

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import javax.swing.CellRendererPane; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

/** @see http://stackoverflow.com/questions/7774960 */ 
public class PaintComponentTest extends JPanel { 

    private static final int N = 8; 
    private static final String s = "<html><big><u>Hello</u></html>"; 
    private JLabel renderer = new JLabel(s); 
    private CellRendererPane crp = new CellRendererPane(); 
    private Dimension dim; 

    public PaintComponentTest() { 
     this.setBackground(Color.black); 
     dim = renderer.getPreferredSize(); 
     this.add(crp); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (int i = 0; i < N; i++) { 
      renderer.setForeground(Color.getHSBColor((float) i/N, 1, 1)); 
      crp.paintComponent(g, renderer, this, 
       i * dim.width, i * dim.height, dim.width, dim.height); 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("PaintComponentTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setSize(dim.width * N, dim.height * (N + 1)); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new PaintComponentTest().display(); 
      } 
     }); 
    } 
} 
+0

非常感謝您的幫助。我發現了另一種不需要CellRendererPane的方法。 (看看我的答案)。 –

+1

不客氣。 ['CellRendererPane'](http://download.oracle.com/javase/7/docs/api/javax/swing/CellRendererPane.html)爲緩衝和驗證提供了一些方便的優化,這些優化可能對未來有用。 – trashgod

+1

我會記住這一點,再次感謝您的信息。 –