【问题标题】:How can i get caret position in Java我如何在 Java 中获得插入符号位置
【发布时间】:2021-04-09 17:05:28
【问题描述】:

我想要我的 JTextPane 的插入符号的 X 和 Y 位置。

这是我现在拥有的:

Rectangle2D rectangle = textPane.modelToView2D(textPane.getCaretPosition());
popupMenu.show(frame, (int)rectangle.getX(), 80 + (int)rectangle.getY());

此代码来自:https://stackoverflow.com/a/18864392/14911094

但是有问题!

这没关系,但我也有一个带有 JTextPane 的滚动窗格(这是 JFrame 构造函数的代码):

editorPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane(editorPane);
this.setLayout(new GridLayout(1, 1, 0, 0));
this.add(scrollPane);

显示弹出菜单的代码正在被 diff 类中的另一个函数调用:

popupMenu.removeAll();
for (String item : stringItems)
    popupMenu.add(new JMenuItem(item));
Rectangle2D rectangle = editorPane.modelToView2D(editorPane.getCaretPosition());`
popupMenu.show(frame, (int)rectangle.getX(), 80 + (int)rectangle.getY());
popupMenu.updateUI();

所以当我进入下一行时,弹出窗口会移出屏幕,因为 rectangle.getY() 非常高。

我该如何解决这个问题!

这是一个最小的可重现示例:

public class Try {
    public static void main(String args[]) throws Exception {
        JFrame frame = new JFrame();
        JTextPane textPane = new JTextPane();
        JScrollPane pane = new JScrollPane(textPane);
        JPopupMenu popupMenu = new JPopupMenu();
        textPane.setText("SOME RANDOME TEXT FHDFFHNGHNFKJ!");
        textPane.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                try {
                    Rectangle2D rectangle = textPane.modelToView2D(textPane.getCaretPosition());
                    popupMenu.show(frame, (int) rectangle.getX(), 80 + (int) rectangle.getY());
                } catch (Exception ex) {}
                frame.requestFocus();
                frame.requestFocusInWindow();
                textPane.requestFocusInWindow();
            }
        });
        String itms[] = {
            "HI",
            "Hello"
        };
        ArrayList < String > items = new ArrayList < > (Arrays.asList(itms));
        for (String item: items)
            popupMenu.add(new JMenuItem(item));
        frame.add(pane);
        frame.setSize(900, 500);
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 没有投反对票,但是:: 我认为这对于一个可重现的例子来说已经足够了 - minimal reproducible example 意味着我们可以复制/粘贴/编译和测试查看描述的行为。我们不能用发布的代码来做到这一点。我猜想弹出窗口不应该与框架相关。您需要考虑视口位置。
  • @camickr 我不可能提供框架的代码,因为它们属于不同的类,因为这是一个相当大的项目,但我仍然会尝试提供
  • @AndrewThompson 现在检查它,但请尝试理解项目很大并且代码被分成多个类,我试图拉出负责弹出窗口的部分并在问题中显示它
  • 我们不关心您的申请。您的问题是关于在 JTextPanel 上显示弹出窗口。因此,您需要一个带有 JScrollPane 和 JTextPane 以及弹出窗口的 JFrame。 minimal reproducible example 的重点是简化代码,以确保您真正理解您试图描述的问题。您应该能够在大约 20-30 行代码中创建 MRE。以下是 MRE 的示例:stackoverflow.com/questions/16743427/…
  • @camickr 改变它的框架解决了问题

标签: java swing user-interface popup caret


【解决方案1】:

https://stackoverflow.com/users/131872/camickr建议的答案是cmets!

我的代码的问题是我显示的是关于框架而不是 textPane 的弹出菜单

这将是一个解决方案。

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;

public class Try {
    public static final int CARET_HEIGHT = 15;
    public static void main(String args[]) throws Exception {
        JFrame frame = new JFrame();
        JTextPane textPane = new JTextPane();
        JScrollPane pane = new JScrollPane(textPane);
        JPopupMenu popupMenu = new JPopupMenu();
        textPane.setText("SOME RANDOME TEXT FHDFFHNGHNFKJ!");
        textPane.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                try {
                    Rectangle2D rectangle = ((JTextPane)(e.getSource())).modelToView2D(textPane.getCaretPosition());
                    popupMenu.show(((JTextPane)(e.getSource())), (int) rectangle.getX(), CARET_HEIGHT + (int) rectangle.getY());
                } catch (Exception ex) {}
                frame.requestFocus();
                frame.requestFocusInWindow();
                textPane.requestFocusInWindow();
            }
        });
        String itms[] = {
            "HI",
            "Hello"
        };
        ArrayList < String > items = new ArrayList < > (Arrays.asList(itms));
        for (String item: items)
            popupMenu.add(new JMenuItem(item));
        frame.add(pane);
        frame.setSize(900, 500);
        frame.setVisible(true);
    }
}

【讨论】:

  • 正如我在链接中建议的那样,您应该从 KeyEvent 的源中获取文本窗格。学习使用事件中的信息将允许您创建更通用和可重用的侦听器。
  • @camickr 我添加了它
猜你喜欢
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 2016-07-12
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
  • 2013-05-21
相关资源
最近更新 更多