Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swing HTML drawString

I'm trying to create some special component for a specific purpose, on that component I need to draw a HTML string, here's a sample code:

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

Unfortunately the drawString method seems to be not recognizing the HTML format, it foolishly draws the string just as it is.

Is there any way to make that work?

like image 269
George Casttrey Avatar asked Oct 15 '11 00:10

George Casttrey


People also ask

How to use HTML in Swing?

To specify that a component's text has HTML formatting, just put the <html> tag at the beginning of the text, then use any valid HTML in the remainder. Here is an example of using HTML in a button's text: button = new JButton("<html><b><u>T</u>wo</b><br>lines</html>"); Here is the resulting button.

Can I use HTML with Java?

Rich clients in Java are done using Swing or SWT. If you want to use HTML/CSS for your user interface, you need to use the server/client model. It can be as simple as creating a local server and launching a browser that connects to it, but it would still be that model.

What is JEditorPane in Java?

public class JEditorPane extends JTextComponent. A text component to edit various kinds of content. You can find how-to information and examples of using editor panes in Using Text Components, a section in The Java Tutorial. This component uses implementations of the EditorKit to accomplish its behavior.


7 Answers

If a fan of Java2D; but to get the most leverage from HTML in Swing components and layouts, I'd encourage you to use the component approach suggested by @camickr. If necessary, you can use the flyweight renderer approach seen in JTable, et al, in which a single component is used repeatedly for drawing. The example below is a very simplified outline of the technique, changing only the color and location.

Addendum: Updated example; see also CellRendererPane and 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();
            }
        });
    }
}
like image 197
trashgod Avatar answered Oct 04 '22 07:10

trashgod


As others have commented, Swing components support HTML 3.2 and basic styles.

For details on how to leverage that ability in the paintComponent(Graphics) method, see the LabelRenderTest.java source on this thread.

The approach is to render the label to an image, then render the image to the Graphics object.

like image 43
Andrew Thompson Avatar answered Oct 04 '22 08:10

Andrew Thompson


The answer to your question is that HTML is not supported.

The easy solution is to use Swing components and lay them out properly.

If you want to do it yourself then you need to manipulate the Font that you use for the drawString() method. You can use a Font with italics, bold etc.

like image 41
camickr Avatar answered Oct 04 '22 08:10

camickr


I've found a short and a clean way to simulate the paintHtmlString; here's the code:

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

Thanks to every one for the help, I do appreciate that very much.

like image 39
George Casttrey Avatar answered Oct 04 '22 08:10

George Casttrey


This is not the way to implement.

The drawString(String str, int x, int y) only draws the text given by the specified string, using this graphics context's current font and color.

You can get more information for your problem from here, How to Use HTML in Swing Components

like image 33
COD3BOY Avatar answered Oct 04 '22 09:10

COD3BOY


Use JLabel as your base class. Graphics.drawString() can only... draw a string.

like image 33
Michał Šrajer Avatar answered Oct 04 '22 07:10

Michał Šrajer


There isn't an easy way to render HTML to paint with Graphics, go with a JLabel.

However, there is an interesting way to accomplish this by creating a JLabel with HTML and painting it's graphics to the component:

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

The easiest way to accomplish this would be to set a font for your graphics, for example:

public void repaint(Graphics g){    
    Font f = new Font("Courier", Font.BOLD, 12);
    g.setFont(f);
    g.drawString("Bolded Courier", 5, 15);
}
like image 40
jpalm Avatar answered Oct 04 '22 09:10

jpalm