001: package tide.editor.completions;
002:
003: import snow.sortabletable.*;
004: import java.util.*;
005: import java.awt.*;
006: import java.awt.event.*;
007: import javax.swing.*;
008:
009: /** Some collected utilities for the completion UI.
010: */
011: public final class CompletionUtils {
012:
013: private CompletionUtils() {
014: }
015:
016: /** Convenience to add navigation in the table with focus in the field.
017: * ENTER must be removed, because it jumps to the next line !
018: */
019: public static void controlTableWithFieldKeys(
020: final JTextField field, final JTable table,
021: final CompletionDialog dialog, final String charsToClose) {
022: Action doNothing = new AbstractAction() {
023: public void actionPerformed(ActionEvent e) {
024: //do nothing
025: }
026: };
027: KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0,
028: false);
029: table.getInputMap(JComponent.WHEN_FOCUSED).put(ks, "doNothing");
030: table.getActionMap().put("doNothing", doNothing);
031:
032: field.addKeyListener(new KeyAdapter() {
033: public void scrollTo(int pos) {
034: if (pos < table.getRowCount() && pos >= 0) {
035: table.setRowSelectionInterval(pos, pos);
036: table.scrollRectToVisible(table.getCellRect(pos, 0,
037: true));
038: }
039: }
040:
041: @Override
042: public void keyPressed(KeyEvent ke) {
043:
044: if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
045: int pos = table.getSelectedRow() + 1;
046: if (pos >= table.getRowCount()) { // cycle
047: pos = 0;
048: }
049: scrollTo(pos);
050: }
051: if (ke.getKeyCode() == KeyEvent.VK_PAGE_DOWN) {
052: int pos = table.getSelectedRow() + 20;
053: if (pos >= table.getRowCount()) {
054: pos = table.getRowCount() - 1;
055: }
056: scrollTo(pos);
057: } else if (ke.getKeyCode() == KeyEvent.VK_UP) {
058: int pos = table.getSelectedRow() - 1;
059: if (pos < 0) {// cycle
060: pos = table.getRowCount() - 1;
061: }
062: scrollTo(pos);
063: } else if (ke.getKeyCode() == KeyEvent.VK_PAGE_UP) {
064: int pos = table.getSelectedRow() - 10;
065: if (pos < 0) {
066: pos = 0;
067: }
068: scrollTo(pos);
069: } else if (ke.getKeyCode() == KeyEvent.VK_DELETE
070: || ke.getKeyCode() == KeyEvent.VK_LEFT) {
071: // if one press delete or go back => leave the dialog if empty
072: if (field.getText().length() == 0) {
073: dialog.cancelDialog();
074: }
075: } else if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
076: //MainEditorFrame. System.out.println("enter pressed");
077: } else {
078: char ci = ke.getKeyChar();
079: if (charsToClose.indexOf(ci) >= 0) {
080: EventQueue.invokeLater(new Runnable() {
081: public void run() {
082: dialog.selectAndQuit(); // so the typed ")" will be contained when closing !! (good idea ??)
083: }
084: });
085: }
086: }
087:
088: // ensure that the first hit is always selected
089: if (table.getSelectedRow() == -1) {
090: if (table.getRowCount() > 0) {
091: table.setRowSelectionInterval(0, 0);
092: }
093: }
094: }
095:
096: @Override
097: public void keyReleased(KeyEvent ke) {
098: //System.out.println("kr="+ke);
099: }
100:
101: @Override
102: public void keyTyped(KeyEvent ke) {
103: //System.out.println("kt="+ke);
104: }
105:
106: });
107:
108: table.addMouseListener(new MouseAdapter() {
109: @Override
110: public void mousePressed(MouseEvent me) {
111: if (me.getClickCount() == 2) {
112: dialog.selectAndQuit();
113: }
114: }
115: });
116: }
117:
118: /** Just look at the lower right corner, this is the main problem of complection dialogs
119: when they are popped from a textpane position that is near the lower frame position or right border.
120: */
121: public static void ensureDialogInScreen(JDialog dialog) {
122: int sw = (int) Toolkit.getDefaultToolkit().getScreenSize()
123: .getWidth();
124: if (dialog.getLocation().getX() + dialog.getWidth() > sw) {
125: dialog.setLocation(sw - dialog.getWidth(), dialog.getY());
126: }
127: int sh = (int) Toolkit.getDefaultToolkit().getScreenSize()
128: .getHeight();
129: if (dialog.getLocation().getY() + dialog.getHeight() > sh) {
130: dialog.setLocation(dialog.getX(), sh - dialog.getHeight());
131: }
132: }
133:
134: }
|