diff src/viewer_swing/java/com/glavsoft/viewer/swing/gui/AutoCompletionComboEditorDocument.java @ 0:daa24f8a557b

TightVNC original
author YU
date Thu, 11 Sep 2014 07:30:03 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/viewer_swing/java/com/glavsoft/viewer/swing/gui/AutoCompletionComboEditorDocument.java	Thu Sep 11 07:30:03 2014 +0900
@@ -0,0 +1,112 @@
+package com.glavsoft.viewer.swing.gui;
+
+import javax.swing.*;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+
+/**
+ * @author dime at tightvnc.com
+ *
+ * Using idea by Thomas Bierhance from http://www.orbital-computer.de/JComboBox/
+ */
+public class AutoCompletionComboEditorDocument extends PlainDocument {
+
+	private ComboBoxModel model;
+	private boolean selecting;
+	private JComboBox comboBox;
+	private final boolean hidePopupOnFocusLoss;
+	private JTextComponent editor;
+
+	public AutoCompletionComboEditorDocument(final JComboBox comboBox) {
+		this.comboBox = comboBox;
+		this.model = comboBox.getModel();
+		this.editor = (JTextComponent)comboBox.getEditor().getEditorComponent();
+		editor.setDocument(this);
+		comboBox.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (!selecting) highlightCompletedText(0);
+			}
+		});
+
+		Object selectedItem = comboBox.getSelectedItem();
+		if (selectedItem!=null) {
+			setText(selectedItem.toString());
+			highlightCompletedText(0);
+		}
+		hidePopupOnFocusLoss = System.getProperty("java.version").startsWith("1.5");
+		editor.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusLost(FocusEvent e) {
+				if (hidePopupOnFocusLoss) comboBox.setPopupVisible(false);
+			}
+		});
+	}
+
+	@Override
+	public void remove(int offs, int len) throws BadLocationException {
+		if (selecting) return;
+		super.remove(offs, len);
+	}
+
+	@Override
+	public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+		if (selecting) return;
+		super.insertString(offs, str, a);
+		Object item = lookupItem(getText(0, getLength()));
+		if (item != null) {
+			setSelectedItem(item);
+			setText(item.toString());
+			highlightCompletedText(offs + str.length());
+			if (comboBox.isDisplayable()) comboBox.setPopupVisible(true);
+		}
+	}
+
+	private void setText(String text) {
+		try {
+			super.remove(0, getLength());
+			super.insertString(0, text, null);
+		} catch (BadLocationException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private void setSelectedItem(Object item) {
+		selecting = true;
+		model.setSelectedItem(item);
+		selecting = false;
+	}
+
+	private void highlightCompletedText(int offs) {
+		JTextComponent editor = (JTextComponent) comboBox.getEditor().getEditorComponent();
+		editor.setSelectionStart(offs);
+		editor.setSelectionEnd(getLength());
+	}
+
+	private Object lookupItem(String pattern) {
+		Object selectedItem = model.getSelectedItem();
+		if (selectedItem != null && startsWithIgnoreCase(selectedItem, pattern)) {
+			return selectedItem;
+		} else {
+			for (int i = 0, n = model.getSize(); i < n; i++) {
+				Object currentItem = model.getElementAt(i);
+				if (startsWithIgnoreCase(currentItem, pattern)) {
+					return currentItem;
+				}
+			}
+		}
+		return null;
+	}
+
+	private boolean startsWithIgnoreCase(Object currentItem, String pattern) {
+		return currentItem.toString().toLowerCase().startsWith(pattern.toLowerCase());
+	}
+
+
+}