为了账号安全,请及时绑定邮箱和手机立即绑定

JTextArea - 双击/三次单击 + 移动鼠标的选择行为

JTextArea - 双击/三次单击 + 移动鼠标的选择行为

尚方宝剑之说 2024-01-28 17:08:19
问题:当您双击 JTextArea 中的单词时,它会被标记,但是当您不释放鼠标按钮并尝试标记下一个单词时,它不会标记整个单词,而是标记单个字符。移动鼠标(双击)时,它应该标记整个单词(而不是单个字符)。这实际上是我尝试过的所有程序的默认行为,例如:记事本、Firefox、Chrome、Word,甚至 Netbeans 等。与三次单击相同(当按住并移动鼠标时应标记下一行,而不是字符)。有任何想法吗?我很难用谷歌搜索这个问题,但由于这是一个很常见的事情,我相信一定有一个简单的选择,或者至少有人已经有了解决方案。示例代码:public class TestJTextArea {    public static void main(final String[] args)    {        final JPanel panel = new JPanel(new BorderLayout());        panel.setPreferredSize(new Dimension(500, 500));        panel.add(new JTextArea(), BorderLayout.CENTER);        final JFrame frame = new JFrame("Test");        frame.getContentPane().add(panel, BorderLayout.CENTER);        frame.pack();        frame.setResizable(false);        frame.setLocationRelativeTo(null);        frame.setVisible(true);    }}
查看完整描述

1 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

也许您需要创建一个自定义的Caret,例如:


import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.text.*;


public class TestJTextArea2 {

  public Component makeUI() {

    String text = "The quick brown fox jumps over the lazy dog.";

    JTextArea textArea1 = new JTextArea("default\n" + text);

    JTextArea textArea2 = new JTextArea("setCaret\n" + text) {

      @Override public void updateUI() {

        setCaret(null);

        super.updateUI();

        Caret oldCaret = getCaret();

        int blinkRate = oldCaret.getBlinkRate();

        Caret caret = new SelectWordCaret();

        caret.setBlinkRate(blinkRate);

        setCaret(caret);

      }

    };

    JPanel p = new JPanel(new GridLayout(2, 1));

    p.add(new JScrollPane(textArea1));

    p.add(new JScrollPane(textArea2));

    return p;

  }


  public static void main(String[] args) {

    EventQueue.invokeLater(() -> {

      JFrame f = new JFrame();

      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

      f.getContentPane().add(new TestJTextArea2().makeUI());

      f.setSize(320, 240);

      f.setLocationRelativeTo(null);

      f.setVisible(true);

    });

  }

}


class SelectWordCaret extends DefaultCaret {

  private boolean wordSelectingMode = false;

  private int p0; // = Math.min(getDot(), getMark());

  private int p1; // = Math.max(getDot(), getMark());


  @Override public void mousePressed(MouseEvent e) {

    super.mousePressed(e);

    int nclicks = e.getClickCount();

    if (SwingUtilities.isLeftMouseButton(e) && !e.isConsumed() && nclicks == 2) {

      p0 = Math.min(getDot(), getMark());

      p1 = Math.max(getDot(), getMark());

      wordSelectingMode = true;

    } else {

      wordSelectingMode = false;

    }

  }


  @Override public void mouseDragged(MouseEvent e) {

    if (wordSelectingMode && !e.isConsumed() && SwingUtilities.isLeftMouseButton(e)) {

      continuouslySelectWords(e);

    } else {

      super.mouseDragged(e);

    }

  }


  private void continuouslySelectWords(MouseEvent e) {

    Position.Bias[] biasRet = new Position.Bias[1];

    JTextComponent c = getComponent();

    int pos = c.getUI().viewToModel2D(c, e.getPoint(), biasRet);

    if(biasRet[0] == null) {

      biasRet[0] = Position.Bias.Forward;

    }

    try {

      if (p0 <= pos && pos <= p1) {

        setDot(p0);

        moveDot(p1, biasRet[0]);

      } else if (p1 < pos) {

        setDot(p0);

        moveDot(Utilities.getWordEnd(c, pos - 1), biasRet[0]);

      } else if (p0 > pos) {

        setDot(p1);

        moveDot(Utilities.getWordStart(c, pos), biasRet[0]);

      }

    } catch (BadLocationException bl) {

      UIManager.getLookAndFeel().provideErrorFeedback(c);

    }

  }

}


查看完整回答
反对 回复 2024-01-28
  • 1 回答
  • 0 关注
  • 29 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信