# scrollable Tooltip



## GilbertGrape (25. Nov 2008)

Hallöchen,

gibt es da was um dem Tooltip ne maximale Größe mitzugeben und den Rest dann über Scrollbalken erreichen lassen.
Also so wie in Eclipse?

Danke, GG

PS:Google+Forum konnten mir beim obigen Suchbegriff nicht so richtig helfen


----------



## André Uhres (25. Nov 2008)

JScrollableToolTip

Der Code von diesem scrollable Tooltip enthält eine "main"-Methode zum Testen und um zu zeigen, 
wie wir "JScrollableToolTip" benutzen können.

*Bemerkung für Tooltip in einer JTable*: 

Wenn wir "JScrollableToolTip" für die Zellen einer JTable benutzen wollen, 
dann müssen wir wissen, daß der Renderer nur indirekt für den Tooltip zuständig ist. 
In erster Linie kümmert sich _JTable _um den Tooltip. Sie benutzt lediglich den Tooltip_text_ vom Renderer.
Darum müssen wir _JTable_#createTooltip() überschreiben um eine Instanz von "JScrollableToolTip" zurückzugeben 
und nicht die createTooltip-Methode der Rendererkomponente (die wird nie aufgerufen).
*Zusammenfassung der Änderungen:*

- Man kann mit dem Mausrad scrollen, auch wenn die Maus noch über der Quellkomponente ist.
_- mouseWheelMoved _veranlasst einen Reset vom DismissDelay, wenn die Maus über der Qellkomponente ist.


```
/*
 * JScrollableToolTip.java
 */
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class JScrollableToolTip extends JToolTip implements MouseWheelListener {
 
    private JTextArea tipArea;
    private JScrollPane scrollpane;
    private JComponent comp;
 
    /** Creates a tool tip. */
    public JScrollableToolTip(final int width, final int height) {
        this(width, height, null);
    }
 
    public JScrollableToolTip(final int width, final int height, final JComponent comp) {
        this.comp = comp;
        setPreferredSize(new Dimension(width, height));
        setLayout(new BorderLayout());
        tipArea = new JTextArea();
        tipArea.setLineWrap(true);
        tipArea.setWrapStyleWord(true);
        tipArea.setEditable(false);
        tipArea.setBackground(new Color(255, 255, 204));
        scrollpane = new JScrollPane(tipArea);
        add(scrollpane);
        if(comp != null){
            comp.addMouseWheelListener(this);
        }
    }
 
    public void mouseWheelMoved(final MouseWheelEvent e) {
        scrollpane.dispatchEvent(e);
        MouseEvent e2 = new MouseEvent(comp, MouseEvent.MOUSE_MOVED, 0, 0, 0, 0, 0, false);
        comp.dispatchEvent(e2);
    }
 
    @Override
    public void setTipText(final String tipText) {
        String oldValue = this.tipArea.getText();
        tipArea.setText(tipText);
        tipArea.setCaretPosition(0);
        firePropertyChange("tiptext", oldValue, tipText);
    }
 
    @Override
    public String getTipText() {
        return tipArea == null ? "" : tipArea.getText();
    }
 
    @Override
    protected String paramString() {
        String tipTextString = (tipArea.getText() != null ? tipArea.getText() : "");
 
        return super.paramString() +
                ",tipText=" + tipTextString;
    }
 
    //for testing only:
    public static void main(final String args[]) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 100);
        f.setLocationRelativeTo(null);
        ToolTipManager.sharedInstance().setDismissDelay(30000);
        JButton button = new JButton("Used to display...") {
 
            @Override
            public JToolTip createToolTip() {
                JScrollableToolTip tip = new JScrollableToolTip(200, 80, this);
                tip.setComponent(this);
                return tip;
            }
        };
        button.setToolTipText("Used to display a 'Tip' for a Component. " +
                "Typically components provide api to automate the process of " +
                "using ToolTips. For example, any Swing component can use the " +
                "JComponent  setToolTipText method to specify the text for a standard tooltip.");
        f.add(button);
        f.setVisible(true);
    }
}
```


----------



## GilbertGrape (25. Nov 2008)

Wow, das ist toll. Vielen Dank!

In meinem Kontext (TableCellRenderer) funktioniert es noch nicht so, aber ich werd mal ein bissel debuggen. Ich kann ja nicht andere meine ganze Arbeit machen lassen  :wink:


----------



## André Uhres (25. Nov 2008)

Wir müssen die Methode 'createToolTip' von der *JTable* überschreiben!


----------



## GilbertGrape (26. Nov 2008)

Ok danke!
Obwohl ich das nicht so ganz verstehe. Ich mach ja im Renderer this.setToolTipText, deswegen dachte ich, dass ich auch da die Methode überschreiben muss.


----------



## André Uhres (26. Nov 2008)

Die JTable ist für den Tooltip zuständig. Sie benutzt lediglich den Tooltiptext vom Renderer.
Darum müssen wir JTable#createTooltip() überschreiben um unseren angepassten Tooltip zurückzugeben.


----------



## GilbertGrape (26. Nov 2008)

Hm, es ist leider noch nicht ganz perfekt. 
Da meine Spalten in der Table eine recht geringe Höhe haben, schaffe ich es nie, mit der Maus ins Scrollpane zu kommen, ohne schon den Tooltip von der nächsten Zeile zu haben. Aus diesem Grund wollte ich ich den ToolTip etwas nach oben verschieben, sodass das Tooltip auf der gleichen Höhe ist wie die Zeile.
Dafür habe ich die Methode getToolTipLocation überschrieben, und zwar so:


```
public Point getToolTipLocation(MouseEvent event) {
//		return new Point(20, -30);
		return new Point(super.getToolTipLocation(event).x, super.getToolTipLocation(event).y-10);
	}
```

Aber da kommt immer eine NullPointerException, weil getToolTipLocation in JComponent immer null zurückgibt. Wenn ich einen festen Punkt (siehe Kommentar) zurückgebe, funktioniert das, aber ich will die Position ja relativ zu der ursprünglichen Position haben.
Wie komme ich denn an die richtige Position?

Danke, GG


----------



## André Uhres (26. Nov 2008)

Versuch's mal so:

```
@Override
public Point getToolTipLocation(MouseEvent event) {
    return event.getPoint();
}
```


----------



## GilbertGrape (26. Nov 2008)

so gehts!
Ich danke dir ganz herzlich!!!


----------



## André Uhres (27. Nov 2008)

Ich habe "JScrollableToolTip" oben verbessert.
Man kann jetzt die Quellkomponente im Konstruktor übergeben.
In dem Fall wird das Mausrad an die Quellkomponente gebunden, 
so daß man scrollen kann, auch wenn die Maus noch über der Quellkomponente ist.

Das löst gleichzeitig das Problem, das man hat, wenn der Tooltip einer Komponente ausserhalb 
der Grenzen der Komponente erscheint: wenn man dann die Maus von der Komponente
zum Tooltip bewegt um nach unten scrollen zu können, verschwindet der Tooltip!

EDIT: Bei "mouseWheelMoved" wird jetzt ein Reset vom DismissDelay gemacht, 
wenn die Maus über der Quellkomponent ist.


----------

