TextComponents: triple-click-and-drag now extends selection by whole lines

triple-click-and-drag does not work in theme editor because drag is enabled, anyway a triple-click now selects the whole line before dragging starts
This commit is contained in:
Karl Tauber
2021-10-22 13:14:01 +02:00
parent e13fb25f14
commit 8fa1eae352
5 changed files with 165 additions and 70 deletions

View File

@@ -15,7 +15,8 @@ FlatLaf Change Log
- TextField, FormattedTextField and PasswordField: Support leading and trailing - TextField, FormattedTextField and PasswordField: Support leading and trailing
icons (set client property `JTextField.leadingIcon` or icons (set client property `JTextField.leadingIcon` or
`JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368) `JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368)
- TextComponents: Double-click-and-drag now extends selection by whole words. - TextComponents: Double/triple-click-and-drag now extends selection by whole
words/lines.
- Theming improvements: Reworks core themes to make it easier to create new - Theming improvements: Reworks core themes to make it easier to create new
themes (e.g. reduced explicit colors by using color functions). **Note**: themes (e.g. reduced explicit colors by using color functions). **Note**:
There are minor incompatible changes in FlatLaf properties files. (PR #390) There are minor incompatible changes in FlatLaf properties files. (PR #390)

View File

@@ -19,14 +19,18 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultCaret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document; import javax.swing.text.Document;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import javax.swing.text.Utilities; import javax.swing.text.Utilities;
@@ -52,8 +56,9 @@ public class FlatCaret
private boolean wasTemporaryLost; private boolean wasTemporaryLost;
private boolean isMousePressed; private boolean isMousePressed;
private boolean isWordSelection; private boolean isWordSelection;
private int beginInitialWord; private boolean isLineSelection;
private int endInitialWord; private int dragSelectionStart;
private int dragSelectionEnd;
public FlatCaret( String selectAllOnFocusPolicy, boolean selectAllOnMouseClick ) { public FlatCaret( String selectAllOnFocusPolicy, boolean selectAllOnMouseClick ) {
this.selectAllOnFocusPolicy = selectAllOnFocusPolicy; this.selectAllOnFocusPolicy = selectAllOnFocusPolicy;
@@ -153,11 +158,34 @@ public class FlatCaret
isMousePressed = true; isMousePressed = true;
super.mousePressed( e ); super.mousePressed( e );
JTextComponent c = getComponent();
// left double-click starts word selection // left double-click starts word selection
isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed(); isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed();
if( isWordSelection ) {
beginInitialWord = getMark(); // left triple-click starts line selection
endInitialWord = getDot(); 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 );
} }
} }
@@ -165,33 +193,29 @@ public class FlatCaret
public void mouseReleased( MouseEvent e ) { public void mouseReleased( MouseEvent e ) {
isMousePressed = false; isMousePressed = false;
isWordSelection = false; isWordSelection = false;
isLineSelection = false;
super.mouseReleased( e ); super.mouseReleased( e );
} }
@Override @Override
public void mouseDragged( MouseEvent e ) { public void mouseDragged( MouseEvent e ) {
if( isWordSelection && !e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) ) { if( (isWordSelection || isLineSelection) &&
// fix Swing's double-click-and-drag behavior so that dragging after !e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) )
// a double-click extends selection by whole words {
// 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(); JTextComponent c = getComponent();
int pos = c.viewToModel( e.getPoint() ); int pos = c.viewToModel( e.getPoint() );
if( pos < 0 ) if( pos < 0 )
return; return;
try { try {
int mark; if( pos > dragSelectionEnd )
int dot; select( dragSelectionStart, isWordSelection ? Utilities.getWordEnd( c, pos ) : Utilities.getRowEnd( c, pos ) );
if( pos > endInitialWord ) { else if( pos < dragSelectionStart )
mark = beginInitialWord; select( dragSelectionEnd, isWordSelection ? Utilities.getWordStart( c, pos ) : Utilities.getRowStart( c, pos ) );
dot = Utilities.getWordEnd( c, pos ); else
} else if( pos < beginInitialWord ) { select( dragSelectionStart, dragSelectionEnd );
mark = endInitialWord;
dot = Utilities.getWordStart( c, pos );
} else {
mark = beginInitialWord;
dot = endInitialWord;
}
select( mark, dot );
} catch( BadLocationException ex ) { } catch( BadLocationException ex ) {
UIManager.getLookAndFeel().provideErrorFeedback( c ); UIManager.getLookAndFeel().provideErrorFeedback( c );
} }

View File

@@ -81,6 +81,14 @@ public class FlatTextComponentsTest
} }
} }
private void dragEnabledChanged() {
boolean dragEnabled = dragEnabledCheckBox.isSelected();
textField.setDragEnabled( dragEnabled );
textArea.setDragEnabled( dragEnabled );
textPane.setDragEnabled( dragEnabled );
editorPane.setDragEnabled( dragEnabled );
}
private void initComponents() { private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JLabel textFieldLabel = new JLabel(); JLabel textFieldLabel = new JLabel();
@@ -138,14 +146,15 @@ public class FlatTextComponentsTest
JComboBox<String> comboBox6 = new JComboBox<>(); JComboBox<String> comboBox6 = new JComboBox<>();
JSpinner spinner5 = new JSpinner(); JSpinner spinner5 = new JSpinner();
JLabel label5 = new JLabel(); JLabel label5 = new JLabel();
JTextField textField4 = new JTextField(); textField = new JTextField();
dragEnabledCheckBox = new JCheckBox();
JLabel label6 = new JLabel(); JLabel label6 = new JLabel();
JScrollPane scrollPane2 = new JScrollPane(); JScrollPane scrollPane2 = new JScrollPane();
JTextArea textArea2 = new JTextArea(); textArea = new JTextArea();
JScrollPane scrollPane4 = new JScrollPane(); JScrollPane scrollPane4 = new JScrollPane();
JTextPane textPane4 = new JTextPane(); textPane = new JTextPane();
JScrollPane scrollPane6 = new JScrollPane(); JScrollPane scrollPane6 = new JScrollPane();
JEditorPane editorPane5 = new JEditorPane(); editorPane = new JEditorPane();
JPopupMenu popupMenu1 = new JPopupMenu(); JPopupMenu popupMenu1 = new JPopupMenu();
JMenuItem cutMenuItem = new JMenuItem(); JMenuItem cutMenuItem = new JMenuItem();
JMenuItem copyMenuItem = new JMenuItem(); JMenuItem copyMenuItem = new JMenuItem();
@@ -535,10 +544,16 @@ public class FlatTextComponentsTest
label5.setName("label5"); label5.setName("label5");
add(label5, "cell 0 16"); add(label5, "cell 0 16");
//---- textField4 ---- //---- textField ----
textField4.setText("123 456 789 abc def"); textField.setText("123 456 789 abc def");
textField4.setName("textField4"); textField.setName("textField");
add(textField4, "cell 1 16 2 1,growx"); add(textField, "cell 1 16 2 1,growx");
//---- dragEnabledCheckBox ----
dragEnabledCheckBox.setText("Drag enabled");
dragEnabledCheckBox.setName("dragEnabledCheckBox");
dragEnabledCheckBox.addActionListener(e -> dragEnabledChanged());
add(dragEnabledCheckBox, "cell 3 16 2 1,alignx left,growx 0");
//---- label6 ---- //---- label6 ----
label6.setText("<html>JTextArea<br>JTextPane<br>JEditorPane</html>"); label6.setText("<html>JTextArea<br>JTextPane<br>JEditorPane</html>");
@@ -549,10 +564,10 @@ public class FlatTextComponentsTest
{ {
scrollPane2.setName("scrollPane2"); scrollPane2.setName("scrollPane2");
//---- textArea2 ---- //---- textArea ----
textArea2.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"); textArea.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def");
textArea2.setName("textArea2"); textArea.setName("textArea");
scrollPane2.setViewportView(textArea2); scrollPane2.setViewportView(textArea);
} }
add(scrollPane2, "cell 1 17 4 1,growx"); add(scrollPane2, "cell 1 17 4 1,growx");
@@ -560,10 +575,10 @@ public class FlatTextComponentsTest
{ {
scrollPane4.setName("scrollPane4"); scrollPane4.setName("scrollPane4");
//---- textPane4 ---- //---- textPane ----
textPane4.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"); textPane.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def");
textPane4.setName("textPane4"); textPane.setName("textPane");
scrollPane4.setViewportView(textPane4); scrollPane4.setViewportView(textPane);
} }
add(scrollPane4, "cell 1 17 4 1,growx"); add(scrollPane4, "cell 1 17 4 1,growx");
@@ -571,10 +586,10 @@ public class FlatTextComponentsTest
{ {
scrollPane6.setName("scrollPane6"); scrollPane6.setName("scrollPane6");
//---- editorPane5 ---- //---- editorPane ----
editorPane5.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"); editorPane.setText("1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def");
editorPane5.setName("editorPane5"); editorPane.setName("editorPane");
scrollPane6.setViewportView(editorPane5); scrollPane6.setViewportView(editorPane);
} }
add(scrollPane6, "cell 1 17 4 1,growx"); add(scrollPane6, "cell 1 17 4 1,growx");
@@ -612,6 +627,11 @@ public class FlatTextComponentsTest
private JSpinner bottomPaddingField; private JSpinner bottomPaddingField;
private JCheckBox leadingIconCheckBox; private JCheckBox leadingIconCheckBox;
private JCheckBox trailingIconCheckBox; private JCheckBox trailingIconCheckBox;
private JTextField textField;
private JCheckBox dragEnabledCheckBox;
private JTextArea textArea;
private JTextPane textPane;
private JEditorPane editorPane;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- TestIcon ----------------------------------------------------------- //---- TestIcon -----------------------------------------------------------

