package com.revolsys.swing.menu;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.concurrent.Callable;
import javax.swing.ComboBoxEditor;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.text.JTextComponent;
import com.revolsys.logging.Logs;
import com.revolsys.swing.listener.BaseMouseListener;
public class ShowMenuMouseListener implements BaseMouseListener {
public static ShowMenuMouseListener addListener(final JComponent component,
final Callable<BaseJPopupMenu> menuFactory) {
return addListener(component, menuFactory, false);
}
public static ShowMenuMouseListener addListener(final JComponent component,
final Callable<BaseJPopupMenu> menuFactory, final boolean addDnd) {
if (component != null && menuFactory != null) {
final ShowMenuMouseListener listener = new ShowMenuMouseListener(component, menuFactory,
addDnd);
component.addMouseListener(listener);
return listener;
} else {
return null;
}
}
private Callable<BaseJPopupMenu> menuFactory;
private JTextComponent textComponent;
private JComponent component;
private final boolean addDnd;
private ShowMenuMouseListener previousListener;
private ShowMenuMouseListener(final JComponent component,
final Callable<BaseJPopupMenu> menuFactory, final boolean addDnd) {
this.component = component;
this.menuFactory = menuFactory;
this.addDnd = addDnd;
addMenuListener(component);
}
@SuppressWarnings("rawtypes")
private boolean addMenuListener(final JComponent component) {
if (component != null) {
for (final MouseListener listener : component.getMouseListeners()) {
if (listener instanceof ShowMenuMouseListener) {
this.previousListener = (ShowMenuMouseListener)listener;
component.removeMouseListener(listener);
}
}
component.addMouseListener(this);
if (component instanceof JComboBox) {
final JComboBox comboBox = (JComboBox)component;
final ComboBoxEditor editor = comboBox.getEditor();
final Component editorComponent = editor.getEditorComponent();
addMenuListener((JComponent)editorComponent);
} else if (component instanceof JTextComponent) {
this.textComponent = (JTextComponent)component;
this.textComponent.setDragEnabled(true);
}
}
return true;
}
public void close() {
if (this.component != null) {
this.component.removeMouseListener(this);
if (this.component instanceof JComboBox) {
final JComboBox<?> comboBox = (JComboBox<?>)this.component;
final ComboBoxEditor editor = comboBox.getEditor();
final Component editorComponent = editor.getEditorComponent();
editorComponent.removeMouseListener(this);
if (this.previousListener != null) {
editorComponent.addMouseListener(this.previousListener);
}
}
if (this.previousListener != null) {
this.component.addMouseListener(this.previousListener);
}
}
this.previousListener = null;
this.component = null;
this.textComponent = null;
this.menuFactory = null;
}
@Override
public void mousePressed(final MouseEvent e) {
showMenu(e);
}
@Override
public void mouseReleased(final MouseEvent e) {
showMenu(e);
}
private void showMenu(final MouseEvent e) {
if (this.menuFactory != null) {
if (e.isPopupTrigger() && !e.isConsumed()) {
e.consume();
final Component component = e.getComponent();
final int x = e.getX();
final int y = e.getY();
try {
final BaseJPopupMenu menu = this.menuFactory.call();
if (menu != null) {
if (this.addDnd && this.textComponent != null) {
menu.addSeparator();
menu.addMenuItem("Cut", "cut", this.textComponent::cut);
menu.addMenuItem("Copy", "page_copy", this.textComponent::copy);
menu.addMenuItem("Paste", "paste_plain", this.textComponent::paste);
}
menu.showMenu(component, x + 5, y);
}
} catch (final Exception e1) {
Logs.error(this, "Error creating menu", e1);
}
}
}
}
}