【问题标题】:How to get a point value for where a word (or selection) in a JTextArea is on the screen?如何获取 JTextArea 中的单词(或选择)在屏幕上的位置的点值?
【发布时间】:2018-02-10 19:56:25
【问题描述】:

我的目标是让 JTextArea 中的 anyGivenWord “可操作”。例如,当您将鼠标悬停在 anyGivenWord 上时,会出现一个工具提示,但当您将鼠标悬停在 JTextArea 中的任何其他词上时不会出现。由于据我所知您无法直接执行此操作,因此我正在考虑将一个组件放置在 JTextArea 中每个 anyGivenWord 出现的位置上,并在 JTextArea 的大小发生变化时让它重新定位,以便单击看起来是 anyGivenWord实际上是单击组件(导致触发某些侦听器)。为此,我需要知道该单词出现在哪个点 (x,y),以便我可以将组件放置在该点。

我在想我可以搜索 JTextArea 并选择 anyGivenWord 的实例,然后选择 getSelectionStart() 和 getSelectionEnd(),但我认为这些方法返回的 int 是所选第一个/最后一个字母的索引,如,它在 getText() 返回的字符串中的位置。我需要的是 x/y 坐标。这可能吗?

如果没有...关于更优雅的方式来做我想做的事情的任何建议?

【问题讨论】:

  • 只用 Java 编码大约 3 个月,只用不到一年的任何语言编码 - 原谅我的新手身份 XD

标签: java swing jtextarea mouselistener


【解决方案1】:

您可以使用带有 HTML 的 JEditorPane 并将超链接添加到任何给定的单词。阅读 How to Use Editor Panes 上的 Swing 教程部分,了解帮助您入门的基础知识。

然后您可以添加HyperlinkListener 以在单击该单词时响应事件。阅读JEditorPane API,了解使用HyperlinkListener 的示例。

例如,当您将鼠标悬停在 anyGivenWord 上时,会出现一个工具提示,

如果您不想使用超链接,则可以通过覆盖getToolTipText(...) 方法来控制工具提示文本。此方法接收 MouseEvent,因此您可以获取鼠标位置。然后,您可以使用 JTextArea 的 viewToModel(...) 方法来获取鼠标在 Document 中的偏移量。然后查看Utilities。该类将帮助您获取单词的开始/结束偏移量,以便您可以使用getText(...) 方法在当前鼠标位置提取单词。

