`
liugh1974
  • 浏览: 20501 次
  • 来自: ...
社区版块
存档分类
最新评论

JTextField + JPopupMenu 完全实现google suggest功能

    博客分类:
  • JAVA
阅读更多

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

 }
}

分享到:
评论

相关推荐

    原创:java封装了的JTextField,可以达到google输入框的效果

    在标准的`JTextField`中,虽然没有内置的自动联想或提示功能,但开发者可以通过自定义和扩展`JTextField`的功能来实现类似Google输入框的效果。 这篇原创文章描述的是如何在Java中封装`JTextField`,以实现输入时的...

    JTextField输入时实现位数监听

    通过这种方式,我们可以在`JTextField`中实现输入位数的实时监听和限制。这种机制不仅可以防止用户输入过长的文本,还可以用于实现各种输入验证,例如只允许数字输入、字母输入或者特定格式的文本等。 在实际项目中...

    JTextField添加“自动完成”

    在本文中,我们将探讨如何在不使用继承的情况下,通过组合`JTextField`和`JComboBox`来实现这一功能。 首先,我们需要理解自动完成的核心要求:保持`JTextField`的外观,但利用`JComboBox`的下拉列表特性。为了达到...

    JTextField限制最大数字.txt

    通过以上分析,我们可以看到如何通过自定义`Document`类来实现对`JTextField`的输入限制,以及如何通过扩展`JTextField`来添加额外的功能,如鼠标滚轮控制。这种方法不仅可以应用于限制数字输入的情况,还可以根据...

    jTextField中关键字加颜色

    上述代码实现了一种基本的关键字高亮显示功能,能够实现在文本区域 (`jTextArea1`) 中对特定关键字 (`jTextField1` 中输入的文本) 进行颜色高亮。此方法的核心在于关键字的搜索与匹配以及使用 `Highlighter` 接口...

    弹窗辅助输入JTextField

    本知识点将深入探讨如何扩展JTextField实现这样的弹窗辅助输入功能,并结合JTable进行使用。 首先,`PopWindowTextFiled.java`是关键类,它扩展了JTextField,增加了弹窗显示功能。这个类需要实现一个监听机制,...

    带水印(背景)的JTextField

    标题中的“带水印(背景)的JTextField”指的是在Java Swing编程中,为JTextField组件添加水印或背景图像的功能。在Java图形用户界面设计中,JTextField是用于接收单行文本输入的基本组件。而水印效果通常是指在...

    java JTextField美化Demo

    实现圆角矩形边框,hint文字,主要代码: Graphics2D g2d=(Graphics2D) g; g2d.setStroke(new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND)); g2d.setComposite(AlphaComposite.getInstance...

    其他类别jsp+servlet+javaBean实现MVC-jspmvc.zip

    jsp+servlet+javaBean实现MVC_jspmvc public static void main(String[] args) { addrecord frame=new addrecord(); } JLabel lb; JLabel lb1[]=new JLabel[8]; JTextField tf1[]=new JTextField[8]; String...

    Java+Swing+Txt实现自助款机系统

    在Java Swing中,开发者可以使用各种组件来构建用户界面,如JFrame(窗口)、JButton(按钮)、JLabel(标签)、JTextField(文本框)等。例如,在这个ATM系统中,可能会有一个JFrame作为主窗口,包含多个JButton...

    Java+Swing+Txt实现通讯录管理系统

    本项目"Java+Swing+Txt实现通讯录管理系统"利用了Swing库来创建用户界面,并结合文本文件(Txt)进行数据存储,实现了基本的通讯录管理功能,包括添加联系人、删除联系人、修改联系人信息以及查询联系人等操作。...

    Java+Swing+Mysql实现学生信息管理系统

    它构建在Java Foundation Classes (JFC) 上,提供了一套完全基于Java的组件,包括按钮、文本框、表格、菜单等,使得开发者可以轻松地设计出美观且功能强大的用户界面。 在学生信息管理系统中,Swing可能被用来创建...

    JTextField_Example.java

    JTextField_Example.java

    大学Java实验作业:运用SWing,MYsql 实现简单登录,注销,注册,改密功能

    在这个实验中,学生将用到JFrame作为主窗口,JButton用于用户交互,JLabel显示信息,JTextField收集用户输入,以及可能的JOptionPane用于弹出对话框来提示用户或获取输入。 **MySQL数据库**是一种广泛使用的开源...

    java JTextField组件的使用

    本文将详细介绍JTextField的使用方法、功能特性以及如何在实际编程中应用。 1. **JTextField简介** JTextField是javax.swing.text包下的一个类,它提供了单行文本输入的功能。用户可以在文本框内输入、修改或查看...

    Java+Swing+Txt实现宠物管理系统

    Swing 提供了一系列预定义的组件,如按钮(JButton)、文本框(JTextField)、表格(JTable)和菜单(JMenu),这些组件使得开发者能够构建出功能丰富的用户界面。在宠物管理系统中,可能包括了添加、编辑、删除宠物...

    控制JTextField的输入

    这篇博客“控制JTextField的输入”主要探讨了如何实现这些功能。 首先,我们可以使用`DocumentFilter`来过滤`JTextField`中的输入。`DocumentFilter`是`javax.swing.text.Document`接口的一个子类,它可以拦截并...

    Java+swing+完全完整实例Java实用源码整理learns

    描述中提到的"完全完整实例"可能包括了Swing的各种常见功能和设计模式的示例,例如窗口管理、布局管理器的使用(如FlowLayout、GridLayout、BorderLayout和GridBagLayout)、事件监听器的实现、组件间通信、数据模型...

    Java实现登录功能

    Java实现登录功能是软件开发中的基础操作,尤其在构建用户界面时不可或缺。在这个实验任务中,我们将关注单一职责原则的应用,这是设计模式中的一项重要原则,有助于提高代码的可读性和可维护性。遵循单一职责原则,...

Global site tag (gtag.js) - Google Analytics