org.eclipse.jface.bindings.keys.KeySequence Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2004, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.bindings.keys;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.formatting.KeyFormatterFactory;
import org.eclipse.jface.util.Util;
/**
*
* A KeySequence
is defined as a list of zero or more
* KeyStrokes
, with the stipulation that all
* KeyStroke
objects must be complete, save for the last one,
* whose completeness is optional. A KeySequence
is said to be
* complete if all of its KeyStroke
objects are complete.
*
*
* All KeySequence
objects have a formal string representation
* available via the toString()
method. There are a number of
* methods to get instances of KeySequence
objects, including one
* which can parse this formal string representation.
*
*
* All KeySequence
objects, via the format()
* method, provide a version of their formal string representation translated by
* platform and locale, suitable for display to a user.
*
*
* KeySequence
objects are immutable. Clients are not permitted
* to extend this class.
*
*
* @since 3.1
*/
public final class KeySequence extends TriggerSequence implements Comparable {
/**
* An empty key sequence instance for use by everyone.
*/
private static final KeySequence EMPTY_KEY_SEQUENCE = new KeySequence(
new KeyStroke[0]);
/**
* The delimiter between multiple key strokes in a single key sequence --
* expressed in the formal key stroke grammar. This is not to be displayed
* to the user. It is only intended as an internal representation.
*/
public static final String KEY_STROKE_DELIMITER = "\u0020"; //$NON-NLS-1$
/**
* The set of delimiters for KeyStroke
objects allowed during
* parsing of the formal string representation.
*/
public static final String KEY_STROKE_DELIMITERS = KEY_STROKE_DELIMITER
+ "\b\r\u007F\u001B\f\n\0\t\u000B"; //$NON-NLS-1$
/**
* Gets an instance of KeySequence
.
*
* @return a key sequence. This key sequence will have no key strokes.
* Guaranteed not to be null
.
*/
public static final KeySequence getInstance() {
return EMPTY_KEY_SEQUENCE;
}
/**
* Creates an instance of KeySequence
given a key sequence
* and a key stroke.
*
* @param keySequence
* a key sequence. Must not be null
.
* @param keyStroke
* a key stroke. Must not be null
.
* @return a key sequence that is equal to the given key sequence with the
* given key stroke appended to the end. Guaranteed not to be
* null
.
*/
public static final KeySequence getInstance(final KeySequence keySequence,
final KeyStroke keyStroke) {
if (keySequence == null || keyStroke == null) {
throw new NullPointerException();
}
final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
final int oldKeyStrokeLength = oldKeyStrokes.length;
final KeyStroke[] newKeyStrokes = new KeyStroke[oldKeyStrokeLength + 1];
System
.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
oldKeyStrokeLength);
newKeyStrokes[oldKeyStrokeLength] = keyStroke;
return new KeySequence(newKeyStrokes);
}
/**
* Creates an instance of KeySequence
given a single key
* stroke.
*
* @param keyStroke
* a single key stroke. Must not be null
.
* @return a key sequence. Guaranteed not to be null
.
*/
public static final KeySequence getInstance(final KeyStroke keyStroke) {
return new KeySequence(new KeyStroke[] { keyStroke });
}
/**
* Creates an instance of KeySequence
given an array of key
* strokes.
*
* @param keyStrokes
* the array of key strokes. This array may be empty, but it must
* not be null
. This array must not contain
* null
elements.
* @return a key sequence. Guaranteed not to be null
.
*/
public static final KeySequence getInstance(final KeyStroke[] keyStrokes) {
return new KeySequence(keyStrokes);
}
/**
* Creates an instance of KeySequence
given a list of key
* strokes.
*
* @param keyStrokes
* the list of key strokes. This list may be empty, but it must
* not be null
. If this list is not empty, it
* must only contain instances of KeyStroke
.
* @return a key sequence. Guaranteed not to be null
.
*/
public static final KeySequence getInstance(final List keyStrokes) {
return new KeySequence(keyStrokes.toArray(new KeyStroke[keyStrokes.size()]));
}
/**
* Creates an instance of KeySequence
by parsing a given
* formal string representation.
*
* @param string
* the formal string representation to parse.
* @return a key sequence. Guaranteed not to be null
.
* @throws ParseException
* if the given formal string representation could not be parsed
* to a valid key sequence.
*/
public static final KeySequence getInstance(final String string)
throws ParseException {
if (string == null) {
throw new NullPointerException();
}
final List keyStrokes = new ArrayList<>();
final StringTokenizer stringTokenizer = new StringTokenizer(string,
KEY_STROKE_DELIMITERS);
try {
while (stringTokenizer.hasMoreTokens()) {
keyStrokes.add(KeyStroke.getInstance(stringTokenizer.nextToken()));
}
final KeyStroke[] keyStrokeArray = keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
return new KeySequence(keyStrokeArray);
} catch (final IllegalArgumentException | NullPointerException e) {
throw new ParseException(
"Could not construct key sequence with these key strokes: " //$NON-NLS-1$
+ keyStrokes);
}
}
/**
* Constructs an instance of KeySequence
given a list of key
* strokes.
*
* @param keyStrokes
* the list of key strokes. This list may be empty, but it must
* not be null
. If this list is not empty, it
* must only contain instances of KeyStroke
.
*/
protected KeySequence(final KeyStroke[] keyStrokes) {
super(keyStrokes);
for (int i = 0; i < triggers.length - 1; i++) {
KeyStroke keyStroke = (KeyStroke) triggers[i];
if (!keyStroke.isComplete()) {
throw new IllegalArgumentException();
}
}
}
@Override
public final int compareTo(final Object object) {
final KeySequence castedObject = (KeySequence) object;
return Util.compare(triggers, castedObject.triggers);
}
/**
* Formats this key sequence into the current default look.
*
* @return A string representation for this key sequence using the default
* look; never null
.
*/
@Override
public final String format() {
return KeyFormatterFactory.getDefault().format(this);
}
/**
* Returns the list of key strokes for this key sequence.
*
* @return the list of key strokes keys. This list may be empty, but is
* guaranteed not to be null
. If this list is not
* empty, it is guaranteed to only contain instances of
* KeyStroke
.
*/
public final KeyStroke[] getKeyStrokes() {
final int triggerLength = triggers.length;
final KeyStroke[] keyStrokes = new KeyStroke[triggerLength];
System.arraycopy(triggers, 0, keyStrokes, 0, triggerLength);
return keyStrokes;
}
@Override
public final TriggerSequence[] getPrefixes() {
final int numberOfPrefixes = triggers.length;
final TriggerSequence[] prefixes = new TriggerSequence[numberOfPrefixes];
prefixes[0] = KeySequence.getInstance();
for (int i = 0; i < numberOfPrefixes - 1; i++) {
final KeyStroke[] prefixKeyStrokes = new KeyStroke[i + 1];
System.arraycopy(triggers, 0, prefixKeyStrokes, 0, i + 1);
prefixes[i + 1] = KeySequence.getInstance(prefixKeyStrokes);
}
return prefixes;
}
/**
* Returns whether or not this key sequence is complete. Key sequences are
* complete iff all of their key strokes are complete.
*
* @return true
, iff the key sequence is complete.
*/
public final boolean isComplete() {
final int triggersLength = triggers.length;
for (int i = 0; i < triggersLength; i++) {
if (!((KeyStroke) triggers[i]).isComplete()) {
return false;
}
}
return true;
}
/**
* Returns the formal string representation for this key sequence.
*
* @return The formal string representation for this key sequence.
* Guaranteed not to be null
.
*/
@Override
public final String toString() {
return KeyFormatterFactory.getFormalKeyFormatter().format(this);
}
}