View File

@@ -423,11 +423,24 @@ new FormModel {
"value": "cell 0 16" "value": "cell 0 16"
} ) } )
add( new FormComponent( "javax.swing.JTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "textField4" name: "textField"
"text": "123 456 789 abc def" "text": "123 456 789 abc def"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 2 1,growx" "value": "cell 1 16 2 1,growx"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "dragEnabledCheckBox"
"text": "Drag enabled"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dragEnabledChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 16 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6" name: "label6"
"text": "<html>JTextArea<br>JTextPane<br>JEditorPane</html>" "text": "<html>JTextArea<br>JTextPane<br>JEditorPane</html>"
@@ -437,8 +450,11 @@ new FormModel {
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane2" name: "scrollPane2"
add( new FormComponent( "javax.swing.JTextArea" ) { add( new FormComponent( "javax.swing.JTextArea" ) {
name: "textArea2" name: "textArea"
"text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def" "text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 4 1,growx" "value": "cell 1 17 4 1,growx"
@@ -446,8 +462,11 @@ new FormModel {
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane4" name: "scrollPane4"
add( new FormComponent( "javax.swing.JTextPane" ) { add( new FormComponent( "javax.swing.JTextPane" ) {
name: "textPane4" name: "textPane"
"text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def" "text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 4 1,growx" "value": "cell 1 17 4 1,growx"
@@ -455,8 +474,11 @@ new FormModel {
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "scrollPane6" name: "scrollPane6"
add( new FormComponent( "javax.swing.JEditorPane" ) { add( new FormComponent( "javax.swing.JEditorPane" ) {
name: "editorPane5" name: "editorPane"
"text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def" "text": "1 123 456 789 abc def\n2 123 456 789 abc def\n3 123 456 789 abc def\n4 123 456 789 abc def\n5 123 456 789 abc def\n6 123 456 789 abc def\n7 123 456 789 abc def\n8 123 456 789 abc def"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 4 1,growx" "value": "cell 1 17 4 1,growx"

View File

@@ -18,12 +18,16 @@ package com.formdev.flatlaf.themeeditor;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.Caret; import javax.swing.text.Caret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import javax.swing.text.Utilities; import javax.swing.text.Utilities;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI; import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI;
@@ -70,59 +74,83 @@ class FlatRSyntaxTextAreaUI
extends ConfigurableCaret extends ConfigurableCaret
{ {
private boolean isWordSelection; private boolean isWordSelection;
private int beginInitialWord; private boolean isLineSelection;
private int endInitialWord; private int dragSelectionStart;
private int dragSelectionEnd;
@Override @Override
public void mousePressed( MouseEvent e ) { public void mousePressed( MouseEvent e ) {
super.mousePressed( e ); super.mousePressed( e );
JTextComponent c = getComponent();
// left double-click starts word selection // left double-click starts word selection
isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed(); isWordSelection = e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) && !e.isConsumed();
if( isWordSelection ) {
beginInitialWord = getMark(); // left triple-click starts line selection
endInitialWord = getDot(); 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 @Override
public void mouseReleased( MouseEvent e ) { public void mouseReleased( MouseEvent e ) {
isWordSelection = false; isWordSelection = false;
isLineSelection = false;
super.mouseReleased( e ); super.mouseReleased( e );
} }
@Override @Override
public void mouseDragged( MouseEvent e ) { public void mouseDragged( MouseEvent e ) {
if( isWordSelection && !e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) ) { if( (isWordSelection || isLineSelection) &&
// fix Swing's double-click-and-drag behavior so that dragging after !e.isConsumed() && SwingUtilities.isLeftMouseButton( e ) )
// a double-click extends selection by whole words {
// 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(); JTextComponent c = getComponent();
int pos = c.viewToModel( e.getPoint() ); int pos = c.viewToModel( e.getPoint() );
if( pos < 0 ) if( pos < 0 )
return; return;
try { try {
int mark; if( pos > dragSelectionEnd )
int dot; select( dragSelectionStart, isWordSelection ? Utilities.getWordEnd( c, pos ) : Utilities.getRowEnd( c, pos ) );
if( pos > endInitialWord ) { else if( pos < dragSelectionStart )
mark = beginInitialWord; select( dragSelectionEnd, isWordSelection ? Utilities.getWordStart( c, pos ) : Utilities.getRowStart( c, pos ) );
dot = Utilities.getWordEnd( c, pos ); else
} else if( pos < beginInitialWord ) { select( dragSelectionStart, dragSelectionEnd );
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 ) { } catch( BadLocationException ex ) {
UIManager.getLookAndFeel().provideErrorFeedback( c ); UIManager.getLookAndFeel().provideErrorFeedback( c );
} }
} else } else
super.mouseDragged( e ); super.mouseDragged( e );
} }
private void select( int mark, int dot ) {
if( mark != getMark() )
setDot( mark );
if( dot != getDot() )
moveDot( dot );
}
} }
} }