001: package org.acm.seguin.completer.popup;
002:
003: //import anthelper.adapters.Plugin;
004: import javax.swing.BorderFactory;
005: import javax.swing.border.Border;
006: import javax.swing.JPanel; //import anthelper.adapters.JIndexUtils;
007: //import anthelper.JavaUtils;
008: //import anthelper.AntHelperPlugin;
009: import org.acm.seguin.completer.Config;
010: import org.acm.seguin.ide.jedit.Navigator; //import anthelper.utils.ReflectUtils;
011: import org.acm.seguin.completer.Completer;
012: import java.awt.*;
013: import java.awt.event.*;
014: import java.util.*;
015: import javax.swing.*;
016: import javax.swing.BoxLayout;
017: import javax.swing.event.*;
018: import org.gjt.sp.jedit.*;
019: import org.gjt.sp.jedit.View;
020: import org.gjt.sp.jedit.gui.KeyEventWorkaround;
021: import org.gjt.sp.jedit.textarea.*;
022:
023: /**
024: * The popup
025: *
026: * @author btateyama@yahoo.com
027: * @created December 10, 2002
028: */
029: public class CodePopup extends BasePopup {
030:
031: final static Navigator.NavigatorLogger logger = Navigator
032: .getLogger(CodePopup.class);
033: String _strPrefix = null;
034: JList _listMembers = null;
035: Vector _dataAll = null;
036: ArrayList _listInsertListeners = new ArrayList();
037: PopupItemCellRenderer _cellRenderer = null;
038:
039: // used for resizing the popup as data narrows
040: int _iLastDataSize = 0;
041:
042: /**
043: * Create the key handler used by the JList as well as
044: * handling intercepted key events from the jEditTextArea
045: *
046: * Default will collect letters and narrow list, handle
047: * list up/down motion as well as TAB/ENTER (insertSelected())
048: *
049: * @param argOwningPopup Description of the Parameter
050: * @param argView Description of the Parameter
051: * @return Description of the Return Value
052: */
053: protected KeyListener createKeyHandler(CodePopup argOwningPopup,
054: View argView) {
055: return new DefaultKeyHandler(argOwningPopup, argView);
056: }
057:
058: /**
059: * Create the Mouse Listener for hanlding mouse click events
060: * on the list.
061: * Default handler will calls insertSelected();
062: *
063: * @param argOwningPopup Description of the Parameter
064: * @param argView Description of the Parameter
065: * @return Description of the Return Value
066: */
067: protected MouseListener createMouseHandler(
068: CodePopup argOwningPopup, View argView) {
069: return new DefaultMouseHandler(argOwningPopup);
070: }
071:
072: /**
073: * Constructor for the CodePopup object
074: *
075: * @param argView Description of the Parameter
076: * @param argPrefix Description of the Parameter
077: * @param argPopupItems Description of the Parameter
078: * @param argTag Description of the Parameter
079: */
080: public CodePopup(View argView, String argPrefix,
081: Vector argPopupItems, String argTag) {
082: super (argView);
083:
084: _strPrefix = argPrefix;
085: _dataAll = argPopupItems;
086: Collections.sort(_dataAll);
087: _iLastDataSize = _dataAll.size();
088: _cellRenderer = new PopupItemCellRenderer(_dataAll);
089: _listMembers = createList(_dataAll, _cellRenderer);
090:
091: JPanel panel = createMainPanel();
092: panel.add(createScrollPane(_listMembers), BorderLayout.CENTER);
093: if (argTag != null && argTag.trim().length() > 0) {
094: panel.add(createTypeLabel(argTag), BorderLayout.SOUTH);
095: }
096:
097: setContentPane(panel);
098: pack();
099: // calculate left offset and position popup
100: Point point = PopupUtils.getPointOnTextArea(argView, argPrefix);
101: point.x -= _cellRenderer.getLeftOffset(_listMembers.getFont());
102: setLocation(point);
103: filterData();
104: }
105:
106: protected void postShow() {
107: KeyListener keyHandler = createKeyHandler(this , _view);
108: addKeyListener(keyHandler);
109: _listMembers.addKeyListener(keyHandler);
110: _view.setKeyEventInterceptor(keyHandler);
111: GUIUtilities.requestFocus(this , _listMembers);
112: }
113:
114: JList createList(Vector argData, ListCellRenderer argRenderer) {
115: JList listMembers = new JList(argData);
116: listMembers.setFont(UIManager.getFont("TextArea.font"));
117: listMembers.setVisibleRowCount(Math.min(argData.size(), 8));
118: listMembers.setSelectionBackground(Color.blue);
119: listMembers.setSelectionForeground(Color.white);
120: //listMembers.addMouseListener(new MouseHandler());
121: listMembers.addMouseListener(createMouseHandler(this , _view));
122: listMembers.setSelectedIndex(0);
123: listMembers
124: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
125: listMembers.setCellRenderer(argRenderer);
126: return listMembers;
127: }
128:
129: static JButton createSmallButton(String argText) {
130: JButton buttonTiny = new JButton(argText);
131: //buttonTiny.setBorder(BorderFactory.createEtchedBorder());
132: //buttonTiny.setBorder(BorderFactory.createLineBorder(Color.blue));
133: buttonTiny.setMargin(new Insets(0, 2, 0, 2));
134: return buttonTiny;
135: }
136:
137: Component createTypeLabel(final String argText) {
138: JLabel label = new JLabel(argText);
139: JButton buttonCB = createSmallButton("CB");
140: buttonCB.setToolTipText("Open class in AH Class Browser");
141: buttonCB.addActionListener(new AbstractAction() {
142: public void actionPerformed(ActionEvent argEvent) {
143: dispose();
144: // FIXME : JavaUtils.viewClassInfo(_view, argText);
145: }
146: });
147:
148: JButton buttonJD = createSmallButton("JD");
149: buttonJD.setToolTipText("Open Javadoc with JIndex");
150: buttonJD.addActionListener(new AbstractAction() {
151: public void actionPerformed(ActionEvent argEvent) {
152: dispose();
153: // FIXME: JIndexUtils.lookUp(_view, argText);
154: }
155: });
156: buttonJD.setEnabled(false); //FIXME: Plugin.JINDEX.isInstalled());
157:
158: JPanel panel = new JPanel();
159: panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
160: panel.add(Box.createHorizontalStrut(Math.max(_cellRenderer
161: .getIconWidth(), PopupUtils.ICON_WIDTH)));
162: panel.add(label);
163: panel.add(Box.createHorizontalGlue());
164: panel.add(buttonCB);
165: panel.add(buttonJD);
166:
167: return panel;
168: }
169:
170: /**
171: * Adds a feature to the InsertListeners attribute of the CodePopup object
172: *
173: * @param argListener The feature to be added to the InsertListeners
174: * attribute
175: */
176: public void addInsertListener(InsertListener argListener) {
177: _listInsertListeners.add(argListener);
178: }
179:
180: public JList getListMembers() {
181: return _listMembers;
182: }
183:
184: String getPrefix() {
185: return _strPrefix;
186: }
187:
188: void setPrefix(String argVal) {
189: _strPrefix = argVal;
190: }
191:
192: void insertSelected() {
193: PopupItem popupItem = (PopupItem) _listMembers
194: .getSelectedValue();
195:
196: String strText = popupItem.getBeforeCaretString();
197: strText += popupItem.getAfterCaretString();
198:
199: // add text
200: strText = strText.substring(_strPrefix.length());
201: _textArea.setSelectedText(strText);
202: //_textArea.setSelectedText(strText.substring(_strPrefix.length()));
203:
204: // back step cursor to before the "after" text
205: int iPos = _textArea.getCaretPosition();
206: iPos -= popupItem.getAfterCaretString().length();
207: _textArea.setCaretPosition(iPos);
208: // position
209: dispose();
210:
211: // alert listener, delegates
212: InsertListener listener;
213: for (Iterator it = _listInsertListeners.iterator(); it
214: .hasNext();) {
215: listener = (InsertListener) it.next();
216: listener.insertPerformed(popupItem, _strPrefix, strText,
217: _view);
218: }
219: }
220:
221: void filterData() {
222: Vector vNewData = new Vector();
223:
224: Object objDataItem;
225: for (Iterator it = _dataAll.iterator(); it.hasNext();) {
226: objDataItem = it.next();
227: if (objDataItem.toString().startsWith(_strPrefix)) {
228: vNewData.add(objDataItem);
229: }
230: }
231:
232: if (vNewData.size() == 0) {
233: dispose();
234: } else {
235: _listMembers.setListData(vNewData);
236: _listMembers.setSelectedIndex(0);
237:
238: if (Config.RESIZE_POPUP_AS_DATA_NARROWS.getAsBoolean()
239: && Math.abs(_iLastDataSize - vNewData.size()) > 10) {
240: _listMembers.setVisibleRowCount(Math.min(vNewData
241: .size(), 8));
242: pack();
243: }
244: _iLastDataSize = vNewData.size();
245: }
246: }
247:
248: class DefaultMouseHandler extends MouseAdapter {
249: CodePopup _popup = null;
250:
251: DefaultMouseHandler(CodePopup argPopup) {
252: _popup = argPopup;
253: }
254:
255: /**
256: * Description of the Method
257: *
258: * @param evt Description of the Parameter
259: */
260: public void mouseClicked(MouseEvent evt) {
261: _popup.insertSelected();
262: }
263: }
264:
265: public static void main(String[] args) {
266: try {
267: JFrame frame = new JFrame();
268: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
269: frame.setLocation(300, 300);
270: frame.setSize(200, 200);
271: JButton buttonTiny = new JButton(
272: "<html><font size=-2>small</font></html>");
273: buttonTiny.setMargin(new Insets(0, 10, 0, 10));
274: //buttonTiny.setBorder(BorderFactory.createEtchedBorder());
275: JButton buttonTiny2 = new JButton(
276: "<html><font size=-2>small</font></html>");
277: buttonTiny2.setMargin(new Insets(0, 0, 0, 0));
278:
279: JPanel panel = new JPanel();
280: //panel.add(new JButton("small"));
281: //panel.add(new JButton("<html><font size=-1>small</font></html>"));
282: panel.add(createSmallButton("foobar"));
283: panel.add(createSmallButton("foobar"));
284: panel.add(buttonTiny2);
285: frame.setContentPane(panel);
286: frame.show();
287: } catch (Throwable t) {
288: t.printStackTrace();
289: }
290: }
291:
292: }
|