2011-10-15 17 views
7

Tôi đang cố gắng để tạo ra một số thành phần đặc biệt cho một mục đích cụ thể, trên thành phần mà tôi cần phải rút ra một chuỗi HTML, đây là một mẫu mã: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); 
    } 
} 

Thật không may là phương pháp drawString có vẻ là không nhận ra định dạng HTML, nó ngu xuẩn vẽ chuỗi giống như nó.

Có cách nào để thực hiện công việc đó không?

+3

Tại sao bạn không sử dụng JLabel? Nó hỗ trợ thẻ HTML. –

+0

Thành phần của tôi không chỉ vẽ một chuỗi html, có rất nhiều thao tác vẽ khác mà tôi không muốn hiển thị trong mã mẫu chỉ để tập trung vào vấn đề thực sự. –

+0

'Đặc biệt' như thế nào? 'Cụ thể' cái gì? Câu trả lời cho câu hỏi này sẽ gợi ý bạn nên đưa thêm chi tiết, thay vì ít hơn. –

Trả lời

5

Tôi đã tìm thấy một đoạn ngắn và là một cách sạch để mô phỏng các paintHtmlString; đây là mã:

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

Cảm ơn mọi người đã trợ giúp, tôi đánh giá cao điều đó rất nhiều.

+0

+1 để theo dõi. – trashgod

+0

+1 tốt đẹp, không bao giờ biết nó có thể được thực hiện theo cách này :-) –

4

Sử dụng JLabel làm lớp cơ sở của bạn. Graphics.drawString() chỉ có thể ... vẽ một chuỗi.

+0

Thành phần của tôi không chỉ vẽ một chuỗi html, có rất nhiều thao tác vẽ khác mà tôi không muốn hiển thị trong mã mẫu chỉ để tập trung vào vấn đề thực sự. Tôi biết rằng JLabel và tất cả các thành phần Swing khác đang giữ văn bản hỗ trợ định dạng html.
Im chỉ tự hỏi liệu có cách nào để hiển thị văn bản html thông qua một cá thể Đồ họa hay không. –

+0

Cảm ơn bạn đã trả lời hữu ích. –

6

Câu trả lời cho câu hỏi của bạn là HTML không được hỗ trợ.

Giải pháp dễ dàng là sử dụng các thành phần Swing và đặt chúng ra đúng cách.

Nếu bạn muốn tự làm điều đó thì bạn cần thao tác Phông chữ mà bạn sử dụng cho phương thức drawString(). Bạn có thể sử dụng Phông chữ in nghiêng, in đậm, v.v.

+0

Cảm ơn bạn rất nhiều vì câu trả lời, nó giúp tôi suy nghĩ đúng đắn. –

5

Đây không phải là cách để triển khai.

drawString(String str, int x, int y) chỉ vẽ văn bản được cung cấp bởi chuỗi được chỉ định, sử dụng phông chữ và màu sắc hiện tại của ngữ cảnh đồ họa này.

Bạn có thể tìm thêm thông tin cho vấn đề của mình từ đây, How to Use HTML in Swing Components

+0

cảm ơn bạn đã trả lời, nó đã giúp tôi đi đúng hướng. –

2

Có không phải là một cách dễ dàng để làm cho HTML để vẽ với đồ họa, đi với một JLabel.

Tuy nhiên, có một cách thú vị để thực hiện điều này bằng cách tạo ra một JLabel với HTML và vẽ nó chính là đồ họa với thành phần:

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

Cách dễ nhất để thực hiện điều này sẽ được thiết lập một phông chữ cho đồ họa của bạn , ví dụ:

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

Như những người khác đã nhận xét, các thành phần Swing hỗ trợ HTML 3.2 và kiểu cơ bản.

Để biết chi tiết về cách tận dụng khả năng đó trong phương pháp paintComponent(Graphics), hãy xem nguồn LabelRenderTest.java trên this thread.

Cách tiếp cận là để render nhãn cho một hình ảnh, sau đó render hình ảnh đến đối tượng Graphics.

+0

Tôi đã tìm ra cách để vẽ htmlString bằng cách sử dụng JLabel nhưng không cần phải hiển thị hình ảnh (hãy xem bài đăng của tôi). Cảm ơn bạn rất nhiều vì sự giúp đỡ. –

10

Nếu quạt của Java2D; nhưng để tận dụng tối đa HTML từ các thành phần và bố cục Swing, tôi khuyến khích bạn sử dụng cách tiếp cận thành phần được gợi ý bởi @camickr. Nếu cần, bạn có thể sử dụng trọng lượng bay renderer approach được thấy trong JTable, et al, trong đó một thành phần được sử dụng nhiều lần để vẽ. Ví dụ dưới đây là rất phác thảo đơn giản của kỹ thuật, chỉ thay đổi màu sắc và vị trí.

Phụ lục: Ví dụ đã cập nhật; xem thêm 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

cảm ơn bạn rất nhiều vì đã giúp đỡ. Tôi đã tìm ra cách khác để làm điều này mà không cần CellRendererPane. (Hãy xem bài trả lời của tôi). –

+1

Bạn được chào đón. ['CellRendererPane'] (http://download.oracle.com/javase/7/docs/api/javax/swing/CellRendererPane.html) cung cấp một vài tối ưu hóa thuận tiện cho việc đệm và xác nhận hợp lệ mà vẫn có thể hữu ích cho tương lai. – trashgod

+1

Tôi sẽ ghi nhớ điều đó, cảm ơn một lần nữa vì thông tin. –