/* * RapidMiner * * Copyright (C) 2001-2008 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.look.fc; import java.awt.event.InputMethodEvent; import java.awt.event.InputMethodListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Enumeration; import java.util.Vector; import javax.swing.JList; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.text.BadLocationException; /** * This text field is connected to the file chooser and provides some automation mechanisms. * * @author Ingo Mierswa * @version $Id: AutomaticTextField.java,v 1.2 2008/05/09 19:22:53 ingomierswa Exp $ */ public class AutomaticTextField extends JTextField implements KeyListener, CaretListener, InputMethodListener { private static final long serialVersionUID = 9138792080755085206L; private FileChooserUI fileChooserUI; private JList itemList = new JList(new Object[] {}); private JPopupMenu popupMenu = new JPopupMenu(); private Vector<String> fileList = new Vector<String>(); private int caretPosition = 0; private String mainText; public AutomaticTextField(FileChooserUI fcui) { super(); this.fileChooserUI = fcui; this.addCaretListener(this); this.addKeyListener(this); } private Vector findItems() { if (this.mainText == null) { this.mainText = this.getText(); } this.fileList.removeAllElements(); Enumeration en = this.fileChooserUI.fileList.visibleItemsList.elements(); while (en.hasMoreElements()) { Item vi = (Item) en.nextElement(); if (vi.getFileName().toLowerCase().startsWith(this.mainText.toLowerCase().substring(0, Math.min(this.caretPosition, this.mainText.length())))) { this.fileList.add(vi.getFileName()); } } return this.fileList; } private void generatePopup(boolean help) { this.popupMenu.setVisible(false); this.popupMenu.removeAll(); final JTextField t = this; this.popupMenu.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().toLowerCase().equals("visible")) { if (e.getNewValue().toString().toLowerCase().equals("false")) { AutomaticTextField.this.mainText = t.getText(); } } } }); this.itemList = new JList(findItems()); this.itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.itemList.setBorder(null); this.itemList.setAutoscrolls(true); this.itemList.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { AutomaticTextField.this.popupMenu.setVisible(false); t.setSelectionEnd(0); t.setCaretPosition(t.getText().length()); } }); this.itemList.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { AutomaticTextField.this.popupMenu.setVisible(false); t.setSelectionEnd(0); t.setText(AutomaticTextField.this.mainText); t.setCaretPosition(t.getText().length()); } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { AutomaticTextField.this.popupMenu.setVisible(false); t.setSelectionEnd(0); t.setCaretPosition(t.getText().length()); } } }); this.itemList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { AutomaticTextField.this.itemList.scrollRectToVisible(AutomaticTextField.this.itemList.getCellBounds(AutomaticTextField.this.itemList.getSelectedIndex(), AutomaticTextField.this.itemList.getSelectedIndex())); String cpt = AutomaticTextField.this.mainText; try { cpt = t.getText(AutomaticTextField.this.caretPosition, t.getText().length() - AutomaticTextField.this.caretPosition); } catch (BadLocationException ex) { } if (!AutomaticTextField.this.itemList.getModel().getElementAt(AutomaticTextField.this.itemList.getSelectedIndex()).toString().equals(cpt)) { t.setText(AutomaticTextField.this.itemList.getModel().getElementAt(AutomaticTextField.this.itemList.getSelectedIndex()).toString()); t.setCaretPosition(AutomaticTextField.this.caretPosition); if ((AutomaticTextField.this.caretPosition == 0) || !t.getText().toLowerCase().startsWith(AutomaticTextField.this.mainText.toLowerCase())) { t.select(0, t.getText().length()); } else { t.select(AutomaticTextField.this.mainText.length(), t.getText().length()); } } } }); JScrollPane scroller = new JScrollPane(this.itemList); scroller.setBorder(null); scroller.setFocusable(false); this.popupMenu.add(scroller); int h = 30; try { if (this.itemList.getModel().getSize() > 0) { h = (int) (this.itemList.getModel().getSize() * this.itemList.getCellBounds(0, 0).getHeight()) + 10; } } catch (Exception exp) { } this.popupMenu.setPopupSize(this.getWidth() - 6, Math.min(100, h)); if (this.itemList.getModel().getSize() > 0) { this.popupMenu.show(this, 3, this.getHeight() - 2); if (help) { this.itemList.getSelectionModel().setSelectionInterval(0, 0); } } } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { this.popupMenu.setVisible(false); this.setSelectionEnd(0); this.setCaretPosition(this.getText().length()); this.mainText = this.getText(); } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { if (this.popupMenu.isVisible()) { this.setText(this.mainText); this.popupMenu.setVisible(false); this.setSelectionEnd(0); this.setCaretPosition(this.getText().length()); e.consume(); } } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { this.caretPosition = this.getCaretPosition(); generatePopup(false); this.requestFocus(); } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { this.caretPosition = this.getCaretPosition(); generatePopup(false); if (!this.popupMenu.isVisible()) { this.setText(this.mainText); this.setCaretPosition(this.caretPosition); } this.requestFocus(); } else if (e.getKeyCode() == KeyEvent.VK_UP) { if (!this.popupMenu.isVisible()) { generatePopup(true); } int n = this.itemList.getSelectedIndex(); n -= 1; if (n < 0) { n = 0; } this.itemList.setSelectedIndex(n); this.requestFocus(); } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { if (!this.popupMenu.isVisible()) { generatePopup(true); } int n = this.itemList.getSelectedIndex(); n += 1; if (n >= this.itemList.getModel().getSize()) { n = this.itemList.getModel().getSize() - 1; } this.itemList.setSelectedIndex(n); this.requestFocus(); } else if ((e.getKeyCode() == KeyEvent.VK_BACK_SPACE) || (e.getKeyCode() == KeyEvent.VK_DELETE)) { e.consume(); this.mainText = this.getText(); this.requestFocus(); } if (e.isActionKey() && this.popupMenu.isVisible()) { e.consume(); } } public void keyReleased(KeyEvent e) { if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) || (e.getKeyCode() == KeyEvent.VK_BACK_SPACE)) { e.consume(); } else if (!e.isActionKey()) { this.mainText = this.getText(); generatePopup(true); this.requestFocus(); } } public void keyTyped(KeyEvent e) { if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) || (e.getKeyCode() == KeyEvent.VK_BACK_SPACE)) { e.consume(); } } public void caretUpdate(CaretEvent e) { this.caretPosition = e.getDot(); } public void propertyChange(PropertyChangeEvent evt) {} public void caretPositionChanged(InputMethodEvent event) {} public void inputMethodTextChanged(InputMethodEvent event) {} }