[#1942] Fix text component selection key behavior

This commit is contained in:
SiboVG 2023-01-06 14:30:28 +01:00
parent ede9dfe700
commit cdfac5f649
3 changed files with 96 additions and 56 deletions

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.gui;
import net.sf.openrocket.gui.adaptors.TextComponentSelectionKeyListener;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
@ -7,8 +9,8 @@ import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Editable editor for a JSpinner. Simply uses JSpinner.DefaultEditor, which has been made
@ -29,58 +31,7 @@ public class SpinnerEditor extends JSpinner.DefaultEditor {
DefaultFormatter formatter = (DefaultFormatter) dff.getDefaultFormatter();
formatter.setOverwriteMode(false);
// Add listeners to select all the text when the field is focussed
{
getTextField().addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
selectAllText();
}
@Override
public void focusLost(FocusEvent e) {
}
});
getTextField().addMouseListener(new MouseListener() {
private boolean isFocussed = false; // Checks whether the text field was focussed when it was clicked upon
@Override
public void mouseClicked(MouseEvent e) {
// If the text field was focussed when it was clicked upon instead of e.g. tab-switching to gain focus,
// then the select all action from the focus listener is ignored (it is replaced by a cursor-click event).
// So if we detect such a focus change, then redo the select all action.
if (!isFocussed) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTextField tf = (JTextField) e.getSource();
tf.selectAll();
}
});
}
}
@Override
public void mousePressed(MouseEvent e) {
JTextField tf = (JTextField) e.getSource();
isFocussed = tf.hasFocus();
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
}
addListeners();
}
/**
@ -93,14 +44,54 @@ public class SpinnerEditor extends JSpinner.DefaultEditor {
getTextField().setColumns(cols);
}
private void addListeners() {
// Select all the text when the field is focussed
getTextField().addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
selectAllText(getTextField());
}
@Override
public void focusLost(FocusEvent e) {
}
});
// Select all the text when the field is first clicked upon
getTextField().addMouseListener(new MouseAdapter() {
private boolean isFocussed = false; // Checks whether the text field was focussed when it was clicked upon
@Override
public void mouseClicked(MouseEvent e) {
/*
If the text field was focussed when it was clicked upon instead of e.g. tab-switching to gain focus,
then the select all action from the focus listener is ignored (it is replaced by a cursor-click event).
So if we detect such a focus change, then redo the select all action.
*/
if (!isFocussed) {
selectAllText((JTextField) e.getSource());
}
}
@Override
public void mousePressed(MouseEvent e) {
JTextField tf = (JTextField) e.getSource();
isFocussed = tf.hasFocus();
}
});
// Fix key behavior on text selection
getTextField().addKeyListener(new TextComponentSelectionKeyListener(getTextField()));
}
/**
* Highlights all the text in the text field.
*/
private void selectAllText() {
private void selectAllText(JTextField tf) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getTextField().selectAll();
tf.selectAll();
}
});
}

View File

@ -0,0 +1,43 @@
package net.sf.openrocket.gui.adaptors;
import javax.swing.text.JTextComponent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* This key listener fixes a default behavior by Java Swing text components, where if you select a text, pressing the
* left or right arrow key would not bring the text cursor to the beginning or the end of the selection
* (@Java, please fix...).
* <p>
* This listener's behavior:
* If some text of the editor is selected, set the caret position to:
* - the end of the selection if the user presses the right arrow key
* - the beginning of the selection if the user presses the left arrow key
*/
public class TextComponentSelectionKeyListener extends KeyAdapter {
private final JTextComponent textField;
public TextComponentSelectionKeyListener(JTextComponent textField) {
this.textField = textField;
}
@Override
public void keyPressed(KeyEvent e) {
if (e.isShiftDown()) {
return;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_KP_LEFT) {
int start = textField.getSelectionStart();
int end = textField.getSelectionEnd();
if (end > start) {
textField.setCaretPosition(start + 1);
}
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_KP_RIGHT) {
int start = textField.getSelectionStart();
int end = textField.getSelectionEnd();
if (end > start) {
textField.setCaretPosition(end - 1);
}
}
}
}

View File

@ -5,7 +5,10 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -35,6 +38,7 @@ import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.adaptors.PresetModel;
import net.sf.openrocket.gui.adaptors.TextComponentSelectionKeyListener;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
@ -114,6 +118,7 @@ public class RocketComponentConfig extends JPanel {
textFieldListener = new TextFieldListener();
componentNameField.addActionListener(textFieldListener);
componentNameField.addFocusListener(textFieldListener);
componentNameField.addKeyListener(new TextComponentSelectionKeyListener(componentNameField));
//// The component name.
componentNameField.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip"));
this.add(componentNameField, "growx");
@ -603,6 +608,7 @@ public class RocketComponentConfig extends JPanel {
commentTextArea.setEditable(true);
GUIUtil.setTabToFocusing(commentTextArea);
commentTextArea.addFocusListener(textFieldListener);
commentTextArea.addKeyListener(new TextComponentSelectionKeyListener(commentTextArea));
panel.add(new JScrollPane(commentTextArea), "grow");
order.add(commentTextArea);