【讨论】:

    【解决方案2】:

    您可以使用任何 JTextComponent 并通过一些方法(如下提供)您可以从文本中收集几个不同的项目,例如:

    • 位于当前鼠标指针位置下的字符;
    • 位于当前鼠标指针位置下的Word;
    • 位于当前鼠标指针位置下的选定文本 (如果选择);
    • 位于当前鼠标指针位置下的突出显示文本 (如果您也想在文本中突出显示);
    • 鼠标指针下的文本是否被选中?;
    • 鼠标指针下的文本是否突出显示?

    正如@camickr 已经如此慷慨地指出的那样,这里的关键是使用 JTextComponent.viewToModel() 方法(我相信所有 Swing Text 组件都包含该方法)以获取与当前鼠标指针在组件内的位置相关的文本索引位置。

    这里有一些方法可以玩:

    /**
         * This method will return either boolean true or false if the text contained 
         * under the current mouse pointer location within a JTextComponent is Selected 
         * or not. If the text under the mouse is found to be Selected then boolean
         * true is returned. If the text under the mouse pointer is NOT found to be 
         * Selected then boolean false is returned.<br><br>
         * 
         * This method is not to be confused with the getHighlightedUnderMouse() method. 
         * Highlighted text and Selected text are two completely different things. 
         * Highlighted Text can be text which is Highlighted (generally with a specific 
         * color) and can be in many different locations throughout the entire document 
         * whereas Selected Text is generally done by dragging the mouse over a document 
         * location while holding the left mouse button making the text SELECTED.<br><br>
         * 
         * This method is generally run within a JTextComponent MouseMove Event but can be 
         * run from any JTextComponent Mouse event which will provide the current mouse 
         * coordinates within the supplied JTextComponent Object.
         * 
         * @param textComp (JTextComponent) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int y = evt.getY();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (Boolean) True if the text under the current mouse pointer location 
         * within the supplied JTextComponent is Selected and false if it is not.
         */
        public static boolean isSelectededUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            boolean isSelected = false;
            if (textComp.getText().isEmpty()) { return false; }
    
            Point pt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pt);
    
            int start = textComp.getSelectionStart();
            int end = textComp.getSelectionEnd();
            if (pos >= start && pos <= end) {
                isSelected = true;
            }
            return isSelected;
        }
    
        /**
         * This method will return either boolean true or false if the text contained 
         * under the current mouse pointer location within a JTextComponent is Highlighted 
         * or not. If the text under the mouse is found to be Highlighted then boolean
         * true is returned. If the text under the mouse pointer is not found to be 
         * highlighted then boolean false is returned.<br><br>
         * 
         * This method is not to be confused with the getSelectedUnderMouse() method. 
         * Highlighted text and Selected text are two completely different things. 
         * Highlighted Text can be text which is Highlighted (generally with a specific 
         * color) and can be in many different locations throughout the entire document 
         * whereas Selected Text is generally done by dragging the mouse over a document 
         * location while holding the left mouse button making the text SELECTED.<br><br>
         * 
         * This method is generally run within a JTextComponent's MouseMove Event but can be 
         * run from any JTextComponent's Mouse event which will provide the current mouse 
         * coordinates within the supplied JTextArea Object.
         * 
         * @param textComp (JTextComponent) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int y = evt.getY();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (Boolean) True if the text under the current mouse pointer location 
         * within the supplied JTextComponent is Highlighted and false if it is not.
         */
        public static boolean isHighlightededUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            boolean isHighlighted = false;
            if (textComp.getText().isEmpty()) { return false; }
    
            Point pt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pt);
    
            Highlighter.Highlight[] allHighlights = textComp.getHighlighter().getHighlights();
            String strg = "";
            for (int i = 0; i < allHighlights.length; i++) {
                int start =  (int)allHighlights[i].getStartOffset();
                int end =  (int)allHighlights[i].getEndOffset();
                if (pos >= start && pos <= end) {
                    isHighlighted = true;
                    break;
                }
            }        
            return isHighlighted;
        }
    
        /**
         * This method will return the "Selected" text contained under the mouse pointer
         * location within a JTextComonent.<br><br>
         * 
         * This method is not to be confused with the getHighlightedUnderMouse() method. 
         * Highlighted text and Selected text are two completely different things. 
         * Highlighted Text can be text which is Highlighted (generally with a specific 
         * color) and can be in many different locations throughout the entire document 
         * whereas Selected Text is generally done by dragging the mouse over a document 
         * location while holding the left mouse button making the text SELECTED.<br><br>
         * 
         * This method is generally run within a Text Component's MouseMove Event but can be 
         * run from any Text Component's Mouse event which will provide the current mouse 
         * coordinates within the supplied Text Component Object.
         * 
         * @param textComp (JTextComponent) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the Text Component's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the Text Component's MouseMove event like 
         * this <code>int y = evt.getY();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (String) The current selected string located under the current mouse 
         * location.
         */
        public static String getSelectededUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            String selectedText = "";
            if (textComp.getText().isEmpty()) { return selectedText; }
    
            Point pt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pt);
    
            int start = textComp.getSelectionStart();
            int end = textComp.getSelectionEnd();
            int selectedLength = (end - start);
            if (pos >= start && pos <= end) {
                try {
                    selectedText = textComp.getText(start, selectedLength);
                } 
                catch (BadLocationException ex) {
                    // Ignore!!!
                }
            }
            return selectedText;
        }
    
        /**
         * This method will return the "Highlighted" text contained under the mouse pointer
         * location within a JTextComponent.<br><br>
         * 
         * This method is not to be confused with the getSelectedUnderMouse() method. 
         * Highlighted text and Selected text are two completely different things. 
         * Highlighted Text can be text which is Highlighted (generally with a specific 
         * color) and can be in many different locations throughout the entire document 
         * whereas Selected Text is generally done by dragging the mouse over a document 
         * location while holding the left mouse button making the text SELECTED.<br><br>
         * 
         * This method is generally run within a JTextComponent MouseMove Event but can be 
         * run from any JTextComponent Mouse event which will provide the current mouse 
         * coordinates within the supplied JTextComponent Object.
         * 
         * @param textComp (JTextComponent) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int y = evt.getY();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (String) The current highlighted string located under the current mouse 
         * location.
         */
        public static String getHighlightededUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            if (textComp.getText().isEmpty()) { return ""; }
    
            Point pnt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pnt);
    
            String highlightedText = "";
            Highlighter.Highlight[] allHighlights = textComp.getHighlighter().getHighlights();
            if (allHighlights.length > 0) { 
                for (int i = 0; i < allHighlights.length; i++) {
                    int start =  (int)allHighlights[i].getStartOffset();
                    int end =  (int)allHighlights[i].getEndOffset();
                    int hlStringLength = (end-start);
                    if (pos >= start && pos <= end) {
                        try {
                            highlightedText = textComp.getText(start, hlStringLength);
                            break;
                        } 
                        catch (BadLocationException ex) { 
                            // Ignore!!!
                        }
                    }
    
                }
            }
            return highlightedText;
        }
    
        /**
         * This method would normally be called within a JTextComponent's MouseMove Event.
         * 
         * @param textComp (JTextComponent) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int y = evt.getY();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (String) The current character located under the current mouse 
         * location.
         */
        public static String getCharUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            String character = "";
            Point pt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pt);
            try {
                character = textComp.getDocument().getText(pos, 1);
            } 
            catch (BadLocationException ex) { 
                // Ignore!! 
            }
            return character;
        }
    
        /**
         * This method would normally be called within a JTextComponent's MouseMove Event.
         * 
         * @param textComp (JTextArea) The JTextComponent object to work on. This 
         * can be the component variable name for either a JTextField, JTextArea, 
         * JFormattedField, JPasswordField, JTextPane, and JEditorPane.<br>
         * 
         * @param textAreaMouseXLocation (Integer) The current X Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int x = evt.getX();</code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @param textAreaMouseYLocation (Integer) The current Y Location of the mouse 
         * pointer. This value can be acquired from the JTextComponent's MouseMove event like 
         * this <code>int y = evt.getY();<code> where evt is the <b>java.awt.event.MouseEvent</b> 
         * parameter variable.<br>
         * 
         * @return (String) The current Word located under the current mouse location.
         */
        public static String getWordUnderMouse(JTextComponent textComp, int textAreaMouseXLocation,
                                               int textAreaMouseYLocation) {
            Point pt = new Point(textAreaMouseXLocation, textAreaMouseYLocation);
            int pos = textComp.viewToModel(pt);
            String word = "";
            try {
                Document doc = textComp.getDocument();
                if( pos > 0 && (pos >= doc.getLength() || Character.isWhitespace( doc.getText( pos, 1 ).charAt( 0 ) )) ) {
                    // if the next character is a white space then use 
                    // the word on the left side..
                    pos--;
                }
                // get the word from current position
                final int begOffs = Utilities.getWordStart(textComp, pos);
                final int endOffs = Utilities.getWordEnd(textComp, pos);
                word = textComp.getText( begOffs, endOffs - begOffs );
            } 
            catch( BadLocationException ex ) {
                // Ignore this exception!!!
            }
            return word;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-20
      相关资源
      最近更新 更多