
* additionally merged full input of f/enhanced_component_list with the current working state of f/forward_messages: * implemented setting of colors (theming) for ContextMenu * renamed messageTextColor to textColor
247 lines
7.7 KiB
Java
Executable File
247 lines
7.7 KiB
Java
Executable File
package envoy.client.ui.container;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Component;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import javax.swing.*;
|
|
|
|
import envoy.client.ui.Theme;
|
|
|
|
/**
|
|
* This class defines a menu that will be automatically called if
|
|
* {@link MouseEvent#isPopupTrigger()} returns true for the parent component.
|
|
* The user has the possibility to directly add actions to be performed when
|
|
* clicking on the element with the selected String. Additionally, for each
|
|
* element an {@link Icon} can be added, but it must not be.
|
|
* If the key(text) of an element starts with one of the predefined values, a
|
|
* special component will be called: either a {@link JRadioButtonMenuItem}, a
|
|
* {@link JCheckBoxMenuItem} or a {@link JMenu} will be created.<br>
|
|
* <br>
|
|
* Project: <strong>envoy-client</strong><br>
|
|
* File: <strong>ContextMenu.java</strong><br>
|
|
* Created: <strong>17 Mar 2020</strong><br>
|
|
*
|
|
* @author Leon Hofmeister
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public class ContextMenu extends JPopupMenu {
|
|
|
|
private static final long serialVersionUID = 2177146471226992104L;
|
|
|
|
/**
|
|
* If a key starts with this String, a {@link JCheckBoxMenuItem} will be created
|
|
*/
|
|
public static final String checkboxMenuItem = "ChBoMI";
|
|
/**
|
|
* If a key starts with this String, a {@link JRadioButtonMenuItem} will be
|
|
* created
|
|
*/
|
|
public static final String radioButtonMenuItem = "RaBuMI";
|
|
/**
|
|
* If a key starts with this String, a {@link JMenu} will be created
|
|
*/
|
|
public static final String subMenuItem = "SubMI";
|
|
|
|
private Map<String, ActionListener> items = new HashMap<>();
|
|
private Map<String, Icon> icons = new HashMap<>();
|
|
private Map<String, Integer> mnemonics = new HashMap<>();
|
|
|
|
private ButtonGroup radioButtonGroup = new ButtonGroup();
|
|
private boolean built = false;
|
|
private boolean visible = false;
|
|
|
|
/**
|
|
* @param parent the component which will call this
|
|
* {@link ContextMenu}
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public ContextMenu(Component parent) { setInvoker(parent); }
|
|
|
|
/**
|
|
* @param label the string that a UI may use to display as a title
|
|
* for the pop-up menu
|
|
* @param parent the component which will call this
|
|
* {@link ContextMenu}
|
|
* @param itemsWithActions a map of all strings to be displayed with according
|
|
* actions
|
|
* @param itemIcons the icons to be displayed before a name, if wanted.
|
|
* Only keys in here will have an Icon displayed. More
|
|
* precisely, all keys here not included in the first
|
|
* map will be thrown out.
|
|
* @param itemMnemonics the keyboard shortcuts that need to be pressed to
|
|
* automatically execute the {@link JMenuItem} with the
|
|
* given text
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public ContextMenu(String label, Component parent, Map<String, ActionListener> itemsWithActions, Map<String, Icon> itemIcons,
|
|
Map<String, Integer> itemMnemonics) {
|
|
super(label);
|
|
setInvoker(parent);
|
|
this.items = (itemsWithActions != null) ? itemsWithActions : items;
|
|
this.icons = (itemIcons != null) ? itemIcons : icons;
|
|
this.mnemonics = (itemMnemonics != null) ? itemMnemonics : mnemonics;
|
|
}
|
|
|
|
/**
|
|
* Prepares the PopupMenu to be displayed. Should only be used once all map
|
|
* values have been set.
|
|
*
|
|
* @return this instance of {@link ContextMenu} to allow chaining behind the
|
|
* constructor
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public ContextMenu build() {
|
|
items.forEach((text, action) -> {
|
|
// case radio button wanted
|
|
AbstractButton item;
|
|
if (text.startsWith(radioButtonMenuItem)) {
|
|
item = new JRadioButtonMenuItem(text.substring(radioButtonMenuItem.length()), icons.containsKey(text) ? icons.get(text) : null);
|
|
radioButtonGroup.add(item);
|
|
// case check box wanted
|
|
} else if (text.startsWith(checkboxMenuItem))
|
|
item = new JCheckBoxMenuItem(text.substring(checkboxMenuItem.length()), icons.containsKey(text) ? icons.get(text) : null);
|
|
// case sub-menu wanted
|
|
else if (text.startsWith(subMenuItem)) item = new JMenu(text.substring(subMenuItem.length()));
|
|
else // normal JMenuItem wanted
|
|
item = new JMenuItem(text, icons.containsKey(text) ? icons.get(text) : null);
|
|
item.addActionListener(action);
|
|
if (mnemonics.containsKey(text)) item.setMnemonic(mnemonics.get(text));
|
|
add(item);
|
|
});
|
|
getInvoker().addMouseListener(getShowingListener());
|
|
built = true;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @param label the string that a UI may use to display as a title for the
|
|
* pop-up menu.
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public ContextMenu(String label) { super(label); }
|
|
|
|
private MouseAdapter getShowingListener() {
|
|
return new MouseAdapter() {
|
|
|
|
@Override
|
|
public void mouseClicked(MouseEvent e) { action(e); }
|
|
|
|
@Override
|
|
public void mousePressed(MouseEvent e) { action(e); }
|
|
|
|
@Override
|
|
public void mouseReleased(MouseEvent e) { action(e); }
|
|
|
|
private void action(MouseEvent e) {
|
|
if (!built) build();
|
|
if (e.isPopupTrigger()) {
|
|
// hides the menu if already visible
|
|
visible = !visible;
|
|
if (visible) show(e.getComponent(), e.getX(), e.getY());
|
|
else setVisible(false);
|
|
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Removes all subcomponents of this menu.
|
|
*
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public void clear() {
|
|
removeAll();
|
|
items = new HashMap<>();
|
|
icons = new HashMap<>();
|
|
mnemonics = new HashMap<>();
|
|
}
|
|
|
|
/**
|
|
* @return the items
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public Map<String, ActionListener> getItems() { return items; }
|
|
|
|
/**
|
|
* @param items the items with the displayed text and the according action to
|
|
* take once called
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public void setItems(Map<String, ActionListener> items) { this.items = items; }
|
|
|
|
/**
|
|
* @return the icons
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public Map<String, Icon> getIcons() { return icons; }
|
|
|
|
/**
|
|
* @param icons the icons to set
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public void setIcons(Map<String, Icon> icons) { this.icons = icons; }
|
|
|
|
/**
|
|
* @return the mnemonics (the keyboard shortcuts that automatically execute the
|
|
* command for a {@link JMenuItem} with corresponding text)
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public Map<String, Integer> getMnemonics() { return mnemonics; }
|
|
|
|
/**
|
|
* @param mnemonics the keyboard shortcuts that need to be pressed to
|
|
* automatically execute the {@link JMenuItem} with the given
|
|
* text
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
public void setMnemonics(Map<String, Integer> mnemonics) { this.mnemonics = mnemonics; }
|
|
|
|
/**
|
|
* {@inheritDoc}<br>
|
|
* Additionally sets the foreground of all subcomponents of this
|
|
* {@link ContextMenu}.
|
|
*
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
@Override
|
|
public void setForeground(Color color) {
|
|
super.setForeground(color);
|
|
for (MenuElement element : getSubElements())
|
|
((Component) element).setForeground(color);
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}<br>
|
|
* Additionally sets the background of all subcomponents of this
|
|
* {@link ContextMenu}.
|
|
*
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
@Override
|
|
public void setBackground(Color color) {
|
|
super.setBackground(color);
|
|
for (MenuElement element : getSubElements())
|
|
((Component) element).setBackground(color);
|
|
}
|
|
|
|
/**
|
|
* Sets the fore- and background of all elements contained in this
|
|
* {@link ContextMenu}
|
|
* This method is to be only used by Envoy as {@link Theme} is an
|
|
* Envoy-exclusive object.
|
|
*
|
|
* @param theme the theme to use
|
|
* @since Envoy v0.1-beta
|
|
*/
|
|
protected void applyTheme(Theme theme) {
|
|
setBackground(theme.getInteractableBackgroundColor());
|
|
setForeground(theme.getTextColor());
|
|
}
|
|
}
|