Gibt es etwas, mit dem Sie ein kleines Text-Popup-Fenster (wie einen Tooltip) anzeigen können? individuelle Wörter oder Buchstaben in einer Swing JTextArea? (Oder eine JTextArea-Alternative mit ähnlicher Funktionalität.)
Was ich brauche, sollte sich wie ein Tooltip verhalten, mit anderen Worten, den Popup-Text erst anzeigen, nachdem die Maus ein oder zwei Sekunden über dem Wort schwebte, und er würde automatisch verschwinden, sobald sich die Maus wegbewegt. Der knifflige Teil hier ist natürlich, dass ich es auf der Zeichen-/Wortebene im Text haben möchte, nicht auf der Komponentenebene … irgendwelche Vorschläge?
@trashgod und @camickr haben alles gesagt 🙂 Die einzige kleine Unannehmlichkeit ist Swing selbst: Die Implementierung von standortabhängigen Tooltips erfordert Unterklassen. Das ist ein geringer Preis im Vergleich zu einem eigenen WhateverHoverManager
Nachtrag: JTextComponent, der Elternteil von JTextArea stellt Standortinformationen über zwei Methoden bereit: modelToView() und viewToModel(). Der Letztere sollte Sie die Mausposition in einen Dokumentversatz übersetzen lassen.
@ trashgod +1, aber ich kenne einige Componet.dispatchEvent (SwingUtilities.convertMouseEvent (..) von Renderer, aber wie man mit TextArea + Caret umgeht
– mKorbel
10. Mai 11 um 23:31 Uhr
@mKorbel: Gute Frage. ich Überlegen die Standortinformationen in JTextComponent ist genügend. Als Referenz habe ich den Link zu aktualisiert JTextComponent#getToolTipText(), die das in überschreibt JComponent.
– Müllgott
11. Mai ’11 um 0:00 Uhr
@mKorbel .. was bedeutet? Wie so oft verstehe ich Ihre Worte (einzeln genommen), aber nicht ihre Kombination 😉
– Kleopatra
11. Mai ’11 um 8:25 Uhr
@trashgod Ich habe ein ähnliches Problem, ich habe es überschrieben getToolTipText(MouseEvent event) in meinem JTextArea aber es wird nicht angerufen. Irgendwelche Tipps?
– Benutzer3111525
12. März 14 um 14:54 Uhr
@ user3111525: Aufrufen setToolTipText() mit einem Standardwert zum Initialisieren der ToolTipManager.
– Müllgott
12. März 14 um 17:59 Uhr
könnte sein
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
import javax.swing.event.*;
public class SimplePaintSurface implements Runnable, ActionListener {
private static final int WIDTH = 1250;
private static final int HEIGHT = 800;
private Random random = new Random();
private JFrame frame = new JFrame("SimplePaintSurface");
private JPanel tableaux;
@Override
public void run() {
tableaux = new JPanel(null);
for (int i = 1500; --i >= 0;) {
addRandom();
}
frame.add(tableaux, BorderLayout.CENTER);
JButton add = new JButton("Add");
add.addActionListener(this);
frame.add(add, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
tableaux.requestFocusInWindow();
}
@Override
public void actionPerformed(final ActionEvent e) {
addRandom();
tableaux.repaint();
}
void addRandom() {
Letter letter = new Letter(Character.toString((char) ('a' + random.nextInt(26))));
letter.setBounds(random.nextInt(WIDTH), random.nextInt(HEIGHT), 16, 16);
tableaux.add(letter);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new SimplePaintSurface());
}
}
class Letter extends JLabel {
private Font font1;
private Font font2;
private final FontRenderContext fontRenderContext1;
private final FontRenderContext fontRenderContext2;
public Letter(final String letter) {
super(letter);
setFocusable(true);
setBackground(Color.RED);
font1 = getFont();
font2 = font1.deriveFont(48f);
fontRenderContext1 = getFontMetrics(font1).getFontRenderContext();
fontRenderContext2 = getFontMetrics(font2).getFontRenderContext();
MouseInputAdapter mouseHandler = new MouseInputAdapter() {
@Override
public void mouseEntered(final MouseEvent e) {
Letter.this.setOpaque(true);
setFont(font2);
Rectangle bounds = getBounds();
Rectangle2D stringBounds = font2.getStringBounds(getText(), fontRenderContext2);
bounds.width = (int) stringBounds.getWidth();
bounds.height = (int) stringBounds.getHeight();
setBounds(bounds);
}
@Override
public void mouseExited(final MouseEvent e) {
Letter.this.setOpaque(false);
setFont(font1);
Rectangle bounds = getBounds();
Rectangle2D stringBounds = font1.getStringBounds(getText(), fontRenderContext1);
bounds.width = (int) stringBounds.getWidth();
bounds.height = (int) stringBounds.getHeight();
setBounds(bounds);
}
};
addMouseListener(mouseHandler);
}
}
Der knifflige Teil hier ist natürlich, dass ich es auf Zeichen-/Wortebene im Text haben möchte
Mit dem Mauszeiger bestimmen Sie, wo Sie sich im Textbereich befinden:
int offset = textArea.viewToModel(...);
Jetzt, da Sie einen Offset haben, können Sie das Zeichen oder Wort an dieser Stelle erhalten. Die Utilities-Klasse hat Methoden wie getWordStart() und getWordEnd().
Dann verwenden Sie die getText(…)-Methode, um das Wort oder das Zeichen zu erhalten.
+1 Vielen Dank für die Bestätigung. Ich war unsicher, als ich @mKorbel kommentierte, und ich habe Ihre Antwort versehentlich übersehen, als ich meine aktualisierte.
– Müllgott
11. Mai ’11 um 4:31 Uhr
Wolfgang Fahl
Hier ist eine tatsächliche Implementierung, die auf der Antwort von @trashgods und @camickr basiert:
mit
addToolTip(line,toolTip)
Sie können einen Tooltip für eine bestimmte Zeile hinzufügen, der angezeigt wird, wenn Sie mit der Maus über die Zeile fahren. Vielleicht möchten Sie debug=true setzen, um eine Tooltip-Anzeige für jeden Standort zu erhalten.
Wenn Sie einen allgemeinen Tooltip für Zeilen anzeigen möchten, für die es keinen speziellen gibt, möchten Sie ihn möglicherweise hinzufügen
addToolTip(-1,"general tool tip").
Diese Lösung ist nicht zu 100% das, wonach gefragt wurde, aber ziemlich nah dran. Mit ein paar Anpassungen sollte es das ursprünglich gewünschte Ergebnis erhalten.
Quellcode:
package com.bitplan.swingutil;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
/**
* Answer for
* http://stackoverflow.com/questions/5957241/text-mouseover-popups-over-a-swing-jtextarea/35250911#35250911
*
* see http://stackoverflow.com/a/35250911/1497139
* a JTextArea that shows the current Position of the mouse as a tooltip
* @author wf
*
*/
public class JToolTipEventTextArea extends JTextArea {
// make sure Eclipse doesn't show a warning
private static final long serialVersionUID = 1L;
// switch to display debugging tooltip
boolean debug=false;
/**
* the map of tool tips per line
*/
public Map<Integer,String> lineToolTips=new HashMap<Integer,String>();
/**
* create me with the given rows and columns
* @param rows
* @param cols
*/
public JToolTipEventTextArea(int rows, int cols) {
super(rows,cols);
// initialize the tool tip event handling
this.setToolTipText("");
}
/**
* add a tool tip for the given line
* @param line - the line number
* @param tooltip -
*/
public void addToolTip(int line,String tooltip) {
lineToolTips.put(line,tooltip);
}
/**
* get the ToolTipText for the given mouse event
* @param event - the mouse event to handle
*/
public String getToolTipText(MouseEvent event) {
// convert the mouse position to a model position
int viewToModel =viewToModel(event.getPoint());
// use -1 if we do not find a line number later
int lineNo=-1;
// debug information
String line=" line ?";
// did we get a valid view to model position?
if(viewToModel != -1){
try {
// convert the modelPosition to a line number
lineNo = this.getLineOfOffset(viewToModel)+1;
// set the debug info
line=" line "+lineNo;
} catch (BadLocationException ble) {
// in case the line number is invalid ignore this
// in debug mode show the issue
line=ble.getMessage();
}
}
// try to lookup the tool tip - will be null if the line number is invalid
// if you want to show a general tool tip for invalid lines you might want to
// add it with addToolTip(-1,"general tool tip")
String toolTip=this.lineToolTips.get(lineNo);
// if in debug mode show some info
if (debug) {
// different display whether we found a tooltip or not
if (toolTip==null) {
toolTip="no tooltip for line "+lineNo;
} else {
toolTip="tooltip: "+toolTip+" for line "+lineNo;
}
// generally we add the position info for debugging
toolTip+=String.format(" at %3d / %3d ",event.getX(),event.getY());
}
// now return the tool tip as wanted
return toolTip;
}
}
Das klingt knifflig. Das ist nur aus der Spitze meines Kopfes und wird wahrscheinlich nicht gewählt werden. Aber vielleicht schaffst du das.
Angenommen, es gibt eine Art HoverListener oder etwas, das Sie implementieren können, oder Sie müssen einen Maus-Listener implementieren und Ihren eigenen Wartezeitgeber einbauen. Aber sobald Sie an einem Punkt angelangt sind, an dem Sie wissen, dass Sie einen Tooltip anzeigen möchten, wissen Sie einfach nicht, um welchen Buchstaben / welches Wort es sich handelt. Ich bin mir jedoch ziemlich sicher, dass es möglich ist, die Cursorposition auf dem Bildschirm zu erhalten. Anhand dieser Position können Sie dann möglicherweise berechnen, wo sich der Cursor in der TextArea befand, und dann können Sie das Zeichen greifen. Sobald Sie den Charakter/Ort haben, können Sie auch das ganze Wort ohne viel mehr Arbeit erfassen. (BEACHTEN SIE, dass Sie das “Ansichtsfenster” des Textbereichs erhalten möchten, wenn Sie berechnen, worüber der Cursor schwebte. Wenn Ihr Textbereich Bildlaufleisten hat, stellt das Ansichtsfenster nur den auf dem Bildschirm sichtbaren Bereich dar.)
Entschuldigung für die sehr wortreiche Antwort, aber das ist die allgemeine Logik, die ich versuchen würde, wenn ich diese Funktionalität haben MUSS und ich weiß, dass Swing sie nicht anbietet. Hoffentlich bildet es einen anständigen Ausgangspunkt.
Sie müssten der JTextArea einen MouseMotionListener hinzufügen. aber getToolTipText ist viel einfacher.
– MeBigFatGuy
10. Mai 11 um 22:54 Uhr
Das Überschreiben des ToolTipText ist einfacher, aber die Verwendung des MouseMotionListener könnte meiner Meinung nach die Position des Cursors in seinen Ereignisargumenten übergeben, aber auch ToolTipText. Es geht nur darum, zu sehen, was da draußen und was verfügbar ist, denke ich. Wie gesagt, ich hatte keine Hoffnung auf Stimmen, aber ich möchte zumindest etwas bieten, um die Kreativität anderer Menschen anzuregen.
– Gnom
11. Mai ’11 um 0:00 Uhr
vielleicht wird gestimmt, nach unten … Kreativität ist gut, aber verschwendet damit, das Rad einfach neu zu erfinden. Nur wenn Sie am Ende des Tages mit einem unglaublich verbesserten Rad herauskommen, werden Sie gelobt. Voraussetzung für diesen Erfolg ist eine gründliche Kenntnis des bereits existierenden einfachen Rades und seiner Grenzen (falls vorhanden) … bloße Annahmen helfen nicht. Ende der Predigt 🙂
– Kleopatra
11. Mai 11 um 8:17 Uhr
Sie müssten der JTextArea einen MouseMotionListener hinzufügen. aber getToolTipText ist viel einfacher.
– MeBigFatGuy
10. Mai 11 um 22:54 Uhr
Das Überschreiben des ToolTipText ist einfacher, aber die Verwendung des MouseMotionListener könnte meiner Meinung nach die Position des Cursors in seinen Ereignisargumenten übergeben, aber auch ToolTipText. Es geht nur darum, zu sehen, was da draußen und was verfügbar ist, denke ich. Wie gesagt, ich hatte keine Hoffnung auf Stimmen, aber ich möchte zumindest etwas bieten, um die Kreativität anderer Menschen anzuregen.
– Gnom
11. Mai ’11 um 0:00 Uhr
vielleicht wird gestimmt, nach unten … Kreativität ist gut, aber verschwendet damit, das Rad einfach neu zu erfinden. Nur wenn Sie am Ende des Tages mit einem unglaublich verbesserten Rad herauskommen, werden Sie gelobt. Voraussetzung für diesen Erfolg ist eine gründliche Kenntnis des bereits existierenden einfachen Rades und seiner Grenzen (falls vorhanden) … bloße Annahmen helfen nicht. Ende der Predigt 🙂
– Kleopatra
11. Mai 11 um 8:17 Uhr
.
6204100cookie-checkText-Mouseover-Popups über einer Swing-JTextArea?yes
@trashgod und @camickr haben alles gesagt 🙂 Die einzige kleine Unannehmlichkeit ist Swing selbst: Die Implementierung von standortabhängigen Tooltips erfordert Unterklassen. Das ist ein geringer Preis im Vergleich zu einem eigenen WhateverHoverManager
– Kleopatra
11. Mai 11 um 8:23 Uhr