java - modal - ¿Aparecen ventanas emergentes de texto-mouse sobre un JTextArea Swing?
ventana emergente java netbeans (5)
¿Hay algo por ahí que te permita mostrar una pequeña ventana emergente de texto (como una información sobre herramientas) sobre palabras o letras individuales en un Swing JTextArea? (O una alternativa a JTextArea con funcionalidad similar.)
Lo que necesito debe comportarse como una información sobre herramientas, en otras palabras, solo muestra el texto emergente después de que el mouse haya estado sobre la palabra durante uno o dos segundos, y se desvanecerá automáticamente una vez que el mouse se aleje. Por supuesto, la parte difícil aquí es que lo quiero en el nivel de carácter / palabra dentro del texto, no en el nivel de componente ... ¿alguna sugerencia?
Por supuesto, la parte difícil aquí es que lo quiero en el nivel de carácter / palabra dentro del texto.
Utiliza el punto del mouse para determinar dónde se encuentra en el área de texto:
int offset = textArea.viewToModel(...);
Ahora que tiene un desplazamiento, puede obtener el carácter o la palabra en esa ubicación. La clase Utilidades tiene métodos como getWordStart () y getWordEnd ().
Luego usas el método getText (...) para obtener la palabra o el carácter.
Aquí hay una implementación real basada en @trashgods y @camickr respuesta:
con
addToolTip(line,toolTip)
puede agregar una información sobre herramientas para una línea específica que se mostrará cuando pase el mouse sobre la línea. Es posible que desee establecer debug = true para obtener una visualización de información sobre herramientas para cada ubicación.
Si desea mostrar una sugerencia de herramienta general para líneas que no tienen una específica, es posible que desee agregarla con
addToolTip(-1,"general tool tip").
Código fuente:
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://.com/questions/5957241/text-mouseover-popups-over-a-swing-jtextarea/35250911#35250911
*
* see http://.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;
}
}
Eso suena complicado. Esto está fuera de mi cabeza y probablemente no sea votado. Pero podrías ser capaz de hacer esto.
Suponiendo que haya algún tipo de HoverListener o algo que pueda implementar, o de lo contrario tendrá que implementar un detector de ratón y construir su propio temporizador de espera. Pero una vez que llega aquí, hasta un punto en el que sabe que desea que aparezca una sugerencia emergente, simplemente no sabe en qué letra / palabra están. Estoy bastante seguro de que es posible obtener la posición del cursor en la pantalla. Luego, utilizando esta posición, podría calcular dónde estaba el cursor dentro de TextArea y luego puede tomar el carácter. Una vez que tenga el personaje / ubicación, también puede tomar la palabra completa sin mucho más trabajo. (TENGA EN CUENTA que desea obtener el "viewport" del área de texto al calcular sobre qué estaba el cursor sobre el cursor, si su área de texto tiene barras de desplazamiento, la ventana solo representará el área visible en la pantalla)
Lo siento por la respuesta muy prolija, pero esa es la lógica general que intentaría si tuviera esta funcionalidad y sé que Swing no la ofrece. Esperemos que sea un buen punto de partida.
tal vez
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);
}
}
Puede anular getToolTipText(Mouse Event event)
según sea necesario.
Anexo: JTextComponent
, el padre de JTextArea
proporciona información de ubicación a través de dos métodos: modelToView()
y viewToModel()
. Este viewToModel() debería permitirle traducir la ubicación del mouse en un desplazamiento de documento.