2011-10-15 13 views
7

Sto cercando di creare qualche componente speciale per uno scopo specifico, su quella componente ho bisogno di disegnare una stringa HTML, ecco un esempio di codice:swing 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); 
    } 
} 

Purtroppo il metodo drawString sembra essere non riconoscendo il formato HTML, scioccamente disegna la stringa così com'è.

C'è un modo per farlo funzionare?

+3

Perché non usi JLabel? Supporta tag HTML. –

+0

Il mio componente non si limita a disegnare una stringa html, ci sono un sacco di altre operazioni di disegno che non volevo mostrare nel codice di esempio solo per concentrarsi sul problema reale. –

+0

'Speciale' come? 'Specificamente' cosa? Le risposte a questa domanda suggerirebbero che è una buona idea includere più dettagli, piuttosto che meno. –

risposta

5

Ho trovato un corto e un modo pulito per simulare il paintHtmlString; ecco il codice:

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

Grazie a tutti per l'aiuto, io apprezzo molto.

+0

+1 per il follow-up. – trashgod

+0

+1 bello, non ho mai saputo che si potesse fare in questo modo :-) –

4

Utilizzare JLabel come classe base. Graphics.drawString() può solo ... disegnare una stringa.

+0

Il mio componente non si limita a disegnare una stringa html, ci sono un sacco di altre operazioni di disegno che non volevo mostrare nel codice di esempio solo per concentrarsi sul vero problema. So che JLabel e tutti gli altri componenti di Swing che contengono testo supportano il formato html.
Mi stavo solo chiedendo se c'è un modo per rendere i testi html attraverso un'istanza Graphics. –

+0

Grazie per la risposta utile. –

6

La risposta alla tua domanda è che HTML non è supportato.

La soluzione facile è utilizzare i componenti Swing e disporli correttamente.

Se si desidera eseguire da soli, è necessario modificare il Font che si utilizza per il metodo drawString(). È possibile utilizzare un carattere con corsivo, grassetto, ecc.

+0

Grazie mille per la risposta, mi ha aiutato a pensare nel modo giusto. –

5

Questo non è il modo di implementare.

Il drawString(String str, int x, int y) disegna solo il testo fornito dalla stringa specificata, utilizzando il carattere e il colore correnti di questo contesto grafico.

È possibile ottenere ulteriori informazioni per il vostro problema da qui, How to Use HTML in Swing Components

+0

grazie per la risposta, mi ha aiutato ad andare nel modo giusto. –

2

Non c'è un modo semplice per il rendering HTML per dipingere con la grafica, andare con un JLabel.

Tuttavia, v'è un modo interessante per raggiungere questo obiettivo creando un JLabel con HTML e la pittura è la grafica al componente:

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(); 
} 

Il modo più semplice per raggiungere questo obiettivo sarebbe quello di impostare un tipo di carattere per la grafica , ad esempio:

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

Come altri hanno commentato, i componenti Swing supportano HTML 3.2 e stili di base.

Per i dettagli su come sfruttare tale capacità nel metodo paintComponent(Graphics), vedere l'origine LabelRenderTest.java su this thread.

L'approccio è quello di rendere l'etichetta a un'immagine, quindi rendere l'immagine all'oggetto Graphics.

+0

Ho scoperto un modo per dipingere htmlString usando JLabel ma senza la necessità di eseguire il rendering di un'immagine (dai un'occhiata al mio post). Grazie mille per l'aiuto. –

10

Se un fan di Java2D; ma per sfruttare al massimo l'HTML nei componenti e nei layout di Swing, ti suggerisco di utilizzare l'approccio componente suggerito da @camickr. Se necessario, è possibile utilizzare il peso vivo renderer approach visto in JTable, e altri, in cui un singolo componente viene utilizzato ripetutamente per il disegno. L'esempio che segue è uno molto schema semplificato della tecnica, che modifica solo il colore e la posizione.

Addendum: esempio aggiornato; vedere anche CellRendererPane e Make 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

grazie mille per l'aiuto. Ho scoperto un altro modo per farlo senza aver bisogno di CellRendererPane. (Dai un'occhiata al mio post di risposta). –

+1

Prego. ['CellRendererPane'] (http://download.oracle.com/javase/7/docs/api/javax/swing/CellRendererPane.html) offre alcune ottimizzazioni utili per il buffering e la validazione che potrebbero rivelarsi utili in futuro. – trashgod

+1

Lo terrò a mente, grazie ancora per l'informazione. –