/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ensembl.healthcheck.eg_gui; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.HashMap; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.text.DefaultEditorKit; import javax.swing.text.JTextComponent; /** * * <p> * Copied most of this from from http://www.objectdefinitions.com/odblog/2007/jtextarea-with-popup-menu/ * </p> * * @author michael * */ public class CopyAndPastePopupBuilder { private HashMap actions; public void addPopupMenu(JTextComponent c) { createActionTable(c); JPopupMenu menu = new JPopupMenu(); menu.add(getActionByName(DefaultEditorKit.copyAction, "Copy")); menu.add(getActionByName(DefaultEditorKit.cutAction, "Cut")); menu.add(getActionByName(DefaultEditorKit.pasteAction, "Paste")); menu.add(new JSeparator()); menu.add(getActionByName(DefaultEditorKit.selectAllAction, "Select All")); c.add(menu); c.addMouseListener( new PopupTriggerMouseListener( menu, c ) ); //no need to hold the references in the map, // we have used the ones we need. actions.clear(); } private Action getActionByName(String name, String description) { Action a = (Action)(actions.get(name)); if (a == null) { throw new NullPointerException( "Can't find action with name " + name + "\n" + "Possible actions are:" + actions.keySet() ); } // Error in the copy and pasted code. Original: // // a.putValue(Action.NAME, description); // // corrected: // a.putValue(name, description); //System.out.println("The action is " + Action.NAME + " " + name); return a; } private void createActionTable(JTextComponent c) { actions = new HashMap(); Action[] actionsArray = c.getActions(); for (int i = 0; i < actionsArray.length; i++) { Action a = actionsArray[i]; actions.put(a.getValue(Action.NAME), a); } } public static class PopupTriggerMouseListener extends MouseAdapter { private JPopupMenu popup; private JComponent component; public PopupTriggerMouseListener(JPopupMenu popup, JComponent component) { this.popup = popup; this.component = component; } private void showMenuIfPopupTrigger(MouseEvent e) { // Using e.isPopupTrigger will cause the popup menu to open only // after the second right click. This makes the popup menu appear // lazy. The reason is that after the first right click only a // mouseReleased event is fired. The second right click fires all // three mousePressed, mouseClicked and mouseReleased events as // expected. // if (e.getButton()==MouseEvent.BUTTON3) //if (e.isPopupTrigger()) { popup.show(component, e.getX() + 3, e.getY() + 3); } } //according to the javadocs on isPopupTrigger, checking for popup trigger on mousePressed and mouseReleased //should be all that is required public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) { showMenuIfPopupTrigger(e); } } }