# Image oder Icon auf Tooltip zeichnen



## prototype0815 (16. Jun 2014)

Hallo liebe Leuts, ich versuche seit geraumer Zeit irgendwie die Tooltiptexte zu verstehen und zu durchschauen. Aber irgendwie geh ich das glaub falsch an. 

mein eigenliches Problem beschreibe ich hier...

Nun ist mir die Idee gekommen ich könnte ja Images oder Icons oder ImageIcons auf die Tooltip zeichnen lassen, dazu habe ich auch schon etwas gefunden. hier.. und hier.. Aber mir ist einfach irgendwie nicht klar was ich mit diesem Klassen anfangen soll. Wenn ich auf einem Button ein Tooltip anzeigen möchte dann muss ich eigentlich die setTooltipText() Methode verwenden. Aber nun habe ich ja diese tolle Klasse implementiert die das kann was ich möchte, aber wie verwende ich Sie?

Aber vielleicht wisst ihr ja noch eine ganz andere Lösung für mich.

LG proto


----------



## turtle (16. Jun 2014)

Ich verstehe dich nicht

Du musst doch nur das zweite Beispiel nehmen, übersetzen und starten.

Habe ich gemacht und funzt.


```
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToolTip;
import javax.swing.plaf.metal.MetalToolTipUI;

public class Main {

	@SuppressWarnings("serial")
	public static void main(String[] argv) {
		JFrame frame = new JFrame("Test");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JLabel wonLabel = new JLabel() {
			public JToolTip createToolTip() {
				return new ImageToolTip();
			}
		};
		wonLabel.setText("Turtle");
		wonLabel.setToolTipText("");
		frame.add(wonLabel);
		frame.pack();
		frame.setVisible(true);
	}
}

class ImageToolTip extends JToolTip {
	public ImageToolTip() {
		setUI(new ImageToolTipUI("Images/herz10.jpg"));
	}
}

class ImageToolTipUI extends MetalToolTipUI {
	private ImageIcon icon;

	public ImageToolTipUI(String icon) {
		this.icon = new ImageIcon(getClass().getResource(icon));
	}

	public void paint(Graphics g, JComponent c) {
		FontMetrics metrics = c.getFontMetrics(c.getFont());
		Dimension size = c.getSize();
		g.setColor(c.getBackground());
		g.fillRect(0, 0, size.width, size.height);
		int x = 3;
		if (icon != null) {
			icon.paintIcon(c, g, 0, 0);
			x += icon.getIconWidth() + 1;
		}
		g.setColor(c.getForeground());
		g.drawString(((JToolTip) c).getTipText(), x, metrics.getHeight());
	}

	@Override
	public Dimension getPreferredSize(JComponent c) {
		return new Dimension(icon.getIconWidth(), icon.getIconHeight());
	}
}
```


----------



## prototype0815 (17. Jun 2014)

naja, also ich finde den programmierstil mehr als seltsam. Wer bitteschön erstellt den in jedem Label, Button, TextField,... eine neue Methode die natürlich nur innerhalb dieses Objekts existiert? 

Wie könnte ich es denn ausserdem anstellen das ich jedes mal ein anderes Image als Tooltip bekomme? Das ganze dort sieht mir doch sehr statisch aus. Gerade so als müsste ich pro Bild eine neue Klasse erstellen.


----------



## prototype0815 (17. Jun 2014)

habe eine möglichkeit gefunden, habe die Variante von Turtle und diese hier kombiniert. Anstatt die Klasse ImageTooltip zu benutzen habe ich diese hier benutzt. CToolTip hat nämlich die Möglichkeit ein ImageIcon mit zu übergeben.

