JTextField + JPopupMenu 完全实现google suggest功能

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

 }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值