SplitButtonDelegate.java
package swingtree;
import sprouts.Action;
import swingtree.components.JSplitButton;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* This class is a delegate for events of the {@link JSplitButton} component.
* See {@link UIForSplitButton#onSplitClick(Action)} or {@link UIForSplitButton#onSelection(Action)}
* for more information about where this delegate is used.
* @param <I> The common type of the {@link JMenuItem} which is part of the {@link JSplitButton}.
*/
public final class SplitButtonDelegate<I extends JMenuItem> extends AbstractDelegate<JSplitButton>
{
private final SplitItemDelegate<I> _itemsDelegate;
SplitButtonDelegate(
JSplitButton button,
SplitItemDelegate<I> itemsDelegate
) {
super(false, button, button);
_itemsDelegate = Objects.requireNonNull(itemsDelegate);
}
public ActionEvent getEvent() { return _itemsDelegate.getEvent(); }
/**
* Exposes the underlying {@link SplitItemDelegate} instance.
* @return The {@link JSplitButton} to which this {@link SplitItem} (and its {@link JMenuItem}) belongs.
*/
public JSplitButton getSplitButton() {
return _itemsDelegate.getSplitButton();
}
/**
* This method exposes all of the {@link JMenuItem}s which are
* part of the {@link JSplitButton} in an immutable list.
*
* @return A list of all split button items.
*/
List<I> getItems() {
return _itemsDelegate.getSiblinghood();
}
/**
* Exposes the {@link JMenuItem} which is currently selected.
*
* @return The {@link JMenuItem} which caused this action to be executed.
*/
public final I getCurrentItem() {
return _itemsDelegate.getCurrentItem();
}
/**
* The "siblinghood" of a component refers to all children of its parent component, including itself.
* This is contrary to the {@link #getSiblings()} method which returns all children of the parent component
* except the current component.
*
* @return A list of all the {@link JComponent} siblings of the split button, including the split button itself.
*/
public List<JComponent> getSiblinghood() {
// We make sure that only the Swing thread can access the sibling components:
if ( !UI.thisIsUIThread() )
throw new IllegalStateException(
"Sibling components can only be accessed by the Swing thread."
);
return _siblingsSource();
}
/**
* The "siblings" of a component refer to all children of its parent component, except itself.
* This is contrary to the {@link #getSiblinghood()} method which returns all children of the parent component
* including the current component.
*
* @return A list of all the {@link JComponent} which constitute the neighbouring UI components of the split button.
* except the current {@link JSplitButton} itself.
*/
public List<JComponent> getSiblings() {
// We make sure that only the Swing thread can access the sibling components:
if ( !UI.thisIsUIThread() )
throw new IllegalStateException(
"Sibling components can only be accessed by the Swing thread."
);
return _siblingsSource()
.stream()
.filter( s -> s != getCurrentItem() )
.collect(Collectors.toList());
}
/**
* Selects the current {@link JMenuItem} by passing {@code true}
* to the {@link JMenuItem#setSelected(boolean)} method.
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> selectCurrentItem() {
_itemsDelegate.selectCurrentItem();
return this;
}
/**
* Selects only the current {@link JMenuItem} by passing {@code true}
* to the {@link JMenuItem#setSelected(boolean)} method.
* All other {@link JMenuItem}s will be unselected.
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> selectOnlyCurrentItem() {
_itemsDelegate.selectOnlyCurrentItem();
return this;
}
/**
* Unselects the current {@link JMenuItem} by passing {@code false}
* to the {@link JMenuItem#setSelected(boolean)} method.
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> unselectCurrentItem() {
_itemsDelegate.unselectCurrentItem();
return this;
}
/**
* Unselects all {@link JMenuItem}s by passing {@code false}
* to their {@link JMenuItem#setSelected(boolean)} methods.
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> unselectAllItems() {
_itemsDelegate.unselectAllItems();
return this;
}
/**
* Selects all {@link JMenuItem}s by passing {@code true}
* to their {@link JMenuItem#setSelected(boolean)} methods.
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> selectAllItems() {
_itemsDelegate.selectAllItems();
return this;
}
/**
* Use this to conveniently make the {@link JSplitButton} display the text
* of the currently selected {@link JMenuItem} (button item).
*
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> displayCurrentItemText() {
_itemsDelegate.displayCurrentItemText();
return this;
}
/**
* Allows you to set the text displayed on the {@link JSplitButton}
* inside of your user {@link Action} implementation.
*
* @param text The text which should be displayed on the {@link JSplitButton}.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> setButtonText( String text ) {
_itemsDelegate.setButtonText(text);
return this;
}
/**
* A convenient getter method for accessing the text displayed on the {@link JSplitButton}.
* See also {@link #setButtonText(String)} for setting the text displayed on the {@link JSplitButton}.
*
* @return The text displayed on the {@link JSplitButton}.
*/
public String getButtonText() {
return _itemsDelegate.getButtonText();
}
/**
* A convenience method to append text to the text displayed on the {@link JSplitButton}.
*
* @param postfix The text which should be appended to the text displayed on the {@link JSplitButton}.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> appendToButtonText( String postfix ) {
_itemsDelegate.appendToButtonText(postfix);
return this;
}
/**
* A convenience method to prepend text to the text displayed on the {@link JSplitButton}.
*
* @param prefix The text which should be prepended to the text displayed on the {@link JSplitButton}.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> prependToButtonText( String prefix ) {
_itemsDelegate.prependToButtonText(prefix);
return this;
}
/**
* Selects the targeted split item ({@link JMenuItem}).
*
* @param i The item index of the {@link JMenuItem} which should be selected.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> selectItem( int i ) {
_itemsDelegate.selectItem(i);
return this;
}
/**
* Selects the targeted split item ({@link JMenuItem}) and unselects all other items.
*
* @param i The item index of the {@link JMenuItem} which should be selected exclusively.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> selectOnlyItem( int i ) {
_itemsDelegate.selectOnlyItem(i);
return this;
}
/**
* Unselects the targeted split item ({@link JMenuItem}).
*
* @param i The item index of the {@link JMenuItem} which should be unselected.
* @return This delegate instance to allow for method chaining.
*/
public SplitButtonDelegate<I> unselectItem( int i ) {
_itemsDelegate.unselectItem(i);
return this;
}
}