JTextAreaをマウスで長押しして単語選択などを実行する
Total: 618
, Today: 3
, Yesterday: 7
Posted by aterai at
Last-modified:
概要
JTextArea
にMouseListener
を追加し、マウス左ボタンの長押しで単語選択、右クリックでのフォーカス移動などの機能を追加します。
Screenshot
Advertisement
サンプルコード
class TextComponentMouseHandler extends MouseAdapter {
private final AtomicInteger count = new AtomicInteger(0);
private final Timer holdTimer = new Timer(1000, null);
private final List<String> list = Arrays.asList(
DefaultEditorKit.selectWordAction,
DefaultEditorKit.selectLineAction,
DefaultEditorKit.selectParagraphAction,
DefaultEditorKit.selectAllAction);
protected TextComponentMouseHandler(JTextComponent textArea) {
super();
holdTimer.setInitialDelay(500);
holdTimer.addActionListener(e -> {
Timer timer = (Timer) e.getSource();
if (timer.isRunning()) {
int i = count.getAndIncrement();
if (i < list.size()) {
String cmd = list.get(i);
textArea.getActionMap().get(cmd).actionPerformed(e);
} else {
timer.stop();
count.set(0);
}
}
});
}
@Override public void mousePressed(MouseEvent e) {
boolean isSingleClick = e.getClickCount() == 1;
if (isSingleClick) {
JTextComponent textArea = (JTextComponent) e.getComponent();
if (!textArea.hasFocus()) {
textArea.requestFocusInWindow();
}
if (textArea.getSelectedText() == null) {
// Java 9: int pos = textArea.viewToModel2D(e.getPoint());
int pos = textArea.viewToModel(e.getPoint());
textArea.setCaretPosition(pos);
}
if (e.getButton() == MouseEvent.BUTTON1) {
holdTimer.start();
}
}
}
@Override public void mouseReleased(MouseEvent e) {
holdTimer.stop();
count.set(0);
}
@Override public void mouseDragged(MouseEvent e) {
mouseReleased(e);
}
}
View in GitHub: Java, Kotlin解説
- マウス左ボタンの長押し
1.5
秒後にgetActionMap().get(DefaultEditorKit.selectWordAction)
アクションを実行して単語選択- 左ボタンの長押しが継続している場合は
2.5
秒後にgetActionMap().get(DefaultEditorKit.selectLineAction)
アクションを実行して行選択 3.5
秒後にgetActionMap().get(DefaultEditorKit.selectParagraphAction)
アクションを実行してパラグラフ選択4.5
秒後にgetActionMap().get(DefaultEditorKit.selectAllAction)
アクションを実行して全選択- 以降はタイマーをストップ
MouseListener#mousePressed(...)
をオーバーライド- シングルクリック、かつ
JTextArea
にフォーカスが存在しない場合は右、中ボタンでもJTextArea#requestFocusInWindow()
を実行してフォーカスを取得- また文字列選択されていない場合は右、中ボタンでもキャレットをクリック位置に移動
- 左ボタンのシングルクリックの場合は長押しのタイマーを起動
- デフォルトのダブルクリックには単語選択が割り当てられているのでこれに干渉しないよう注意が必要
- シングルクリック、かつ
MouseListener#mouseReleased(...)
、MouseMotionListener#mouseDragged(...)
をオーバーライド- 長押しのタイマーを停止、リセット