2009-05-15 19 views
95

Estoy tratando de mostrar información sobre herramientas en Java que puede ser o no ser de longitud de párrafo. ¿Cómo puedo ajustar la información sobre herramientas largas?Tooltips multilínea en Java?

+0

Proporcione un ejemplo de código. –

+1

¿Las sugerencias de herramientas no se envuelven automáticamente si se envuelven en etiquetas HTML? No estoy seguro, así que no voy a poner esto como una respuesta. –

+0

Paul: solo si tiene saltos de línea explícitos. –

Respuesta

135

Si ajusta la información sobre herramientas en las etiquetas <html> y </html>, puede dividir las líneas con las etiquetas <br>. Ver http://www.jguru.com/faq/view.jsp?EID=10653 para ejemplos y discusión.

O bien, puede utilizar la clase JMultiLineToolTip que se pueden encontrar muchos sitios en la red, incluyendo sobre herramientas http://code.ohloh.net/search?s=jmultilinetooltip

+1

Utilicé la clase JMultiLineToolTip que sugeriste. Una vez que usé setFixedWidth() para limitar la información sobre herramientas a un tamaño razonable, funcionó de maravilla. ¡Gracias! –

4

uso de HTML y de forma manual romper sus líneas (una simple palabra tokenizer con una longitud de línea fija debería hacerlo) . Solo asegúrese de que el texto de la herramienta comience con "<HTML>". Romper líneas con "< BR/>" o "<P>". Me doy cuenta de que no es la solución más limpia y el soporte HTML de Java es horrible, pero debería hacer las cosas.

23

El texto de información sobre herramientas que comienza con "<html>" se tratará como HTML. Por supuesto, eso podría ser un HTML muy amplio.

Puede reemplazar JComponent.createTooltip para reemplazar la información sobre herramientas con su propio componente que puede mostrar lo que desea.

+2

+1 para explicar cómo reemplazar la información sobre herramientas predeterminada –

2

Puede subclase JToolTip, que es un Componente, y anular createToolTip() en el componente.

4

Ejemplo:

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

Esto no responde a la pregunta del consultante. Él estaba preguntando sobre la envoltura cuando se muestra, no en el código fuente. – ArtB

+2

@ArtB este código de ejemplo da una sugerencia de dos líneas como se le pidió. – Thelema

+0

@Thelema Ah, por lo que en ese caso I'd've se formatea como 'jTextField1.setToolTipText ("Línea Uno
Línea 2");' – ArtB

2

Esto se podría mejorar un poco, pero mi enfoque era una función auxiliar llamada antes de información sobre herramientas que divide el texto de sugerencia al fin previsto, pero ajustada a dividir las palabras en el espacio que sea posible.

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

uso como

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

Aquí es una versión que he usado antes, funciona bien si está cargando la punta de la herramienta de 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); 
    } 

} 

Y se utilizaría llamando a este método, antes de que se cree su UI:

MultiLineToolTipUI.installUI(); 

Luego, en sus archivos de propiedades solo inserte líneas nuevas para ajustar sus sugerencias de herramientas según lo desee.

17

Sé que este es bastante viejo, pero encontré una solución bastante simple usando código HTML.

sólo tiene que utilizar un párrafo HTML con un ancho fijo:

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

¿Qué pasa si quiero mostrar el texto que es mucho más corto que el tamaño de información sobre herramientas? La etiqueta "max-width" no funciona aquí –

0

Si acaba de añadir a su <html> texto de sugerencia, que aparecerá a trabajar hasta que tenga /*...*/ o HTML en el texto. Use <html><pre> o escape su texto. También tuve que usar <font size=3> para que pareciera algo decente.