TextComponents: double-click-and-drag now extends selection by whole words

This commit is contained in:
Karl Tauber
2021-10-21 13:24:07 +02:00
parent f8b9f4c1fa
commit e36f942129
8 changed files with 254 additions and 5 deletions

View File

@@ -22,14 +22,19 @@ import java.awt.Rectangle;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import javax.swing.JFormattedTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Utilities;
/**
* Caret that can select all text on focus gained.
* Also fixes Swing's double-click-and-drag behavior so that dragging after
* a double-click extends selection by whole words.
*
* @author Karl Tauber
*/
@@ -43,6 +48,9 @@ public class FlatCaret
private boolean wasFocused;
private boolean wasTemporaryLost;
private boolean isMousePressed;
private boolean isWordSelection;
private int beginInitialWord;
private int endInitialWord;
public FlatCaret( String selectAllOnFocusPolicy, boolean selectAllOnMouseClick ) {
this.selectAllOnFocusPolicy = selectAllOnFocusPolicy;
@@ -97,14 +105,56 @@ public class FlatCaret
public void mousePressed( MouseEvent e ) {
isMousePressed = true;
super.mousePressed( e );
// left double-click starts word selection
isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed();
if( isWordSelection ) {
beginInitialWord = getMark();
endInitialWord = getDot();
}
}
@Override
public void mouseReleased( MouseEvent e ) {
isMousePressed = false;
isWordSelection = false;
super.mouseReleased( e );
}
@Override
public void mouseDragged( MouseEvent e ) {
if( isWordSelection && !e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) ) {
// fix Swing's double-click-and-drag behavior so that dragging after
// a double-click extends selection by whole words
JTextComponent c = getComponent();
int pos = c.viewToModel( e.getPoint() );
if( pos < 0 )
return;
try {
int mark;
int dot;
if( pos > endInitialWord ) {
mark = beginInitialWord;
dot = Utilities.getWordEnd( c, pos );
} else if( pos < beginInitialWord ) {
mark = endInitialWord;
dot = Utilities.getWordStart( c, pos );
} else {
mark = beginInitialWord;
dot = endInitialWord;
}
if( mark != getMark() )
setDot( mark );
if( dot != getDot() )
moveDot( dot );
} catch( BadLocationException ex ) {
UIManager.getLookAndFeel().provideErrorFeedback( c );
}
} else
super.mouseDragged( e );
}
protected void selectAllOnFocusGained() {
JTextComponent c = getComponent();
Document doc = c.getDocument();

View File

@@ -30,6 +30,7 @@ import javax.swing.JEditorPane;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicEditorPaneUI;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
@@ -147,6 +148,11 @@ public class FlatEditorPaneUI
focusListener = null;
}
@Override
protected Caret createCaret() {
return new FlatCaret( null, false );
}
@Override
protected void propertyChange( PropertyChangeEvent e ) {
// invoke updateBackground() before super.propertyChange()

View File

@@ -29,6 +29,7 @@ import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextAreaUI;
import javax.swing.text.Caret;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.HiDPIUtils;
@@ -136,6 +137,11 @@ public class FlatTextAreaUI
focusListener = null;
}
@Override
protected Caret createCaret() {
return new FlatCaret( null, false );
}
@Override
protected void propertyChange( PropertyChangeEvent e ) {
// invoke updateBackground() before super.propertyChange()

View File

@@ -29,6 +29,7 @@ import javax.swing.JEditorPane;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextPaneUI;
import javax.swing.text.Caret;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.HiDPIUtils;
@@ -144,6 +145,11 @@ public class FlatTextPaneUI
focusListener = null;
}
@Override
protected Caret createCaret() {
return new FlatCaret( null, false );
}
@Override
protected void propertyChange( PropertyChangeEvent e ) {
// invoke updateBackground() before super.propertyChange()