001: package net.sourceforge.squirrel_sql.fw.completion;
002:
003: import javax.swing.*;
004: import java.awt.event.*;
005:
006: /**
007: * This tries to handle the focus of the completion popup
008: * and tell its listener when the completion popup lost focus.
009: * <p/>
010: * Note: this class does not send focus gained events.
011: */
012: public class CompletionFocusHandler {
013: private TextComponentProvider _txtComp;
014: private JList _completionList;
015: private FocusListener _completionFocusListener;
016: private Timer _timer;
017: private ActionListener _timerActionListener;
018: private FocusEvent _lastFocusEvent;
019:
020: public CompletionFocusHandler(TextComponentProvider txtComp,
021: JList completionList) {
022: _txtComp = txtComp;
023: _completionList = completionList;
024:
025: _timerActionListener = new ActionListener() {
026: public void actionPerformed(ActionEvent e) {
027: onTimerAction();
028: }
029: };
030:
031: _timer = new Timer(200, null);
032: _timer.setRepeats(false);
033:
034: _completionList.addFocusListener(new FocusAdapter() {
035: public void focusGained(FocusEvent e) {
036: //System.out.println("################_completionList.focusGained");
037: onCompletionListFocusGained(e);
038: onFocusGained(e);
039: }
040:
041: public void focusLost(FocusEvent e) {
042: //System.out.println("################_completionList.focusLost");
043: onFocusLost(e);
044: }
045: });
046:
047: if (_txtComp.editorEqualsFilter()) {
048: _txtComp.getEditor().addFocusListener(new FocusListener() {
049: public void focusGained(FocusEvent e) {
050: //System.out.println("################editor.focusGained " + _txtComp.getEditor());
051: onFocusGained(e);
052: }
053:
054: public void focusLost(FocusEvent e) {
055: //System.out.println("################editor.focusLost " + _txtComp.getEditor());
056: onFocusLost(e);
057: }
058: });
059: } else {
060: _txtComp.getFilter().addFocusListener(new FocusListener() {
061: public void focusGained(FocusEvent e) {
062: //System.out.println("################filter.focusGained");
063: onFocusGained(e);
064: }
065:
066: public void focusLost(FocusEvent e) {
067: //System.out.println("################filter.focusLost");
068: onFocusLost(e);
069: }
070: });
071: }
072:
073: }
074:
075: private void onFocusGained(FocusEvent e) {
076: // Temporary events need to be included
077: // in case a modla dialog opens.
078: _timer.stop();
079: _lastFocusEvent = e;
080: }
081:
082: private void onFocusLost(FocusEvent e) {
083: // Note: Temporary events need to be included
084: // in case a modla dialog opens.
085: _lastFocusEvent = e;
086: _timer.start();
087: }
088:
089: private void onTimerAction() {
090: _timer.stop();
091: if (null != _completionFocusListener) {
092: //System.out.println("CompletionFocusHandler.onTimerAction");
093: _completionFocusListener.focusLost(_lastFocusEvent);
094: }
095: }
096:
097: /**
098: * This method has nothing to do with the focus handling outside the
099: * popup it is needed to keep the focus on the filter, if the popup has
100: * its own filter, for example the tools popup.
101: */
102: private void onCompletionListFocusGained(FocusEvent e) {
103: if (false == e.isTemporary()
104: && false == _txtComp.editorEqualsFilter()) {
105: _txtComp.getFilter().requestFocusInWindow();
106: }
107: }
108:
109: public void setFocusListener(FocusListener completionFocusListener) {
110: _completionFocusListener = completionFocusListener;
111:
112: _timer.removeActionListener(_timerActionListener);
113: if (null != _completionFocusListener) {
114: _timer.addActionListener(_timerActionListener);
115: }
116: }
117: }
|