⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keysequencetext.java

📁 jfa2ce 源码帮助开发人员更好的理解运用
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	/** An empty string instance for use in clearing text values. */	private static final String EMPTY_STRING = ""; //$NON-NLS-1$	/**	 * The special integer value for the maximum number of strokes indicating	 * that an infinite number should be allowed.	 */	public static final int INFINITE = -1;	/**	 * The name of the property representing the current key sequence in this	 * key sequence widget.	 * 	 * @since 3.2	 */	public static final String P_KEY_SEQUENCE = "org.eclipse.jface.bindings.keys.KeySequenceText.KeySequence"; //$NON-NLS-1$	/**	 * The keys trapped by this widget. This list is guaranteed to be roughly	 * accurate. Perfection is not possible, as SWT does not export traversal	 * keys as constants.	 */	public static final List TRAPPED_KEYS;	/**	 * The key filter attached to the underlying widget that traps key events.	 */	private final KeyTrapListener keyFilter = new KeyTrapListener();	/**	 * The text of the key sequence -- containing only the complete key strokes.	 */	private KeySequence keySequence = KeySequence.getInstance();	/**	 * Those listening to changes to the key sequence in this widget. This value	 * may be <code>null</code> if there are no listeners.	 */	private Collection listeners = null;	/** The maximum number of key strokes permitted in the sequence. */	private int maxStrokes = INFINITE;	/** The text widget that is wrapped for this class. */	private final Text text;	/**	 * The listener that makes sure that the text widget remains up-to-date with	 * regards to external modification of the text (e.g., cut & pasting).	 */	private final UpdateSequenceListener updateSequenceListener = new UpdateSequenceListener();	/**	 * Constructs an instance of <code>KeySequenceTextField</code> with the	 * text field to use. If the platform is carbon (MacOS X), then the font is	 * set to be the same font used to display accelerators in the menus.	 * 	 * @param wrappedText	 *            The text widget to wrap; must not be <code>null</code>.	 */	public KeySequenceText(Text wrappedText) {		text = wrappedText;		// Set the font if the platform is carbon.		if ("carbon".equals(SWT.getPlatform())) { //$NON-NLS-1$			// Don't worry about this font name here; it is the official menu			// font and point size on the Mac.			final Font font = new Font(text.getDisplay(),					"Lucida Grande", 13, SWT.NORMAL); //$NON-NLS-1$			text.setFont(font);			text.addDisposeListener(new DisposeListener() {				public void widgetDisposed(DisposeEvent e) {					font.dispose();				}			});		}		// Add the key listener.		text.addListener(SWT.KeyUp, keyFilter);		text.addListener(SWT.KeyDown, keyFilter);		// Add the focus listener that attaches the global traversal filter.		text.addFocusListener(new TraversalFilterManager());		// Add an internal modify listener.		text.addModifyListener(updateSequenceListener);	}	/**	 * Adds a property change listener to this key sequence widget. It will be	 * notified when the key sequence changes.	 * 	 * @param listener	 *            The listener to be notified when changes occur; must not be	 *            <code>null</code>.	 * @since 3.2	 */	public final void addPropertyChangeListener(			final IPropertyChangeListener listener) {		if (listener == null) {			return;		}		if (listeners == null) {			listeners = new ArrayList(1);		}		listeners.add(listener);	}	/**	 * Clears the text field and resets all the internal values.	 */	public void clear() {		final KeySequence oldKeySequence = keySequence;		keySequence = KeySequence.getInstance();		text.setText(EMPTY_STRING);		firePropertyChangeEvent(oldKeySequence);	}	/**	 * Removes the key strokes from the list corresponding the selection. If	 * <code>allowIncomplete</code>, then invalid key sequences will be	 * allowed (i.e., those with incomplete strokes in the non-terminal	 * position). Otherwise, incomplete strokes will be removed. This modifies	 * <code>keyStrokes</code> in place, and has no effect on the text widget	 * this class wraps.	 * 	 * @param keyStrokes	 *            The list of key strokes from which the selection should be	 *            removed; must not be <code>null</code>.	 * @param allowIncomplete	 *            Whether incomplete strokes should be allowed to exist in the	 *            list after the deletion.	 * @return The index at which a subsequent insert should occur. This index	 *         only has meaning to the <code>insertStrokeAt</code> method.	 */	private final int deleteSelection(final KeyStroke[] keyStrokes,			final boolean allowIncomplete, final KeyStroke[][] deletedKeyStrokes) {		// Get the current selection.		Point selection = text.getSelection();		int start = selection.x;		int end = selection.y;		/*		 * Using the key sequence format method, discover the point at which		 * adding key strokes passes or equals the start of the selection. In		 * other words, find the first stroke that is part of the selection.		 * Keep track of the text range under which the stroke appears (i.e.,		 * startTextIndex->string.length() is the first selected stroke).		 */		String string = new String();		List currentStrokes = new ArrayList();		int startTextIndex = 0; // keeps track of the start of the stroke		final int keyStrokesLength = keyStrokes.length;		int i;		for (i = 0; (i < keyStrokesLength) && (string.length() < start); i++) {			startTextIndex = string.length();			currentStrokes.add(keyStrokes[i]);			string = KeySequence.getInstance(currentStrokes).format();		}		/*		 * If string.length() == start, then the cursor is positioned between		 * strokes (i.e., selection is outside of a stroke).		 */		int startStrokeIndex;		if (string.length() == start) {			startStrokeIndex = currentStrokes.size();		} else {			startStrokeIndex = currentStrokes.size() - 1;		}		/*		 * Check to see if the cursor is only positioned, rather than actually		 * selecting something. We only need to compute the end if there is a		 * selection.		 */		int endStrokeIndex;		if (start == end) {			return startStrokeIndex;		}		for (; (i < keyStrokesLength) && (string.length() < end); i++) {			currentStrokes.add(keyStrokes[i]);			string = KeySequence.getInstance(currentStrokes).format();		}		endStrokeIndex = currentStrokes.size() - 1;		if (endStrokeIndex < 0) {			endStrokeIndex = 0;		}		/*		 * Remove the strokes that are touched by the selection. Keep track of		 * the first stroke removed.		 */		final int newLength = endStrokeIndex - startStrokeIndex + 1;		deletedKeyStrokes[0] = new KeyStroke[newLength];		final KeyStroke startStroke = keyStrokes[startStrokeIndex];		System.arraycopy(keyStrokes, 0, keyStrokes, 0, newLength);		/*		 * Allow the first stroke removed to be replaced by an incomplete		 * stroke.		 */		if (allowIncomplete) {			final int modifierKeys = startStroke.getModifierKeys();			KeyStroke incompleteStroke = KeyStroke.getInstance(modifierKeys,					KeyStroke.NO_KEY);			int incompleteStrokeLength = incompleteStroke.format().length();			if ((startTextIndex + incompleteStrokeLength) <= start) {				final KeyStroke[] added = new KeyStroke[newLength + 1];				System.arraycopy(deletedKeyStrokes[0], 0, added, 0,						startStrokeIndex);				added[startStrokeIndex] = incompleteStroke;				System.arraycopy(deletedKeyStrokes[0], startStrokeIndex, added,						startStrokeIndex + 1, newLength);				deletedKeyStrokes[0] = added;			}		}		return startStrokeIndex;	}	/**	 * Fires a property change event to all of the listeners.	 * 	 * @param oldKeySequence	 *            The old key sequence; must not be <code>null</code>.	 * @since 3.2	 */	protected final void firePropertyChangeEvent(			final KeySequence oldKeySequence) {		if (listeners != null) {			final Iterator listenerItr = listeners.iterator();			final PropertyChangeEvent event = new PropertyChangeEvent(this,					P_KEY_SEQUENCE, oldKeySequence, getKeySequence());			while (listenerItr.hasNext()) {				final IPropertyChangeListener listener = (IPropertyChangeListener) listenerItr						.next();				listener.propertyChange(event);			}		}	}	/**	 * An accessor for the <code>KeySequence</code> that corresponds to the	 * current state of the text field. This includes incomplete strokes.	 * 	 * @return The key sequence representation; never <code>null</code>.	 */	public KeySequence getKeySequence() {		return keySequence;	}	/**	 * An accessor for the underlying text widget's contents.	 * 	 * @return The text contents of this entry; never <code>null</code>.	 */	private String getText() {		return text.getText();	}	/**	 * Tests whether the current key sequence has a stroke with no natural key.	 * 	 * @return <code>true</code> is there is an incomplete stroke;	 *         <code>false</code> otherwise.	 */	private boolean hasIncompleteStroke() {		return !keySequence.isComplete();	}	/**	 * Tests whether the current text widget has some text selection.	 * 	 * @return <code>true</code> if the number of selected characters it	 *         greater than zero; <code>false</code> otherwise.	 */	private boolean hasSelection() {		return (text.getSelectionCount() > 0);	}	/**	 * Inserts the key stroke at the current insertion point. This does a	 * regular delete and insert, as if the key had been pressed.	 * 	 * @param stroke	 *            The key stroke to insert; must not be <code>null</code>.	 */	public void insert(KeyStroke stroke) {		if (!stroke.isComplete()) {			return;		}		// Copy the key strokes in the current key sequence.		final KeySequence keySequence = getKeySequence();		final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();		final KeyStroke[] newKeyStrokes;		if ((hasIncompleteStroke()) && (!keySequence.isEmpty())) {			final int newKeyStrokesLength = oldKeyStrokes.length - 1;			newKeyStrokes = new KeyStroke[newKeyStrokesLength];			System.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,					newKeyStrokesLength);		} else {			newKeyStrokes = oldKeyStrokes;		}		KeyStroke[][] deletedKeyStrokes = new KeyStroke[1][];		int index = deleteSelection(newKeyStrokes, false, deletedKeyStrokes);		if (index == -1) {			index = 0;		}		final KeyStroke[] keyStrokes = insertStrokeAt(newKeyStrokes, stroke, index);		keyFilter.clearInsertionIndex();		setKeySequence(KeySequence.getInstance(keyStrokes));	}	/**	 * Inserts the stroke at the given index in the list of strokes. If the	 * stroke currently at that index is incomplete, then it tries to merge the	 * two strokes. If merging is a complete failure (unlikely), then it will	 * simply overwrite the incomplete stroke. If the stroke at the index is	 * complete, then it simply inserts the stroke independently.	 * 	 * @param keyStrokes	 *            The list of key strokes in which the key stroke should be	 *            appended; must not be <code>null</code>.	 * @param stroke	 *            The stroke to insert; should not be <code>null</code>.	 * @param index	 *            The index at which to insert; must be a valid index into the	 *            list of key strokes.	 */	private final KeyStroke[] insertStrokeAt(final KeyStroke[] keyStrokes,			KeyStroke stroke, int index) {		final int keyStrokesLength = keyStrokes.length;		final KeyStroke currentStroke = (index >= keyStrokesLength) ? null				: keyStrokes[index];		if ((currentStroke != null) && (!currentStroke.isComplete())) {			int modifierKeys = currentStroke.getModifierKeys();			final int naturalKey = stroke.getNaturalKey();			modifierKeys |= stroke.getModifierKeys();			keyStrokes[index] = KeyStroke.getInstance(modifierKeys, naturalKey);			return keyStrokes;		}		final KeyStroke[] newKeyStrokes = new KeyStroke[keyStrokesLength + 1];		System.arraycopy(keyStrokes, 0, newKeyStrokes, 0, index);		newKeyStrokes[index] = stroke;		if (index < keyStrokesLength) {			System.arraycopy(keyStrokes, index, newKeyStrokes, index + 1,					keyStrokesLength-index);		}		return newKeyStrokes;	}	/**	 * Tests whether the cursor is in the last position. This means that the	 * selection extends to the last position.	 * 	 * @return <code>true</code> if the selection extends to the last	 *         position; <code>false</code> otherwise.	 */	private boolean isCursorInLastPosition() {		return (text.getSelection().y >= getText().length());	}	/**	 * Removes the given listener from this key sequence widget.	 * 	 * @param listener	 *            The listener to be removed; must not be <code>null</code>.	 * @since 3.2	 */	public final void removePropertyChangeListener(			final IPropertyChangeListener listener) {		if ((listener == null) || (listeners == null)) {			return;		}		listeners.remove(listener);	}	/**	 * <p>	 * A mutator for the key sequence stored within this widget. The text and	 * caret position are updated.	 * </p>	 * <p>	 * All sequences are limited to maxStrokes number of strokes in length. If	 * there are already that number of strokes, then it does not show	 * incomplete strokes, and does not keep track of them.	 * </p>	 * 	 * @param newKeySequence	 *            The new key sequence for this widget; may be <code>null</code>	 *            if none.	 */	public void setKeySequence(KeySequence newKeySequence) {		final KeySequence oldKeySequence = keySequence;		keySequence = newKeySequence;		// Trim any extra strokes.		if (maxStrokes != INFINITE) {			final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();			if (maxStrokes < oldKeyStrokes.length) {				final KeyStroke[] newKeyStrokes = new KeyStroke[maxStrokes];				System						.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,								maxStrokes);				keySequence = KeySequence.getInstance(newKeyStrokes);			}		}		// Check to see if the text has changed.		String currentString = getText();		String newString = keySequence.format();		if (!currentString.equals(newString)) {			// We need to update the text			text.removeModifyListener(updateSequenceListener);			text.setText(keySequence.format());			text.addModifyListener(updateSequenceListener);			text.setSelection(getText().length());		}		firePropertyChangeEvent(oldKeySequence);	}	/**	 * Returns the maximum number of strokes that are permitted in this widget	 * at one time.	 * 	 * @return The maximum number of strokes; will be a positive integer or	 *         <code>INFINITE</code>.	 */	public int getKeyStrokeLimit() {		return maxStrokes;	}	/**	 * A mutator for the maximum number of strokes that are permitted in this	 * widget at one time.	 * 	 * @param keyStrokeLimit	 *            The maximum number of strokes; must be a positive integer or	 *            <code>INFINITE</code>.	 */	public void setKeyStrokeLimit(int keyStrokeLimit) {		if (keyStrokeLimit > 0 || keyStrokeLimit == INFINITE) {			this.maxStrokes = keyStrokeLimit;		} else {			throw new IllegalArgumentException();		}		// Make sure we are obeying the new limit.		setKeySequence(getKeySequence());	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -