2009-05-15 42 views
95

Tôi đang cố gắng hiển thị chú giải công cụ trong Java có thể có hoặc không có chiều dài đoạn văn. Làm cách nào để tôi có thể chèn các chú giải dài từ?Chú giải công cụ nhiều dòng trong Java?

+0

Vui lòng cung cấp ví dụ về mã. –

+1

Các mẹo về công cụ không tự động bao bọc từ nếu chúng được gói trong các thẻ HTML? Tôi không chắc chắn, vì vậy tôi không đưa nó vào như một câu trả lời. –

+0

Paul: Chỉ khi bạn có ngắt dòng rõ ràng. –

Trả lời

135

Nếu bạn quấn chú giải công cụ trong các thẻ <html></html>, bạn có thể ngắt các dòng với <br> thẻ. Xem http://www.jguru.com/faq/view.jsp?EID=10653 để biết các ví dụ và thảo luận.

Hoặc bạn có thể sử dụng lớp JMultiLineToolTip có thể tìm thấy nhiều nơi trên mạng, bao gồm tooltips http://code.ohloh.net/search?s=jmultilinetooltip

+1

Tôi đã sử dụng lớp JMultiLineToolTip mà bạn đã đề xuất. Khi tôi đã sử dụng setFixedWidth() để giới hạn chú giải công cụ với kích thước hợp lý, nó hoạt động rất tốt. Cảm ơn! –

4

Sử dụng HTML và tự phá vỡ đường dây của bạn (một từ đơn giản tokenizer với chiều dài cố định nên làm điều đó) . Chỉ cần đảm bảo văn bản công cụ của bạn bắt đầu bằng "<HTML>". Ngắt dòng với "< BR/>" hoặc "<P>". Tôi nhận ra nó không phải là giải pháp sạch nhất và hỗ trợ HTML của Java là khủng khiếp, nhưng nó sẽ hoàn thành công việc.

23

Văn bản chú giải công cụ bắt đầu bằng "<html>" sẽ được coi là HTML. Tất nhiên đó có thể là HTML rất rộng.

Bạn có thể ghi đè JComponent.createTooltip để thay thế chú giải công cụ bằng thành phần của riêng bạn mà có thể hiển thị whatevee bạn thích.

+2

+1 để giải thích cách thay thế chú giải công cụ mặc định –

2

Bạn có thể phân lớp JToolTip, thành phần và ghi đè createToolTip() trên thành phần.

4

Ví dụ:

jTextField1.setToolTipText("<html>" 
           + "Line One" 
           +"<br>" 
           + "Line 2" 
         + "</html>"); 
+0

Điều này không trả lời câu hỏi của người hỏi. Anh ta hỏi về việc gói khi nó được hiển thị, không phải trong mã nguồn. – ArtB

+2

@ArtB mã ví dụ này cung cấp chú giải công cụ hai dòng như được yêu cầu. – Thelema

+0

@Thelema Ah, vì vậy trong trường hợp đó, tôi đã định dạng nó thành 'jTextField1.setToolTipText (" Dòng One
Dòng 2 ");' – ArtB

2

Điều này có thể được cải thiện đôi chút, nhưng cách tiếp cận của tôi là một hàm helper gọi trước khi thiết tooltip mà chia văn bản tooltip tại chiều dài cung cấp, nhưng điều chỉnh để phá vỡ từ trên không gian nếu có thể.

import java.util.ArrayList; 
import java.util.List; 

/** 
* 
*/ 
public class MultiLineTooltips 
{ 
    private static int DIALOG_TOOLTIP_MAX_SIZE = 75; 
    private static final int SPACE_BUFFER = 10; 

    public static String splitToolTip(String tip) 
    { 
     return splitToolTip(tip,DIALOG_TOOLTIP_MAX_SIZE); 
    } 
    public static String splitToolTip(String tip,int length) 
    { 
     if(tip.length()<=length + SPACE_BUFFER) 
     { 
      return tip; 
     } 

     List<String> parts = new ArrayList<>(); 

     int maxLength = 0; 
     String overLong = tip.substring(0, length + SPACE_BUFFER); 
     int lastSpace = overLong.lastIndexOf(' '); 
     if(lastSpace >= length) 
     { 
      parts.add(tip.substring(0,lastSpace)); 
      maxLength = lastSpace; 
     } 
     else 
     { 
      parts.add(tip.substring(0,length)); 
      maxLength = length; 
     } 

     while(maxLength < tip.length()) 
     { 
      if(maxLength + length < tip.length()) 
      { 
       parts.add(tip.substring(maxLength, maxLength + length)); 
       maxLength+=maxLength+length; 
      } 
      else 
      { 
       parts.add(tip.substring(maxLength)); 
       break; 
      } 
     } 

     StringBuilder sb = new StringBuilder("<html>"); 
     for(int i=0;i<parts.size() - 1;i++) 
     { 
      sb.append(parts.get(i)+"<br>"); 
     } 
     sb.append(parts.get(parts.size() - 1)); 
     sb.append(("</html>")); 
     return sb.toString(); 
    } 
} 

Sử dụng như

jComponent.setToolTipText(MultiLineTooltips.splitToolTip(TOOLTIP)); 
1

Đây là một phiên bản mà tôi đã sử dụng trước đó, nó hoạt động tốt nếu bạn đang tải mẹo công cụ của bạn từ ResourceBundles:

import javax.swing.JComponent; 
import javax.swing.JToolTip; 
import javax.swing.LookAndFeel; 
import javax.swing.UIManager; 
import javax.swing.plaf.ComponentUI; 
import javax.swing.plaf.ToolTipUI; 
import java.awt.Dimension; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.util.regex.Pattern; 

/** 
* A tooltip that wraps multi-line text. 
*/ 
public final class MultiLineToolTipUI extends ToolTipUI { 

    private static final int INSET = 2; 

    private static final Pattern LINE_SPLITTER = Pattern.compile("$", Pattern.MULTILINE); 

    private static final MultiLineToolTipUI SHARED_INSTANCE = new MultiLineToolTipUI(); 

    /** 
    * Install the multi-line tooltip into the UI manager. 
    */ 
    public static void installUI() { 
     String toolTipUI = MultiLineToolTipUI.class.getName(); 
     UIManager.put("ToolTipUI", toolTipUI); 
     UIManager.put(toolTipUI, MultiLineToolTipUI.class); 
    } 

    @SuppressWarnings("UnusedDeclaration") 
    public static ComponentUI createUI(JComponent c) { 
     return SHARED_INSTANCE; 
    } 

    private MultiLineToolTipUI() {} 

    @Override 
    public Dimension getMaximumSize(JComponent c) { 
     return getPreferredSize(c); 
    } 

    @Override 
    public Dimension getMinimumSize(JComponent c) { 
     return getPreferredSize(c); 
    } 

    @Override 
    public Dimension getPreferredSize(JComponent c) { 
     String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText()); 
     if (lines.length == 0) { 
      return new Dimension(2 * INSET, 2 * INSET); 
     } 
     FontMetrics metrics = c.getFontMetrics(c.getFont()); 
     Graphics g = c.getGraphics(); 
     int w = 0; 
     for (String line : lines) { 
      w = Math.max(w, (int) metrics.getStringBounds(line, g).getWidth()); 
     } 
     int h = lines.length * metrics.getHeight(); 
     return new Dimension(w + 2 * INSET, h + 2 * INSET); 
    } 

    @Override 
    public void installUI(JComponent c) { 
     LookAndFeel.installColorsAndFont(c, "ToolTip.background", "ToolTip.foreground", "ToolTip.font"); 
     LookAndFeel.installBorder(c, "ToolTip.border"); 
    } 

    @Override 
    public void paint(Graphics g, JComponent c) { 
     int w = c.getWidth(), h = c.getHeight(); 
     g.setColor(c.getBackground()); 
     g.fillRect(0, 0, w, h); 
     g.setColor(c.getForeground()); 
     g.drawRect(0, 0, w, h); 
     String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText()); 
     if (lines.length != 0) { 
      FontMetrics metrics = c.getFontMetrics(c.getFont()); 
      int height = metrics.getHeight(); 
      int y = INSET + metrics.getAscent(); 
      for (String line : lines) { 
       g.drawString(line, INSET, y); 
       y += height; 
      } 
     } 
    } 

    @Override 
    public void uninstallUI(JComponent c) { 
     LookAndFeel.uninstallBorder(c); 
    } 

} 

Và bạn sẽ sử dụng bằng cách gọi phương thức này, trước khi giao diện người dùng của bạn được tạo:

MultiLineToolTipUI.installUI(); 

Sau đó, trong các tệp thuộc tính của bạn, chỉ cần chèn dòng mới để bọc các mẹo công cụ của bạn như mong muốn.

17

Tôi biết điều này khá cũ nhưng tôi đã tìm thấy một giải pháp khá đơn giản bằng cách sử dụng mã HTML!

Chỉ cần sử dụng một đoạn HTML có chiều rộng cố định:

setToolTipText("<html><p width=\"500\">" +value+"</p></html>"); 
+0

Điều gì sẽ xảy ra nếu tôi muốn hiển thị văn bản ngắn hơn nhiều so với kích thước của chú giải công cụ? Thẻ "max-width" không hoạt động ở đây –

0

Nếu bạn chỉ cần thêm <html> văn bản tooltip của bạn, nó sẽ xuất hiện để làm việc cho đến khi bạn có /*...*/ hoặc HTML trong văn bản của bạn. Sử dụng <html><pre> hoặc thoát khỏi văn bản của bạn. Tôi cũng đã phải sử dụng <font size=3> để làm cho nó trông hơi phong nha.

Các vấn đề liên quan