2009-05-15 7 views
95

J'essaie d'afficher des info-bulles en Java qui peuvent être ou non de longueur de paragraphe. Comment puis-je envelopper de longues infobulles?Info-bulles multilignes en Java?

+0

Veuillez fournir un exemple de code. –

+1

Les conseils d'outil ne sont-ils pas automatiquement mis en forme s'ils sont enveloppés dans des balises HTML? Je ne suis pas sûr, alors je ne mets pas cela en réponse. –

+0

Paul: Seulement si vous avez des sauts de ligne explicites. –

Répondre

135

Si vous intégrez l'info-bulle aux étiquettes <html> et </html>, vous pouvez rompre les lignes avec les étiquettes <br>. Voir http://www.jguru.com/faq/view.jsp?EID=10653 pour des exemples et des discussions.

Ou vous pouvez utiliser la classe JMultiLineToolTip qui se trouve de nombreux endroits sur le net, y compris http://code.ohloh.net/search?s=jmultilinetooltip

+1

J'ai utilisé la classe JMultiLineToolTip que vous avez suggérée. Une fois que j'ai utilisé setFixedWidth() pour limiter l'info-bulle à une taille raisonnable, cela a très bien fonctionné. Merci! –

4

Utilisez infobulles HTML et casser manuellement vos lignes (un simple mot tokenizer avec une longueur de ligne fixe devrait le faire) . Assurez-vous simplement que le texte de votre tooltop commence par "<HTML>". Casser les lignes avec "< BR/>" ou "<P>". Je réalise que ce n'est pas la solution la plus propre et le support HTML de Java est horrible, mais il devrait faire avancer les choses.

23

Le texte de l'info-bulle commençant par "<html>" sera traité comme HTML. Bien sûr, cela pourrait être très large HTML.

Vous pouvez remplacer JComponent.createTooltip pour remplacer l'info-bulle par votre propre composant qui peut s'afficher comme vous le souhaitez.

+2

+1 pour expliquer comment remplacer l'info-bulle par défaut –

2

Vous pouvez sous-classer JToolTip, qui est un composant, et remplacer createToolTip() sur le composant.

4

Exemple:

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

Cela ne répond pas à la question du demandeur. Il demandait à propos de l'emballage quand il est affiché, pas dans le code source. – ArtB

+2

@ArtB Cet exemple de code donne une info-bulle à deux lignes comme demandé. – Thelema

+0

@Thelema Ah, dans ce cas, je l'ai formaté comme 'jTextField1.setToolTipText (" Line One
Ligne 2 ");' – ArtB

2

Cela pourrait être quelque peu améliorée, mais mon approche était une fonction d'assistance appelée avant de infobulle qui a divisé le texte de l'infobulle longuement prévu, mais ajusté à briser les mots sur l'espace lorsque cela est possible.

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

utilisation comme

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

Voici une version que je l'ai utilisé auparavant, cela fonctionne bien si vous chargez vos infobulles 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); 
    } 

} 

Et vous utiliseriez En appelant cette méthode, avant que votre interface utilisateur ne soit créée:

MultiLineToolTipUI.installUI(); 

Ensuite, dans vos fichiers de propriétés, insérez simplement des sauts de ligne pour envelopper vos conseils d'outils comme vous le souhaitez.

17

Je sais que celui-ci est assez ancien mais j'ai trouvé une solution assez simple en utilisant du code HTML!

Il suffit d'utiliser un paragraphe HTML avec une largeur fixe:

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

Et si je veux afficher un texte beaucoup plus court que la taille de l'infobulle? La balise "max-width" ne fonctionne pas ici –

0

Si vous ajoutez juste <html> à votre texte de l'infobulle, il semble fonctionner jusqu'à ce que vous avez /*...*/ ou HTML dans votre texte. Utilisez <html><pre> ou échapper votre texte. Je devais aussi utiliser <font size=3> pour que ça ait l'air assez décent.

Questions connexes