Java 在Swing JTextArea上的弹出窗口上放置文本鼠标?
是否有任何东西允许您在Swing JText区域中的单个单词或字母上显示一个小的文本弹出窗口(如工具提示)?(或具有类似功能的JTextArea替代方案。)Java 在Swing JTextArea上的弹出窗口上放置文本鼠标?,java,swing,jtextarea,Java,Swing,Jtextarea,是否有任何东西允许您在Swing JText区域中的单个单词或字母上显示一个小的文本弹出窗口(如工具提示)?(或具有类似功能的JTextArea替代方案。) 我需要的应该像一个工具提示,换句话说,只有在鼠标悬停在单词上一两秒钟后才会显示弹出文本,一旦鼠标离开,它就会自动消失。当然,这里棘手的部分是,我希望它在文本中的字符/单词级别,而不是在组件级别。。。有什么建议吗?听起来很棘手。这只是我的想法,可能不会被投票。但你也许能做到这一点 假设有某种类型的HoverListener或您可以实现的东西,
我需要的应该像一个工具提示,换句话说,只有在鼠标悬停在单词上一两秒钟后才会显示弹出文本,一旦鼠标离开,它就会自动消失。当然,这里棘手的部分是,我希望它在文本中的字符/单词级别,而不是在组件级别。。。有什么建议吗?听起来很棘手。这只是我的想法,可能不会被投票。但你也许能做到这一点 假设有某种类型的HoverListener或您可以实现的东西,或者您必须实现一个鼠标侦听器并在您自己的等待计时器中构建。但一旦你到了这里,你知道你想弹出一个工具提示,你只是不知道他们是什么字母/单词。不过我很确定,可以在屏幕上获得光标的位置。然后使用此位置,您可能能够计算光标在文本区域内的位置,然后您可以抓取字符。一旦你有了角色/位置,你也可以不费吹灰之力就抓住整个单词。(请注意,在计算光标悬停的位置时,您希望获得文本区域的“视口”,如果文本区域具有滚动条,则视口将仅表示屏幕上可见的区域) 很抱歉,我的回答非常冗长,但是如果我必须拥有这个功能,我会尝试使用这个逻辑,我知道Swing不提供这个功能。希望这是一个不错的起点。也许吧
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);
}
}
您可以根据需要进行覆盖
附录:,JTextArea
的父项通过两种方法提供位置信息:和。应该允许您将鼠标位置转换为文档偏移量
当然,这里棘手的部分是,我希望它在文本中的字符/单词级别
使用鼠标点确定您在文本区域中的位置:
int offset = textArea.viewToModel(...);
现在有了偏移量,就可以在该位置获取字符或单词。Utilities类具有getWordStart()和getWordEnd()等方法
然后使用getText(…)方法获取单词或字符。这里是一个基于@trashgoods和@camickr answer的实际实现: 与 您可以添加特定行的工具提示,当您将鼠标悬停在该行上时将显示该提示。您可能希望设置debug=true以获得每个位置的工具提示显示 如果要为没有特定工具提示的行显示常规工具提示,则可能需要添加该提示
addToolTip(-1,"general tool tip").
这个解决方案并非100%符合要求,但非常接近。经过一些调整,它应该会得到最初想要的结果
源代码:
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;
}
}
package com.bitplan.swingutil;
导入java.awt.event.MouseEvent;
导入java.util.HashMap;
导入java.util.Map;
导入javax.swing.JTextArea;
导入javax.swing.text.BadLocationException;
/**
*负责
* http://stackoverflow.com/questions/5957241/text-mouseover-popups-over-a-swing-jtextarea/35250911#35250911
*
*看http://stackoverflow.com/a/35250911/1497139
*一个JTextArea,以工具提示的形式显示鼠标的当前位置
*@author wf
*
*/
公共类JToolTipEventTextArea扩展了JTextArea{
//确保Eclipse没有显示警告
私有静态最终长serialVersionUID=1L;
//切换到显示调试工具提示
布尔调试=假;
/**
*每行的工具提示图
*/
公共映射lineToolTips=新建HashMap();
/**
*使用给定的行和列创建我
*@param行
*@param cols
*/
公共JToolTipEventTextArea(int行,int列){
超级(行、列);
//初始化工具提示事件处理
此.setToolTipText(“”);
}
/**
*为给定行添加工具提示
*@param line-行号
*@param工具提示-
*/
public void addToolTip(int行、字符串工具提示){
行工具提示。放置(行,工具提示);
}
/**
*获取给定鼠标事件的ToolTipText
*@param event-要处理的鼠标事件
*/
公共字符串GetToolTiptText(MouseeEvent事件){
//将鼠标位置转换为模型位置
int viewToModel=viewToModel(event.getPoint());
//如果以后找不到行号,请使用-1
int lineNo=-1;
//调试信息
字符串line=“line?”;
//我们得到模型位置的有效视图了吗?
如果(viewToModel!=-1){
试一试{
//将modelPosition转换为行号
lineNo=this.getLineOfOffset(viewToModel)+1;
//设置调试信息
line=“line”+行号;
}捕获(BadLocationException-ble){
//如果行号无效,请忽略此项
//在调试模式下显示问题
line=ble.getMessage();
}
}
//尝试查找工具提示-如果行号无效,则为空
//如果要显示无效行的常规工具提示,可能需要
//使用addToolTip(-1,“常规工具提示”)添加它
String toolTip=this.lineToolTips.get(lineNo);
//如果处于调试模式,则显示一些信息
如果(调试){
//无论是否找到工具提示,都会显示不同的内容
如果(工具提示==null){
toolTip=“没有行的工具提示”+lineNo;
}否则{
toolTip=“toolTip:”+toolTip+”表示行“+lineNo;
}
//通常我们添加位置信息进行调试
toolTip+=String.format(“at%3d/%3d”,event.getX(),event.getY());
}
//现在根据需要返回工具提示
返回工具提示;
}
}
您必须将MouseMotionListener添加到JTextArea。但是GetToolTiptText要简单得多。重写ToolTiptText更简单,但是使用MouseMotionListener可能会传递光标的位置
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;
}
}