/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.autocomplete; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.text.BadLocationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mucommander.ui.autocomplete.completers.Completer; /** * EditableComboboxCompleter is a CompleterType which suite to editable combobox. * * @author Arik Hadas, based on the code of Santhosh Kumar: http://www.jroller.com/santhosh/entry/file_path_autocompletion */ public class EditableComboboxCompletion extends CompletionType { private static final Logger LOGGER = LoggerFactory.getLogger(EditableComboboxCompletion.class); private class ShowingThreadImp extends ShowingThread { public ShowingThreadImp(int delay) { super(delay); } @Override void showAutocompletionPopup() { if (autocompletedtextComp.isShowing() && autocompletedtextComp.isEnabled() && updateListData(list)){ list.setVisibleRowCount(Math.min(list.getModel().getSize() ,VISIBLE_ROW_COUNT)); int x; try{ x = autocompletedtextComp.modelToView().x; } catch(BadLocationException e){ // this should never happen!!! LOGGER.debug("Caught exception", e); return; } if (autocompletedtextComp.hasFocus()) { if (!isStopped) { list.ensureIndexIsVisible(0); synchronized(popup) { popup.show(autocompletedtextComp.getTextComponent(), x, autocompletedtextComp.getHeight()); // probably because of swing's bug, sometimes the popup window looks // as a gray rectangle - repainting solves it. popup.repaint(); } } } } } } public EditableComboboxCompletion(AutocompleterTextComponent comp, Completer completer){ super(comp, completer); autocompletedtextComp.getDocument().addDocumentListener(documentListener); autocompletedtextComp.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent keyEvent) { switch(keyEvent.getKeyCode()) { case KeyEvent.VK_ENTER: if (isItemSelectedAtPopupList()) { hideAutocompletionPopup(); acceptListItem((String)list.getSelectedValue()); keyEvent.consume(); } else { // Stop the active showing-thread to prevent suggestions-popup // opening after the operation was initiated. if(showingThread!=null) showingThread.done(); autocompletedtextComp.OnEnterPressed(keyEvent); } break; case KeyEvent.VK_ESCAPE: if (isPopupListShowing()) { if (autocompletedtextComp.isEnabled()) hideAutocompletionPopup(); keyEvent.consume(); } else autocompletedtextComp.OnEscPressed(keyEvent); break; case KeyEvent.VK_UP: if(autocompletedtextComp.isEnabled() && popup.isVisible()) { selectPreviousPossibleValue(); keyEvent.consume(); } break; case KeyEvent.VK_DOWN: if(autocompletedtextComp.isEnabled()){ if(popup.isVisible()) { selectNextPossibleValue(); keyEvent.consume(); } } break; case KeyEvent.VK_SPACE: // The combination of cntrl+space makes open the auto-complete popup without delay. if (keyEvent.isControlDown()) { if (!popup.isVisible()) { autocompletedtextComp.setComponentsPopupUnvisibe(); autocompletedtextComp.moveCarentToEndOfText(); createNewShowingThread(0); } } break; case KeyEvent.VK_PAGE_DOWN: if(autocompletedtextComp.isEnabled() && isPopupListShowing()) { selectNextPage(); keyEvent.consume(); } break; case KeyEvent.VK_PAGE_UP: if(autocompletedtextComp.isEnabled() && isItemSelectedAtPopupList()) { selectPreviousPage(); keyEvent.consume(); } break; case KeyEvent.VK_HOME: if(autocompletedtextComp.isEnabled() && isPopupListShowing()) { selectFirstValue(); keyEvent.consume(); } break; case KeyEvent.VK_END: if(autocompletedtextComp.isEnabled() && isPopupListShowing()) { selectLastValue(); keyEvent.consume(); } break; case KeyEvent.VK_LEFT: hideAutocompletionPopup(); break; default: } } }); } @Override protected void hideAutocompletionPopup() { synchronized (popup) { if (popup.isVisible()) popup.setVisible(false); } } @Override protected void startNewShowingThread(int delay) { (showingThread = new ShowingThreadImp(delay)).start(); } }