最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How would I add a tooltip to specific strings on a textArea in java? - Stack Overflow

programmeradmin6浏览0评论

I would like to make it so that a user can select text that they've previously written into a textArea, then afterwards they would be able to select it and add a tooltip that would appear when hovering said text.

I tried to make it but i've only managed to have it show the tooltip when hovering anywhere inside of the textArea, meaning that whenever a tooltip is created, it will be shown if the mouse hovers inside of the textArea, irregardless of where it hovers, as opposed to having it only show the tooltip when the mouse hovers the string that it was created in.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;

public class toolTip extends JFrame {
    private JTextArea textArea;
    private JPopupMenu popupMenu;
    private TooltipManager tooltipManager;

    public toolTip() {
        setTitle("Custom Tooltip Application");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea = new JTextArea();
        tooltipManager = new TooltipManager(textArea);

        popupMenu = new JPopupMenu();
        JMenuItem addTooltipItem = new JMenuItem("Add Tooltip");
        addTooltipItem.addActionListener(e -> addTooltip());
        popupMenu.add(addTooltipItem);

        textArea.setComponentPopupMenu(popupMenu);

        add(new JScrollPane(textArea), BorderLayout.CENTER);
    }

    private void addTooltip() {
        String selectedText = textArea.getSelectedText();
        if (selectedText != null && !selectedText.isEmpty()) {
            String tooltip = JOptionPane.showInputDialog("Enter tooltip text:");
            if (tooltip != null && !tooltip.isEmpty()) {
                tooltipManager.addTooltip(selectedText, tooltip);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new toolTip().setVisible(true));
    }
}

class TooltipManager {
    private JTextArea textArea;
    private Map<String, String> tooltips = new HashMap<>();

    public TooltipManager(JTextArea textArea) {
        this.textArea = textArea;
        textArea.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                updateTooltip(e);
            }
        });
    }

    public void addTooltip(String text, String tooltip) {
        tooltips.put(text, tooltip);
    }

    private void updateTooltip(MouseEvent e) {
        String word = getWordAtPoint(e.getPoint());
        if (word != null && tooltips.containsKey(word)) {
            textArea.setToolTipText(tooltips.get(word));
        } else {
            textArea.setToolTipText(null);
        }
    }

    private String getWordAtPoint(Point p) {
        int pos = textArea.viewToModel2D(p);
        String text = textArea.getText();
        int start = findWordStart(text, pos);
        int end = findWordEnd(text, pos);
        return text.substring(start, end);
    }

    private int findWordStart(String text, int pos) {
        while (pos > 0 && Character.isLetterOrDigit(text.charAt(pos - 1))) {
            pos--;
        }
        return pos;
    }

    private int findWordEnd(String text, int pos) {
        while (pos < text.length() && Character.isLetterOrDigit(text.charAt(pos))) {
            pos++;
        }
        return pos;
    }
}

I would like to make it so that a user can select text that they've previously written into a textArea, then afterwards they would be able to select it and add a tooltip that would appear when hovering said text.

I tried to make it but i've only managed to have it show the tooltip when hovering anywhere inside of the textArea, meaning that whenever a tooltip is created, it will be shown if the mouse hovers inside of the textArea, irregardless of where it hovers, as opposed to having it only show the tooltip when the mouse hovers the string that it was created in.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;

public class toolTip extends JFrame {
    private JTextArea textArea;
    private JPopupMenu popupMenu;
    private TooltipManager tooltipManager;

    public toolTip() {
        setTitle("Custom Tooltip Application");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea = new JTextArea();
        tooltipManager = new TooltipManager(textArea);

        popupMenu = new JPopupMenu();
        JMenuItem addTooltipItem = new JMenuItem("Add Tooltip");
        addTooltipItem.addActionListener(e -> addTooltip());
        popupMenu.add(addTooltipItem);

        textArea.setComponentPopupMenu(popupMenu);

        add(new JScrollPane(textArea), BorderLayout.CENTER);
    }

    private void addTooltip() {
        String selectedText = textArea.getSelectedText();
        if (selectedText != null && !selectedText.isEmpty()) {
            String tooltip = JOptionPane.showInputDialog("Enter tooltip text:");
            if (tooltip != null && !tooltip.isEmpty()) {
                tooltipManager.addTooltip(selectedText, tooltip);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new toolTip().setVisible(true));
    }
}

class TooltipManager {
    private JTextArea textArea;
    private Map<String, String> tooltips = new HashMap<>();

