Merge pull request #1953 from SiboVG/issue-1942
[#1942] Fix text component selection key behavior
This commit is contained in:
		
						commit
						d60045baca
					
				| @ -1,5 +1,7 @@ | |||||||
| package net.sf.openrocket.gui; | package net.sf.openrocket.gui; | ||||||
| 
 | 
 | ||||||
|  | import net.sf.openrocket.gui.adaptors.TextComponentSelectionKeyListener; | ||||||
|  | 
 | ||||||
| import javax.swing.JSpinner; | import javax.swing.JSpinner; | ||||||
| import javax.swing.JTextField; | import javax.swing.JTextField; | ||||||
| import javax.swing.SwingUtilities; | import javax.swing.SwingUtilities; | ||||||
| @ -7,8 +9,8 @@ import javax.swing.text.DefaultFormatter; | |||||||
| import javax.swing.text.DefaultFormatterFactory; | import javax.swing.text.DefaultFormatterFactory; | ||||||
| import java.awt.event.FocusEvent; | import java.awt.event.FocusEvent; | ||||||
| import java.awt.event.FocusListener; | import java.awt.event.FocusListener; | ||||||
|  | import java.awt.event.MouseAdapter; | ||||||
| import java.awt.event.MouseEvent; | import java.awt.event.MouseEvent; | ||||||
| import java.awt.event.MouseListener; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Editable editor for a JSpinner.  Simply uses JSpinner.DefaultEditor, which has been made |  * 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(); | 		DefaultFormatter formatter = (DefaultFormatter) dff.getDefaultFormatter(); | ||||||
| 		formatter.setOverwriteMode(false); | 		formatter.setOverwriteMode(false); | ||||||
| 
 | 
 | ||||||
| 
 | 		addListeners(); | ||||||
| 		// 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) { |  | ||||||
| 				} |  | ||||||
| 			}); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| @ -93,14 +44,54 @@ public class SpinnerEditor extends JSpinner.DefaultEditor { | |||||||
| 		getTextField().setColumns(cols); | 		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. | 	 * Highlights all the text in the text field. | ||||||
| 	 */ | 	 */ | ||||||
| 	private void selectAllText() { | 	private void selectAllText(JTextField tf) { | ||||||
| 		SwingUtilities.invokeLater(new Runnable() { | 		SwingUtilities.invokeLater(new Runnable() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public void run() { | 			public void run() { | ||||||
| 				getTextField().selectAll(); | 				tf.selectAll(); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -5,7 +5,10 @@ import java.awt.Color; | |||||||
| import java.awt.Component; | import java.awt.Component; | ||||||
| import java.awt.Container; | import java.awt.Container; | ||||||
| import java.awt.Font; | 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.ArrayList; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| import java.util.List; | 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.DoubleModel; | ||||||
| import net.sf.openrocket.gui.adaptors.IntegerModel; | import net.sf.openrocket.gui.adaptors.IntegerModel; | ||||||
| import net.sf.openrocket.gui.adaptors.PresetModel; | 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.BasicSlider; | ||||||
| import net.sf.openrocket.gui.components.StyledLabel; | import net.sf.openrocket.gui.components.StyledLabel; | ||||||
| import net.sf.openrocket.gui.components.StyledLabel.Style; | import net.sf.openrocket.gui.components.StyledLabel.Style; | ||||||
| @ -114,6 +118,7 @@ public class RocketComponentConfig extends JPanel { | |||||||
| 		textFieldListener = new TextFieldListener(); | 		textFieldListener = new TextFieldListener(); | ||||||
| 		componentNameField.addActionListener(textFieldListener); | 		componentNameField.addActionListener(textFieldListener); | ||||||
| 		componentNameField.addFocusListener(textFieldListener); | 		componentNameField.addFocusListener(textFieldListener); | ||||||
|  | 		componentNameField.addKeyListener(new TextComponentSelectionKeyListener(componentNameField)); | ||||||
| 		//// The component name. | 		//// The component name. | ||||||
| 		componentNameField.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip")); | 		componentNameField.setToolTipText(trans.get("RocketCompCfg.lbl.Componentname.ttip")); | ||||||
| 		this.add(componentNameField, "growx"); | 		this.add(componentNameField, "growx"); | ||||||
| @ -603,6 +608,7 @@ public class RocketComponentConfig extends JPanel { | |||||||
| 		commentTextArea.setEditable(true); | 		commentTextArea.setEditable(true); | ||||||
| 		GUIUtil.setTabToFocusing(commentTextArea); | 		GUIUtil.setTabToFocusing(commentTextArea); | ||||||
| 		commentTextArea.addFocusListener(textFieldListener); | 		commentTextArea.addFocusListener(textFieldListener); | ||||||
|  | 		commentTextArea.addKeyListener(new TextComponentSelectionKeyListener(commentTextArea)); | ||||||
| 		 | 		 | ||||||
| 		panel.add(new JScrollPane(commentTextArea), "grow"); | 		panel.add(new JScrollPane(commentTextArea), "grow"); | ||||||
| 		order.add(commentTextArea); | 		order.add(commentTextArea); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user