```
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalToolTipUI;

/**
 * Custom implementation of a JToolTip
 * 
 * -- Ability to display a leading icon (icon to the left of the text)
 * 
 * ----------------------------------------------------
 * --- Future Enhancements (in no particular order) ---
 * ----------------------------------------------------
 * 
 * <1> Allow HTML Text (Will open the doors for multiline tooltips
 *                      with lines determined by the <br> syntax)
 * <2> Balloon Shape (Change the shape to a balloon style, similiar to xp)
 * <3> Animated Text (An option to enable to text to appear to be written
 *                    as the user is hovering)
 * <4> Title Section (Will require moving the icon into a title area and the
 *                    title appearing in bold, than displaying the text
 *                    below the title in plain)
 * 
 * ----------------------------------------------------
 * ----------------------------------------------------
 * ----------------------------------------------------
 * 
 * @since Jun 20, 2006 11:57:47 PM
 */
public final class CToolTip extends JToolTip {

  /**
   * <code>serialVersionUID</code>
   */
  private static final long serialVersionUID = -428490306576408190L;

  /**
   * Creates a Tooltip with an Icon
   * 
   * @param icon
   *      The Icon to display (NULL Allowed)
   */
  public CToolTip(final ImageIcon icon) {
    setUI(new CToolTipUI(icon));
  }

  /**
   * Creates a Tooltip with no icon
   */
  public CToolTip() {
    this(null);
  }

  /**
   * Custom Implementation of MetalToolTipUI
   *
   * @since Jun 21, 2006 8:25:40 AM
   */
  private final class CToolTipUI extends MetalToolTipUI {

    private Image tooltipIcon = null;

    /**
     * Default Constructor
     * 
     * @param tooltipIcon
     *      The Icon to display or NULL if there is no icon to display
     */
    public CToolTipUI(final ImageIcon tooltipIcon) {
      if (tooltipIcon != null) {
        this.tooltipIcon = tooltipIcon.getImage();
      }
    }

    /**
     * @see javax.swing.plaf.ComponentUI#paint(java.awt.Graphics, javax.swing.JComponent)
     */
    public void paint(final Graphics g, final JComponent c) {
      String tipText = ((JToolTip) c).getTipText();

      if (tipText == null) {
        tipText = "";
      }

      g.setColor(c.getForeground());

      if (tooltipIcon != null) {
        g.drawImage(tooltipIcon, 3, 3, c);
        g.drawString(tipText, tooltipIcon.getWidth(c) + 6, 15);
      }
      else {
        g.drawString(tipText, 6, 15);
      }
    }

    /**
     * @see javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent)
     */
    public Dimension getPreferredSize(final JComponent c) {
      final FontMetrics metrics = c.getFontMetrics(c.getFont());
      String tipText = ((JToolTip) c).getTipText();

      if (tipText == null) {
        tipText = "";
      }

      final int width = 10 + SwingUtilities.computeStringWidth(metrics, tipText)
          + (tooltipIcon == null ? 0 : tooltipIcon.getWidth(c));

      final int height = 6 + Math.max(metrics.getHeight(), tooltipIcon == null ? 0
          : tooltipIcon.getHeight(c));

      return new Dimension(width, height);
    }
  }
}
```


----------



## prototype0815 (4. Jul 2014)

Morgen, ich hab meine Problem schon vor einiger Zeit gelöst, aber nun dachte ich, ich sollte euch daran Teil haben lassen falls in Zukunft nochmal jemand ein derartiges Problem hat.
So sieht nun die Lösung aus. Ein Buffered Image (bim) wird nicht nur innerhalb der Application gezeichnet sonder wie ein Tooltip auch über den Rand hinaus.






Ich habe mir angeschaut wie die Tooltips funktionieren und mir eine eigene "show" Methode für ein JWindow geschrieben. Es wird nun direkt gezeichnet sobald dieses JWindow erstellt wird und nicht wie man es sonst kennt wenn das System update() aufruft, oder der Programmierer einen Flag setzt mit repaint().

```
win = new JWindow() {

      public void show() {
        synchronized (getTreeLock()) {
          ComponentPeer peer = this.getPeer();
          if (peer != null) {
            if (peer instanceof LightweightPeer)
              super.show();
          }
          else {
            addNotify();
            validate();
            toFront();
            synchronized (getTreeLock()) {
              visible = true;
              peer = getPeer();
              Graphics2D g = (Graphics2D) peer.getGraphics();
              peer.show();
//              System.out.println(peer);
              g.drawImage(bim, 0, 0, bim.getWidth(), bim.getHeight(), null);
            }
//            super.show();
          }
        }
      }
    };
```


```
if (bim == null)
      bim = new BufferedImage(key.getWidth(), key.getHeight(),
          BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = (Graphics2D) bim.getGraphics();
    g2.setFont(this.getParent().getFont());
    key.paint(g2);

    g2.setColor(new Color(255, 255, 0, 150));
    g2.setStroke(new BasicStroke(3));
    g2.drawRoundRect(0, 0, bim.getWidth() - 1, bim.getHeight() - 1, 10, 10);

    win.setBounds(keyboardLocation.x + (int) (p.getX() - (d.width / 4)),
        keyboardLocation.y + (int) (p.getY() - (d.height * 1.5)) - 3,
        bim.getWidth(), bim.getHeight());
    win.setAlwaysOnTop(true);
    win.setVisible(true);
```


----------

