diff --git a/swing/src/net/sf/openrocket/gui/SpinnerEditor.java b/swing/src/net/sf/openrocket/gui/SpinnerEditor.java index d02997e3d..fe6956b71 100644 --- a/swing/src/net/sf/openrocket/gui/SpinnerEditor.java +++ b/swing/src/net/sf/openrocket/gui/SpinnerEditor.java @@ -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(); } }); } diff --git a/swing/src/net/sf/openrocket/gui/adaptors/TextComponentSelectionKeyListener.java b/swing/src/net/sf/openrocket/gui/adaptors/TextComponentSelectionKeyListener.java new file mode 100644 index 000000000..3d0addbf2 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/adaptors/TextComponentSelectionKeyListener.java @@ -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...). + *
+ * 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); + } + } + } +} diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 1cf1bdbf0..c64590bda 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -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);