    public TooltipManager(JTextArea textArea) {
        this.textArea = textArea;
        textArea.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                updateTooltip(e);
            }
        });
    }

    public void addTooltip(String text, String tooltip) {
        tooltips.put(text, tooltip);
    }

    private void updateTooltip(MouseEvent e) {
        String word = getWordAtPoint(e.getPoint());
        if (word != null && tooltips.containsKey(word)) {
            textArea.setToolTipText(tooltips.get(word));
        } else {
            textArea.setToolTipText(null);
        }
    }

    private String getWordAtPoint(Point p) {
        int pos = textArea.viewToModel2D(p);
        String text = textArea.getText();
        int start = findWordStart(text, pos);
        int end = findWordEnd(text, pos);
        return text.substring(start, end);
    }

    private int findWordStart(String text, int pos) {
        while (pos > 0 && Character.isLetterOrDigit(text.charAt(pos - 1))) {
            pos--;
        }
        return pos;
    }

    private int findWordEnd(String text, int pos) {
        while (pos < text.length() && Character.isLetterOrDigit(text.charAt(pos))) {
            pos++;
        }
        return pos;
    }
}
Share Improve this question edited Feb 5 at 12:47 Nicol64PA asked Feb 5 at 5:03 Nicol64PANicol64PA 111 silver badge2 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I modified the GUI to make it easier for me to test.

The TooltipManager class worked for me, but it took 2 or 3 seconds for the tooltip to display. When the mouse is moving, no tooltip displays. I'm running on Windows 10, using Java 22.

Here's the code I used. I made the TooltipManager class an inner class.

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TooltipExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TooltipExample());
    }

    private JTextArea textArea;

    private TooltipManager tooltipManager;

    @Override
    public void run() {
        JFrame frame = new JFrame("Custom Tooltip Application");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createTextPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createTextPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem addTooltipItem = new JMenuItem("Add Tooltip");
        addTooltipItem.addActionListener(e -> addTooltip());
        addTooltipItem.setFont(panel.getFont().deriveFont(20f));
        popupMenu.add(addTooltipItem);

        textArea = new JTextArea(10, 30);
        textArea.setComponentPopupMenu(popupMenu);
        textArea.setFont(panel.getFont().deriveFont(20f));
        textArea.setText(createSampleText());
        textArea.setCaretPosition(0);
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);

        tooltipManager = new TooltipManager(textArea);

        JScrollPane scrollPane = new JScrollPane(textArea);
        panel.add(scrollPane, BorderLayout.CENTER);

        return panel;
    }

    private String createSampleText() {
        return "I would like to make it so that a user can select "
                + "text that they've previously written into a "
                + "textArea, then afterwards they would be "
                + "able to select it and add a tooltip that "
                + "would appear when hovering said text.\r\n\r\n"
                + "I tried to make it but i've only managed"
                + " to have it show the tooltip when hovering"
                + " anywhere inside of the textArea, meaning"
                + " that whenever a tooltip is created, it "
                + "will be shown if the mouse hovers inside "
                + "of the textArea, irregardless of where it "
                + "hovers, as opposed to having it only show "
                + "the tooltip when the mouse hovers the "
                + "string that it was created in.";
    }

    private void addTooltip() {
        String selectedText = textArea.getSelectedText();
//      System.out.println(selectedText);
        if (selectedText == null) {
            JOptionPane.showMessageDialog(textArea,
                    "Please select a word for the tooltip.");
        } else {
            selectedText = selectedText.trim();
            if (!selectedText.isEmpty()) {
                String tooltipText = JOptionPane.showInputDialog(textArea,
                        "Enter tooltip text for \"" + selectedText + "\":");
                tooltipManager.addTooltip(selectedText, tooltipText);
            }

        }

    }

    public class TooltipManager {

        private JTextArea textArea;

        private Map<String, String> tooltips;

        public TooltipManager(JTextArea textArea) {
            this.textArea = textArea;
            this.tooltips = new HashMap<>();
            textArea.addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseMoved(MouseEvent event) {
//                  textArea.setToolTipText("Testing");
                    updateTooltip(event);
                    
                }
            });
        }

        public void addTooltip(String text, String tooltip) {
            tooltips.put(text, tooltip);
        }

        private void updateTooltip(MouseEvent event) {
            String word = getWordAtPoint(event.getPoint());
//          System.out.println(word);
            if (word != null && tooltips.containsKey(word)) {
                String text = tooltips.get(word);
                textArea.setToolTipText(text);
//              System.out.println("Success: " + text);
            } else {
                textArea.setToolTipText(null);
            }
        }

        private String getWordAtPoint(Point p) {
            int pos = textArea.viewToModel2D(p);
            String text = textArea.getText();
            int start = findWordStart(text, pos);
            int end = findWordEnd(text, pos);
            return text.substring(start, end);
        }

        private int findWordStart(String text, int pos) {
            while (pos > 0 && Character.isLetterOrDigit(text.charAt(pos - 1))) {
                pos--;
            }
            return pos;
        }

        private int findWordEnd(String text, int pos) {
            while (pos < text.length()
                    && Character.isLetterOrDigit(text.charAt(pos))) {
                pos++;
            }
            return pos;
        }

    }

}
发布评论

评论列表(0)

  1. 暂无评论