mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
Merge PR #401: Text components: double/triple-click-and-drag selection improvements
This commit is contained in:
@@ -18,9 +18,20 @@ package com.formdev.flatlaf.themeeditor;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Caret;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Utilities;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI;
|
||||
import org.fife.ui.rtextarea.ConfigurableCaret;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -32,6 +43,13 @@ class FlatRSyntaxTextAreaUI
|
||||
super( rSyntaxTextArea );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Caret createCaret() {
|
||||
Caret caret = new FlatConfigurableCaret();
|
||||
caret.setBlinkRate( 500 );
|
||||
return caret;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintCurrentLineHighlight( Graphics g, Rectangle visibleRect ) {
|
||||
if( !textArea.getHighlightCurrentLine() )
|
||||
@@ -49,4 +67,90 @@ class FlatRSyntaxTextAreaUI
|
||||
super.paintCurrentLineHighlight( g, visibleRect );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatConfigurableCaret ----------------------------------------
|
||||
|
||||
private static class FlatConfigurableCaret
|
||||
extends ConfigurableCaret
|
||||
{
|
||||
private boolean isWordSelection;
|
||||
private boolean isLineSelection;
|
||||
private int dragSelectionStart;
|
||||
private int dragSelectionEnd;
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
super.mousePressed( e );
|
||||
|
||||
JTextComponent c = getComponent();
|
||||
|
||||
// left double-click starts word selection
|
||||
isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed();
|
||||
|
||||
// left triple-click starts line selection
|
||||
isLineSelection = e.getClickCount() == 3 && SwingUtilities.isLeftMouseButton( e ) && (!e.isConsumed() || c.getDragEnabled());
|
||||
|
||||
// select line
|
||||
// (this is also done in DefaultCaret.mouseClicked(), but this event is
|
||||
// sent when the mouse is released, which is too late for triple-click-and-drag)
|
||||
if( isLineSelection ) {
|
||||
ActionMap actionMap = c.getActionMap();
|
||||
Action selectLineAction = (actionMap != null)
|
||||
? actionMap.get( DefaultEditorKit.selectLineAction )
|
||||
: null;
|
||||
if( selectLineAction != null ) {
|
||||
selectLineAction.actionPerformed( new ActionEvent( c,
|
||||
ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers() ) );
|
||||
}
|
||||
}
|
||||
|
||||
// remember selection where word/line selection starts to keep it always selected while dragging
|
||||
if( isWordSelection || isLineSelection ) {
|
||||
int mark = getMark();
|
||||
int dot = getDot();
|
||||
dragSelectionStart = Math.min( dot, mark );
|
||||
dragSelectionEnd = Math.max( dot, mark );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
isWordSelection = false;
|
||||
isLineSelection = false;
|
||||
super.mouseReleased( e );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged( MouseEvent e ) {
|
||||
if( (isWordSelection || isLineSelection) &&
|
||||
!e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) )
|
||||
{
|
||||
// fix Swing's double/triple-click-and-drag behavior so that dragging after
|
||||
// a double/triple-click extends selection by whole words/lines
|
||||
JTextComponent c = getComponent();
|
||||
int pos = c.viewToModel( e.getPoint() );
|
||||
if( pos < 0 )
|
||||
return;
|
||||
|
||||
try {
|
||||
if( pos > dragSelectionEnd )
|
||||
select( dragSelectionStart, isWordSelection ? Utilities.getWordEnd( c, pos ) : Utilities.getRowEnd( c, pos ) );
|
||||
else if( pos < dragSelectionStart )
|
||||
select( dragSelectionEnd, isWordSelection ? Utilities.getWordStart( c, pos ) : Utilities.getRowStart( c, pos ) );
|
||||
else
|
||||
select( dragSelectionStart, dragSelectionEnd );
|
||||
} catch( BadLocationException ex ) {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback( c );
|
||||
}
|
||||
} else
|
||||
super.mouseDragged( e );
|
||||
}
|
||||
|
||||
private void select( int mark, int dot ) {
|
||||
if( mark != getMark() )
|
||||
setDot( mark );
|
||||
if( dot != getDot() )
|
||||
moveDot( dot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user