【问题标题】:Get XY position of caret position in JTextArea获取 JTextArea 中插入符号位置的 XY 位置
【发布时间】:2013-09-22 04:34:00
【问题描述】:

其实我已经在here问过这个问题了。但是,我犯了错误。我还没有得到解决方案。

首先,在前面的问题中,我可以得到 Rectangle

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

我也得到了 X 和 Y 的位置。

我正在创建一个编辑器,可以在每次按 Enter 键时添加新的文本区域。上面代码的 XY 位置总是在每个文本区域中给出相同的返回。看我的代码。

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("");
    }

}

每次按下文本区域时,我的代码都会打印 XY 位置。但是,每个文本区域的显示总是相同的。 (尝试制作许多文本区域并给出一些文本)顺便说一句,它只是简单的代码。按下回车键后,您需要更改窗口框架大小以更新新的文本区域..哈哈哈。

所以,我的问题是:如何在任何文本区域中获取插入符号(文本光标)的 XY 位置。我想在那里显示JPopmenu。 :)

我希望你能清楚这个问题。之前谢谢。

【问题讨论】:

    标签: java swing position jtextarea caret


    【解决方案1】:

    返回的Rectangle是相对于文本区域的,它的0x0位置是组件的左上角。

    如果你使用类似...

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

    如果popupJPopupMenu,它将对屏幕本身进行所需的翻译。

    现在。话说回来。就个人而言,我更喜欢使用 Swing 提供的弹出式 API 支持。这意味着需要创建一个从 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;
        }
    }
    

    然后,根据您的需要,您可以使用setComponentPopup 提供JPopupMenu 的共享实例,或者,如果需要,为自定义编辑器的每个实例创建一个自定义JPopupMenu 并使用setComponentPopup 作为您认为合适...不要与鼠标听众混为一谈;)

    【讨论】:

    • 我明白了。谢谢解决方案。顺便说一句,你能给我你的完整代码来解决我的问题吗?至少,您的构造函数或将 Jpopmenu 添加到面板或框架的代码。我还在学习 JPopMenu。每次我将它添加到容器中时,它都会覆盖其他组件。
    • 您不会将 JPopupMenu 添加到组件(通常)。您应该使用 setComponentPopup 将弹出窗口与组件关联,或者,如果您有特殊需要,请使用 JPopupMenu#show 来显示弹出窗口。更像是一个特殊的窗口,而不是一个组件。您可以查看Brining up popup menu 了解更多详情...
    • 这对我来说很有意义。无论如何谢谢:D
    猜你喜欢
    • 2013-05-08
    • 2011-08-22
    • 2013-05-21
    • 1970-01-01
    • 2013-07-18
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多