package com.liugh.swing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class SuggestTextField extends JPanel implements KeyListener,
MouseListener {
private JTextField textField;
private JPopupMenu popupMenu;
private JPopupMenu ctrlPopupMenu;
private JMenuItem copy;
private JMenuItem paste;
private JMenuItem cut;
private int itemIndex = 0;
private String oldTxt = "";
// default width
private int width = 90;
// default height
private int height = 20;
private Component nextComponent;
public SuggestTextField() {
super();
textField = new JTextField();
textField.addKeyListener(this);
textField.setFocusTraversalKeysEnabled(false);
popupMenu = new JPopupMenu();
add(textField);
initControlMenu();
}
private void initControlMenu() {
textField.addMouseListener(this);
ctrlPopupMenu = new JPopupMenu();
ctrlPopupMenu.add(copy = new JMenuItem("Copy"));
ctrlPopupMenu.add(paste = new JMenuItem("Paste"));
ctrlPopupMenu.add(cut = new JMenuItem("Cut"));
copy.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK));
paste.setAccelerator(KeyStroke.getKeyStroke('V', InputEvent.CTRL_MASK));
cut.setAccelerator(KeyStroke.getKeyStroke('X', InputEvent.CTRL_MASK));
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action(e);
}
});
paste.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action(e);
}
});
cut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
action(e);
}
});
textField.add(ctrlPopupMenu);
}
private void action(ActionEvent e) {
String str = e.getActionCommand();
if (str.equals(copy.getText())) {
textField.copy();
} else if (str.equals(paste.getText())) {
textField.paste();
} else if (str.equals(cut.getText())) {
textField.cut();
}
if (!oldTxt.equals(textField.getText())) {
suggest();
}
}
// self implement function
public List<String> loadData(String s) {
return new ArrayList<String>();
}
public void setNextComponent(Component c) {
nextComponent = c;
}
public void requestFocus() {
textField.requestFocus();
}
public void setText(String txt) {
textField.setText(txt);
}
public String getText() {
return textField.getText();
}
public void setComboBoxSize(int width, int height) {
this.width = width;
this.height = height;
textField.setMaximumSize(new Dimension(width, height));
textField.setMinimumSize(new Dimension(width, height));
textField.setPreferredSize(new Dimension(width, height));
}
private boolean isControlKey(int code) {
// 40 down , 39 right , 38 up , 37 left
// 27 esc , 20 Caps Lock , 18 alt , 17 ctrl ,
// 16 shift , 10 enter , 9 tab
return code == 40 || code == 39 || code == 38 || code == 37
|| code == 27 || code == 20 || code == 16 || code == 17
|| code == 18 || code == 10 || code == 9;
}
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
// System.out.println(code);
String txt = textField.getText();
if (!isControlKey(code) && !txt.equals(oldTxt)) {
suggest();
} else if (code == 40 || code == 38) {
int count = popupMenu.getComponentCount();
if (count > 0) {
if (code == 40) {
itemIndex++;
} else {
itemIndex--;
}
if (itemIndex == count) {
itemIndex = 0;
} else if (itemIndex < 0) {
itemIndex = count - 1;
}
JMenuItem item = (JMenuItem) popupMenu.getComponent(itemIndex);
textField.setText(item.getText());
oldTxt = textField.getText();
}
} else if (code == 27 || code == 10 || code == 9) {
popupMenu.removeAll();
popupMenu.setVisible(false);
if (code == 9 && nextComponent != null) {
nextComponent.requestFocus();
}
}
}
private void suggest() {
String txt = textField.getText();
oldTxt = txt;
itemIndex = 0;
popupMenu.setVisible(false);
if (txt.length() > 0) {
List<String> searchResult = loadData(txt);
if (searchResult.size() > 0) {
popupMenu.removeAll();
for (String s : searchResult) {
JMenuItem item = new JMenuItem(s);
item.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
textField.setText(((JMenuItem) e.getSource())
.getText());
popupMenu.setVisible(false);
}
});
popupMenu.add(item);
}
popupMenu.setPopupSize(new Dimension(width, searchResult.size()
* height));
popupMenu.show(textField, 0, height + 1);
textField.requestFocus();
}
}
}
public boolean isClipboardString() {
boolean b = false;
Clipboard clipboard = textField.getToolkit().getSystemClipboard();
Transferable content = clipboard.getContents(this);
try {
if (content.getTransferData(DataFlavor.stringFlavor) instanceof String) {
b = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
public boolean isCanCopy() {
boolean b = false;
int start = textField.getSelectionStart();
int end = textField.getSelectionEnd();
if (start != end)
b = true;
return b;
}
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
copy.setEnabled(isCanCopy());
paste.setEnabled(isClipboardString());
cut.setEnabled(isCanCopy());
ctrlPopupMenu.show(textField, e.getX(), e.getY());
}
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}