java - 如何使 JTextComponent 的插入符号跳过选定的文本?

标签 java swing selection caret jtextcomponent

许多环境中原生文本字段的正常行为如下:

带有文本“abcdefg”的文本域。我用鼠标从左到右选择“efg”。插入符号现在位于“g”后面。当我按一次光标左键将插入符号向左移动时,选择被删除并且插入符号位于“e”之前。当我在 JTextField 或 JTextArea(在 Mac OS 上测试)中执行相同操作时,执行完全相同的操作会导致插入符号位于“g”之前。

我知道如何通过使用 KeyListener 并将其注册到每个组件来以编程方式更改它,但我正在寻找一种方法来更改我的整个应用程序。那可能吗?是否有我找不到的标志,或者我是否必须改变我的外观和感觉?

谢谢

最佳答案

I am looking for a way to change that for my entire application

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class CaretAction extends TextAction
{
    private boolean caretForward;

    public CaretAction(boolean caretForward)
    {
        super(caretForward ? "Caret Forward" : "Caret Backward");
        this.caretForward = caretForward;
    }

    public void actionPerformed(ActionEvent e)
    {
        JTextComponent textComponent = getFocusedComponent();

        int start = textComponent.getSelectionStart();
        int end = textComponent.getSelectionEnd();
        int offset = textComponent.getCaretPosition();

        if (start != end)
        {
            if (caretForward)
                offset = (offset == end) ? offset + 1 : end;
            else
                offset = (offset == start) ? offset -1 : start;
        }
        else
        {
            offset += (caretForward) ? 1 : -1;
        }

        offset = Math.max(offset, 0);
        offset = Math.min(offset, textComponent.getDocument().getLength());
        textComponent.setCaretPosition( offset );
    }

    private static void createAndShowUI()
    {
        JTextField textField1 = new JTextField(10);
        JTextField textField2 = new JTextField(10);

        JPanel panel = new JPanel();
        panel.add( textField1 );
        panel.add( textField2 );

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );

        ActionMap map = (ActionMap)UIManager.get("TextField.actionMap");
        map.put(DefaultEditorKit.backwardAction, new CaretAction(false));
        map.put(DefaultEditorKit.forwardAction, new CaretAction(true));
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

您还需要更改 JTextArea、JFormattedTextField 的 ActionMap ...

关于java - 如何使 JTextComponent 的插入符号跳过选定的文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15554728/

相关文章:

algorithm - 有骗子的选拔程序?

java - 如何避免在以下代码中检测到竞争条件?

java - Android 无法找到我的 JNI native 库函数

java - JTable可点击列排序: Sorting sorts content of cells,但不更新单元格格式?

java - 为什么在添加两个面板时,分割 Pane 分隔线不会移动?

objective-c - 在 UITableView 初始化中设置选定的单元格

java - 从 groovy 脚本调用方法时,我在 Jenkins 中收到 java.lang.NullPointerException

Java 1.0 Applet -- 不兼容类型 : Choice cannot be converted to Button -- Java In A Nutshell Example 1-2

java - 将 JFrame 中的现有 JPanel 替换为另一个 JPanel 的正确方法是什么?

javascript - Vuetify - 当模型更改时,如何使 setSelectionRange(int, int) 在 v-textarea 中工作