001: /*
002: * TextComponentMouseListener.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.event.MouseEvent;
015: import java.awt.event.MouseListener;
016: import java.util.LinkedList;
017: import java.util.List;
018: import javax.swing.JMenuItem;
019: import javax.swing.event.CaretEvent;
020: import javax.swing.event.CaretListener;
021: import javax.swing.text.JTextComponent;
022: import workbench.gui.actions.WbAction;
023: import workbench.gui.menu.TextPopup;
024:
025: /**
026: * Provide a Cut, Copy, Paste popup menu for Text components
027: *
028: * @author support@sql-workbench.net Kellerer
029: */
030: public class TextComponentMouseListener implements MouseListener,
031: CaretListener {
032: private List<JMenuItem> additionalItems = new LinkedList<JMenuItem>();
033: private TextPopup popup;
034: private JTextComponent text;
035: private int originalComponentCount = -1;
036:
037: /**
038: * Create a listener to display a context menu with Cut, Copy and Paste
039: * entries.
040: */
041: public TextComponentMouseListener() {
042: }
043:
044: /**
045: * Create a listener to display a context menu with Cut, Copy and Paste
046: * entries. The shortcuts of the menu actions will be added to the input
047: * map of the text component.
048: */
049: public TextComponentMouseListener(JTextComponent component) {
050: this .text = component;
051: this .popup = createPopup(component);
052: this .originalComponentCount = this .popup.getComponentCount();
053: this .popup.getCutAction().addToInputMap(text);
054: this .popup.getClearAction().addToInputMap(text);
055: this .popup.getPasteAction().addToInputMap(text);
056: this .popup.getCopyAction().addToInputMap(text);
057: text.addCaretListener(this );
058: component.addMouseListener(this );
059: }
060:
061: /**
062: * Add an action to the popup menu. The action's shortcut will
063: * also be added to the underlying text component's input map
064: * (if one was supplied in the constructor)
065: */
066: public void addAction(WbAction action) {
067: this .addMenuItem(action.getMenuItem());
068: if (this .text != null) {
069: action.addToInputMap(text);
070: }
071: }
072:
073: /**
074: * Add additional menu items to the popup menu.
075: */
076: public void addMenuItem(JMenuItem item) {
077: if (popup != null) {
078: if (this .originalComponentCount > -1
079: && popup.getComponentCount() == this .originalComponentCount) {
080: this .popup.addSeparator();
081: }
082: this .popup.add(item);
083: } else {
084: this .additionalItems.add(item);
085: }
086: }
087:
088: public void mouseClicked(MouseEvent e) {
089: if (e.getButton() == MouseEvent.BUTTON3
090: && e.getSource() instanceof JTextComponent) {
091: try {
092: JTextComponent component = (JTextComponent) e
093: .getSource();
094: TextPopup pop = this .popup;
095: if (pop == null) {
096: pop = createPopup(component);
097: }
098: checkActions(component, pop);
099: pop.show(component, e.getX(), e.getY());
100: } catch (Exception ex) {
101: ex.printStackTrace();
102: }
103: }
104: }
105:
106: private TextPopup createPopup(JTextComponent component) {
107: ClipboardWrapper wrapp = new ClipboardWrapper(component);
108: TextPopup pop = new TextPopup(wrapp);
109: if (this .additionalItems.size() > 0) {
110: pop.addSeparator();
111: for (JMenuItem item : additionalItems) {
112: pop.add(item);
113: }
114: }
115: return pop;
116: }
117:
118: /** Invoked when the mouse enters a component.
119: *
120: */
121: public void mouseEntered(MouseEvent e) {
122: }
123:
124: /** Invoked when the mouse exits a component.
125: *
126: */
127: public void mouseExited(MouseEvent e) {
128: }
129:
130: /** Invoked when a mouse button has been pressed on a component.
131: *
132: */
133: public void mousePressed(MouseEvent e) {
134: }
135:
136: /** Invoked when a mouse button has been released on a component.
137: *
138: */
139: public void mouseReleased(MouseEvent e) {
140: }
141:
142: public void caretUpdate(CaretEvent evt) {
143: if (this .text != null && this .popup != null) {
144: checkActions(this .text, this .popup);
145: }
146: }
147:
148: private void checkActions(JTextComponent component, TextPopup pop) {
149: if (component == null || pop == null)
150: return;
151:
152: boolean edit = component.isEditable();
153: boolean selected = component.getSelectionEnd() > component
154: .getSelectionStart();
155: pop.getCutAction().setEnabled(edit && selected);
156: pop.getClearAction().setEnabled(edit && selected);
157: pop.getPasteAction().setEnabled(edit);
158: pop.getCopyAction().setEnabled(selected);
159: }
160: }
|