简体   繁体   English

获取JTextArea中插入符号位置的XY位置

[英]Get XY position of caret position in JTextArea

Actually, i have already ask this question in here . 实际上,我已经在这里问了这个问题。 But, i'm making mistake. 但是,我犯错了。 I haven't already get the solution. 我还没有解决方案。

First, at the question before, i can get Rectangle with 首先,在前面的问题上,我可以使用

Rectangle rectangle = textArea.modelToView( textArea.getCaretPostion() );

I'm also get X and Y position. 我也有X和Y的位置。

I'm creating a editor that can add new Text Area each i press Enter key. 我正在创建一个编辑器,每次按Enter键时,都可以添加新的文本区域。 XY position with code above always give same return in every Text Area. 上面带有代码的XY位置在每个文本区域中始终给出相同的返回值。 Look my code. 看我的代码。

import java.awt.Container;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;

public class forquestion extends JFrame {

    Container textAreaBox;
    LinkedList<JTextComponent> textArea;
    int nameTA;

    public forquestion() {
            int nameTA = 0;

            textArea = new LinkedList<>();

            textAreaBox = Box.createVerticalBox();
            textAreaBox.add(Box.createVerticalGlue());
            addLine();
            this.add(textAreaBox);
            this.setVisible(true);
    }

    public static void main(String[] args) {
            forquestion app = new forquestion();
            app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    }

    public void addLine () {

            JTextComponent temp_ta = createTextComponent();
            textArea.add(temp_ta);
            textAreaBox.add(textArea.getLast());
            textAreaBox.add(Box.createVerticalGlue());
    }

    protected JTextComponent createTextComponent() {
            JTextArea ta = new JTextArea("test");

            /*if (count%2==0)
                            ta.setForeground(Color.red);
            else
                            ta.setForeground(Color.GREEN);*/

            ta.setFont(new Font("Courier New",Font.PLAIN,16));
            ta.setLineWrap(true);                                                                                                                                                                                                                                                   
            ta.setWrapStyleWord(true);
            ta.setName(Integer.toString(nameTA));
            nameTA+=1;

            basicKey("ENTER", enter, ta);

            ta.addMouseListener(new java.awt.event.MouseAdapter() {
                    public void mousePressed(java.awt.event.MouseEvent ev) {
                            try {
                                    taMousePressed(ev);
                            } catch (BadLocationException ex) {
                                    Logger.getLogger(forquestion.class.getName()).log(Level.SEVERE, null, ex);
                            }
                    }
            });

            return ta;
    }

    public void basicKey(String s, Action a, JTextArea ta) {

            ta.getInputMap().put(KeyStroke.getKeyStroke(s), s);
            ta.getActionMap().put(s, a);
    }

    Action enter = new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {

                    addLine();
            }
    };

    private void taMousePressed(java.awt.event.MouseEvent ev) throws BadLocationException {
            int now_focus = Integer.parseInt(ev.getComponent().getName());
            int _caret;
            _caret = textArea.get(now_focus).getCaretPosition();
            Rectangle rectangle = textArea.get(now_focus).modelToView(_caret);
            double x = rectangle.getX();
            //int xc = textArea.get(now_focus).getLocation().x;
            double y = rectangle.getY();
            //int yc = textArea.get(now_focus).getLocation().y;
            //double h = rectangle.getHeight();
            //double w = rectangle.getWidth();
            System.out.println(x);
            System.out.println(y);  
            //System.out.println(xc);
            //System.out.println(yc);  
            //System.out.println(h);
            //System.out.println(w);
            System.out.println("");
    }

}

My code will print XY position each time you press a Text Area. 每次按下文本区域,我的代码都会打印XY位置。 But, the display always same in every text area. 但是,每个文本区域的显示始终相同。 (Try to make many Text Area and give some text) Btw, it just simple code. (尝试创建多个文本区域并提供一些文本)顺便说一句,它只是简单的代码。 You need change the window frame size for update the new text area after you press enter key..hahaha. 您需要更改窗口框的大小,以便在按Enter键之后更新新的文本区域。

So, my question is: How can i get the XY position of caret (text cursor) in any Text Area. 因此,我的问题是:如何获得任何文本区域中插入符号(文本光标)的XY位置。 I want to display JPopmenu there. 我想在那里显示JPopmenu。 :) :)

I hope this question clear for you. 我希望这个问题能为您解决。 Thx before. 谢谢。

The Rectangle reported back is relative to the text area, where it's 0x0 position is the top, left corner of the component. 向后报告的Rectangle相对于文本区域,其0x0位置是组件的顶部,左上角。

If you use something like... 如果您使用类似...

popup.show(textArea.get(now_focus), rectangle.x, rectangle.y + rectangle.height);

Where popup is a JPopupMenu , it will make the required translations to the screen itself. popupJPopupMenu ,它将对屏幕本身进行所需的翻译。

Now. 现在。 Having said that. 话说回来。 Personally, I would prefer to use the popup API support provided by Swing. 就个人而言,我更喜欢使用Swing提供的弹出API支持。 This is going to mean needing to create a custom component that extends from JTextArea to achieve it... 这意味着需要创建一个从JTextArea扩展来的自定义组件来实现它。

public class MyPopupTextArea extends JTextArea {
    /*...*/
    public Point getPopupLocation(MouseEvent evt) {
        Rectangle rectangle = textArea.get(now_focus).modelToView(_caret);

        Point p = rectangle.getLoction();
        p.y += rectangle.height;

        return p;
    }
}

Then, based on your needs, you can use setComponentPopup to provide a shared instance of the JPopupMenu or, if required, create a custom JPopupMenu for each instance of the custom editor and use setComponentPopup as you see fit...no messing about with mouse listeners ;) 然后,根据您的需要,可以使用setComponentPopup提供JPopupMenu的共享实例,或者,如果需要,为自定义编辑器的每个实例创建一个自定义JPopupMenu ,并根据需要使用setComponentPopup ...不要用鼠标弄乱听众;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM