package com.client.view;import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;import com.client.pojo.Place;
import com.client.pojo.Unit;
import com.client.pojo.User;public class Test extends JFrame { CompletableJTextField textField; public Test() {
super();
getContentPane().setLayout(new FlowLayout()); Set<String> set = new HashSet<String>();
set.add("abcdefg");
set.add("abcdefghijkl");
set.add("acdesdasijkl");
set.add("esdasijklabcsd");
set.add("aijklabcsd");
set.add("alabcsd");
set.add("asdasijklabcsd");
set.add("asijklabcsd");
set.add("aesdasijklabcsd");
set.add("aabcsd");
textField = new CompletableJTextField(0);
textField.setPreferredSize(new Dimension(200, 30));
textField.setCompletions(set); getContentPane().add(textField); setSize(400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} public static void main(String[] args) {
new Test();
}


class CompletableJTextField extends JTextField { private static final long serialVersionUID = 1L; JList completionList; DefaultListModel completionListModel; JScrollPane listScroller; JWindow listWindow; Set completions; String completionString; public CompletableJTextField(int col) {
super(col);
getDocument().addDocumentListener(new Completer());
completionListModel = new DefaultListModel();
completionList = new JList(completionListModel);
completionList
.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); listScroller = new JScrollPane(completionList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); listWindow = new JWindow();
listWindow.setLocationRelativeTo(this);
listWindow.setPreferredSize(new Dimension(200, 150));
listWindow.getContentPane().add(listScroller); completionList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
listWindow.setVisible(false);
completionString = (String) completionList
.getSelectedValue();
setText(completionString);
}
}
}); addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode();
int index = completionList.getSelectedIndex();
System.out.println("=========================" + index);
completionList.setVisibleRowCount(8);
if (k == e.VK_DOWN) {
index = index + 1;
completionList.setSelectedIndex(index);
}
if (k == e.VK_UP) {
index = index - 1;
completionList.setSelectedIndex(index);
} if (k == e.VK_ENTER) {
listWindow.setVisible(false);
completionString = (String) completionList
.getSelectedValue();
if (completionString != null) {
setText(completionString);
}
} } public void keyReleased(KeyEvent arg0) { } public void keyTyped(KeyEvent arg0) { }
});
} public Set getCompletions() {
return completions;
} public void setCompletions(Set completions) {
this.completions = completions;
} class Completer implements DocumentListener { private Pattern pattern; private void buildPopup() {
completionListModel.clear();
Iterator it = completions.iterator();
pattern = pattern.compile(getText() + ".+");
Matcher matcher = null;
while (it.hasNext()) {
String completion = (String) it.next();
matcher = pattern.matcher(completion);
if (matcher.matches()) {
completionListModel.add(completionListModel.getSize(),
completion);
}
}
} private void showPopup() {
if (completionListModel.getSize() == 0) {
listWindow.setVisible(false);
return;
}
Point los = getLocationOnScreen();
int popX = los.x;
int popY = los.y + getHeight();
listWindow.setLocation(popX, popY);
listScroller.setSize(new Dimension(200, 60));
listWindow.pack();
listWindow.setVisible(true);
} private void buildAndShowPopup() {
if (getText().length() < 1) {
listWindow.setVisible(false);
return;
} else {
buildPopup();
showPopup();
}
} public void changedUpdate(DocumentEvent arg0) {
buildAndShowPopup();
} public void insertUpdate(DocumentEvent arg0) {
buildAndShowPopup();
} public void removeUpdate(DocumentEvent arg0) {
buildAndShowPopup();
}
}
}}这个程序求高手帮我完善一下,具体效果 拷下来运行一下就知道了,现在效果不是很理想,
缺陷1:不能循环选择
缺陷2:JScrollPane 的下拉工具 不跟着我选择的项移动或者谁有更好的控件可以发 }}这个程序求高手帮我完善一下,具体效果 拷下来运行一下就知道了,现在效果不是很理想,
缺陷1:不能循环选择
缺陷2:JScrollPane 的下拉工具 不跟着我选择的项移动或者谁有更好的控件可以发

解决方案 »

  1.   

    除了你说的,还有很多问题,难道你没有发现?
    弹出了窗体,加入我后面加一个按钮,我点按钮的时候,这个窗体应该隐藏起来吧?你这个做不到。所以这里建议不要用jwindow,当然使用也可以了,但需要额外处理。
    第一次启动,直接按向上键会抛出异常。这或许算是jdk处理的不太严谨的地方,如果是-1它会过滤掉,但如果是其他的负数,它却会继续执行而至出现异常。所以这地方,需要你处理,你给出大于最大的,不必担心,它会处理。
    至于你所说的两个问题,很容易处理。你还是先仔细规划设计一下,什么按键会有什么动作吧。现在有些乱。
      

  2.   

    罢了,闲了一天,我自己写了一个。
    有些地方或许有不符的地方,你自己看着改改吧,或者跟我说看怎么改也可以。/**
     * @author 黯淡星辰
     */
    public class ImitateComponent extends JTextField { private static final long serialVersionUID = 1L;
    private Vector<Object> allData; private Vector<Object> currentData;
    JPopupMenu menu;
    JList list; private boolean shouldFilter = true; public ImitateComponent(Vector<Object> allData) {
    super();
    this.allData = allData;
    currentData = new Vector<Object>(allData); initComponents();
    addKeyListener(keyListener); getDocument().addDocumentListener(documentListener);
    } private void initComponents() {
    menu = new JPopupMenu();
    menu.setInvoker(this);
    menu.setInheritsPopupMenu(true);
    menu.setLightWeightPopupEnabled(true); list = new JList();
    list.setFixedCellHeight(25);
    list.setVisibleRowCount(10);
    list.setModel(new ImitateListModel());
    list.addMouseListener(listMouseListener);
    menu.add(new JScrollPane(list));
    } private class ImitateListModel extends DefaultListModel {
    private static final long serialVersionUID = 1L; @Override
    public int getSize() {
    return currentData.size();
    } @Override
    public Object getElementAt(int index) {
    return currentData.get(index);
    }
    } private void filterValues(String filterStr) {
    currentData.clear();
    if (filterStr == null || "".equals(filterStr)) {
    currentData.addAll(allData); } else { for (Iterator<Object> it = allData.iterator(); it.hasNext();) {
    Object obj = it.next();
    String sValue = obj == null ? "" : obj.toString();
    if (sValue.toUpperCase().startsWith(filterStr.toUpperCase())) {
    currentData.add(obj);
    }
    }
    }
    list.setModel(new ImitateListModel());
    list.setSelectedIndex(-1);
    showPopup();
    } private void showPopup() {
    Rectangle bounds = getBounds();
    Point location = getLocationOnScreen(); menu.setPopupSize(bounds.width, list.getFixedCellHeight()
    * list.getModel().getSize());
    menu.setLocation(location.x, location.y + bounds.height); menu.setVisible(true);
    requestFocus();
    } private DocumentListener documentListener = new DocumentListener() { @Override
    public void removeUpdate(DocumentEvent e) {
    if (shouldFilter) {
    String text = getText();
    filterValues(text);
    } } @Override
    public void insertUpdate(DocumentEvent e) {
    if (shouldFilter) {
    String text = getText();
    filterValues(text);
    } } @Override
    public void changedUpdate(DocumentEvent e) { }
    }; private KeyListener keyListener = new KeyListener() { @Override
    public void keyTyped(KeyEvent e) {
    } @Override
    public void keyReleased(KeyEvent e) { } @Override
    public void keyPressed(KeyEvent e) {
    String text = getText();
    if (e.getKeyCode() == KeyEvent.VK_UP) {
    shouldFilter = false;
    if (!menu.isVisible()) {
    filterValues(text);
    } else {
    int index = list.getSelectedIndex();
    index--;
    index = index < 0 ? list.getModel().getSize() - 1 : index; list.setSelectedIndex(index);
    Object obj = list.getModel().getElementAt(index);
    setText(obj == null ? "" : obj.toString());
    } shouldFilter = true; } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    shouldFilter = false;
    if (!menu.isVisible()) {
    filterValues(text);
    } else {
    int index = list.getSelectedIndex();
    index++;
    index = index >= list.getModel().getSize() - 1 ? 0 : index; list.setSelectedIndex(index);
    Object obj = list.getModel().getElementAt(index);
    setText(obj == null ? "" : obj.toString());
    } shouldFilter = true;
    } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    shouldFilter = false;
    if (!menu.isVisible()) {
    filterValues(text);
    } else {
    int index = list.getSelectedIndex();
    if (index < 0) {
    return;
    } Object obj = list.getModel().getElementAt(index);
    setText(obj == null ? "" : obj.toString());
    menu.setVisible(false);
    } shouldFilter = true;
    } }
    }; private MouseAdapter listMouseListener = new MouseAdapter() {
    public void mouseClicked(java.awt.event.MouseEvent e) {
    int index = list.getSelectedIndex();
    Object obj = list.getModel().getElementAt(index);
    setText(obj == null ? "" : obj.toString());
    menu.setVisible(false);
    }
    };
    }测试窗口:
    public class ImitateFrame extends JFrame {
    private static final long serialVersionUID = 1L;
    private String[] values = new String[] { "ab", "ac", "ad", "bc", "bd", "cc" }; public ImitateFrame() {
    super();
    setDefaultCloseOperation(EXIT_ON_CLOSE); installComponents();
    setSize(600, 400);
    setLocationRelativeTo(null);
    setVisible(true);
    } private void installComponents() {
    Container c = getContentPane();
    c.setLayout(new BorderLayout());
    c.add(new ImitateComponent(new Vector<Object>(Arrays.asList(values))),
    BorderLayout.NORTH); } public static void main(String[] args) {
    new ImitateFrame();
    }
    }
      

  3.   

    修正一个错误:index = index >= list.getModel().getSize() - 1 ? 0 : index;在处理vk_down的时候,这行代码不正确。应替换为:index = index > list.getModel().getSize() - 1 ? 0 : index;否则最后一项选不上。