org.valkyriercp.command.config.CommandButtonLabelInfo Maven / Gradle / Ivy
package org.valkyriercp.command.config;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.valkyriercp.core.ButtonConfigurer;
import org.valkyriercp.core.support.LabelInfo;
import javax.swing.*;
/**
* An immutable parameter object consisting of the text, mnemonic character, mnemonic character
* index and keystroke accelerator that may be associated with a labeled command button.
*
*
* This class also acts as a factory for creating instances of itself based on a string descriptor.
* The syntax used for this descriptor is described in the javadoc for the {@link #valueOf(String)}
* method.
*
*
* @author Keith Donald
* @author Kevin Stembridge
*
* @see LabelInfo
* @see javax.swing.KeyStroke
*/
public final class CommandButtonLabelInfo implements ButtonConfigurer {
/** A default instance to be used for command buttons with no label information. */
public static final CommandButtonLabelInfo BLANK_BUTTON_LABEL = new CommandButtonLabelInfo("");
private final LabelInfo labelInfo;
private final KeyStroke accelerator;
/**
* Return an instance of this class, created by parsing the information in the given label
* descriptor string. The expected format of this descriptor is the same as that used by
* the {@link LabelInfo} class, with the following additions:
*
*
* - The @ symbol is an escapable character.
* - Everything after the first unescaped @ symbol will be treated as the textual representation
* of the keystroke accelerator.
*
*
* The expected format of the keystroke accelerator string is as described in the javadocs for the
* {@link KeyStroke#getKeyStroke(String)} method.
*
*
* @param labelDescriptor The label descriptor. May be null or empty, in which case, a default
* blank label info will be returned.
* @return A CommandButtonLabelInfo instance, never null.
*
* @throws IllegalArgumentException if {@code labelDescriptor} contains invalid syntax.
*
* @see LabelInfo
* @see KeyStroke
*/
public static CommandButtonLabelInfo valueOf(String labelDescriptor) {
if (!StringUtils.hasText(labelDescriptor)) {
return BLANK_BUTTON_LABEL;
}
StringBuffer labelInfoBuffer = new StringBuffer();
char currentChar;
KeyStroke keyStroke = null;
for (int i = 0, textCharsIndex = 0; i < labelDescriptor.length(); i++, textCharsIndex++) {
currentChar = labelDescriptor.charAt(i);
if (currentChar == '\\') {
int nextCharIndex = i + 1;
//if this backslash is escaping an @ symbol, we remove the backslash and
//continue with the next char
if (nextCharIndex < labelDescriptor.length()) {
char nextChar = labelDescriptor.charAt(nextCharIndex);
if (nextChar == '@') {
labelInfoBuffer.append(nextChar);
i++;
} else {
labelInfoBuffer.append(currentChar);
labelInfoBuffer.append(nextChar);
i++;
}
}
}
else if (currentChar == '@') {
//we've found the accelerator indicator
if (i + 1 == labelDescriptor.length()) {
throw new IllegalArgumentException(
"The label descriptor ["
+ labelDescriptor
+ "] does not specify a valid accelerator after the last "
+ "non-espaced @ symbol.");
}
String acceleratorStr = labelDescriptor.substring(i + 1);
keyStroke = KeyStroke.getKeyStroke(acceleratorStr);
if (keyStroke == null) {
throw new IllegalArgumentException(
"The keystroke accelerator string ["
+ acceleratorStr
+ "] from the label descriptor ["
+ labelDescriptor
+ "] is not a valid keystroke format.");
}
break;
}
else {
labelInfoBuffer.append(currentChar);
}
}
LabelInfo info = LabelInfo.valueOf(labelInfoBuffer.toString());
return new CommandButtonLabelInfo(info, keyStroke);
}
/**
* Creates a new {@code CommandButtonLabelInfo} that will display the given text on its label.
* There will be no associated mnemonic character and no keystroke accelerator.
*
* @param text The label text to be displayed. Must not be null.
*
* @throws IllegalArgumentException if {@code text} is null.
*/
public CommandButtonLabelInfo(String text) {
this(new LabelInfo(text), null);
}
/**
* Creates a new {@code CommandButtonLabelInfo} with the given label information and keystroke
* accelerator.
*
* @param labelInfo The label information. Must not be null.
* @param accelerator The keystroke accelerator. May be null.
*
* @throws IllegalArgumentException if {@code labelInfo} is null.
*/
public CommandButtonLabelInfo(LabelInfo labelInfo, KeyStroke accelerator) {
Assert.notNull(labelInfo, "labelInfo");
this.labelInfo = labelInfo;
this.accelerator = accelerator;
}
/**
* Returns the displayable text.
*
* @return The label text. Maybe an empty string but never null.
*/
public String getText() {
return this.labelInfo.getText();
}
/**
* Returns the mnemonic for the label.
*
* @return The mnemonic for the label.
*/
public int getMnemonic() {
return this.labelInfo.getMnemonic();
}
/**
* Returns the zero-based index for the mnemonic character within the label text.
*
* @return The mnemonic index or -1 to indicate that there is no associated mnemonic character.
*/
public int getMnemonicIndex() {
return this.labelInfo.getMnemonicIndex();
}
/**
* Returns the keystroke accelerator for the label.
*
* @return The keystroke accelerator, or null.
*/
public KeyStroke getAccelerator() {
return this.accelerator;
}
/**
* {@inheritDoc}
*/
public int hashCode() {
return this.labelInfo.hashCode() + (this.accelerator != null ? this.accelerator.hashCode() : 0);
}
/**
* {@inheritDoc}
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof CommandButtonLabelInfo)) {
return false;
}
CommandButtonLabelInfo other = (CommandButtonLabelInfo)obj;
if (!this.labelInfo.equals(other.labelInfo)) {
return false;
}
if (!ObjectUtils.nullSafeEquals(this.accelerator, other.accelerator)) {
return false;
}
return true;
}
/**
* Configures an existing button appropriately based on this label info's
* properties.
*
* @param button
*/
public AbstractButton configure(AbstractButton button) {
Assert.notNull(button);
button.setText(this.labelInfo.getText());
button.setMnemonic(this.labelInfo.getMnemonic());
button.setDisplayedMnemonicIndex(this.labelInfo.getMnemonicIndex());
configureAccelerator(button, getAccelerator());
return button;
}
/**
* Sets the given keystroke accelerator on the given button.
*
* @param button The button. May be null.
* @param keystrokeAccelerator The accelerator. May be null.
*/
protected void configureAccelerator(AbstractButton button, KeyStroke keystrokeAccelerator) {
if ((button instanceof JMenuItem) && !(button instanceof JMenu)) {
((JMenuItem)button).setAccelerator(keystrokeAccelerator);
}
}
/**
* {@inheritDoc}
*/
public String toString() {
return new ToStringCreator(this)
.append("labelInfo", this.labelInfo)
.append("accelerator", this.accelerator)
.toString();
}
}