问题描述
我在我的 java swing 程序中有这样一段代码:
JTextField textfield = (JTextField) txtNameID.getEditor().getEditorComponent();
textfield.addKeyListener(new KeyAdapter() {
public void keypressed(KeyEvent ke) {
SwingUtilities.invokelater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
}
});
}
});
它的功能是显示数据库中的名称,就像在文本字段中键入的名称一样。一旦用户开始输入,它就会显示出来。
这在使用硬键盘时效果很好。但我的问题是我必须为此程序使用屏幕键盘/虚拟键盘,而 KeyListener 无法使用它。现在我不知道我应该使用什么类型的事件监听器。我试过 MouseListener 但它也不起作用。我希望有办法。我的项目真的需要这个。请帮助我。
这是我的屏幕键盘代码(在同一个类中,在不同的类中有更长的代码):
textfield.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
DialogVirtualKeyboardReal dlg = new DialogVirtualKeyboardReal(this,false,textfield);
dlg.setLocaleL(locale);
}
});
textfield.addMouseListener(new MouseListener() {
@Override
public void mousepressed(MouseEvent me) {
DialogVirtualKeyboardReal dlg = new DialogVirtualKeyboardReal(r,textfield);
dlg.setLocaleL(locale);
}
@Override
public void mouseReleased(MouseEvent me) {
}
@Override
public void mouseEntered(MouseEvent me) {
}
@Override
public void mouseExited(MouseEvent me) {
}
@Override
public void mouseClicked(MouseEvent me) {
}
});
这是 DialogVirtualKeyboardReal 的图片:
按键由 JButton 组成。
编辑: 我按照@Abra 的说明尝试了 DocumentListener。
键盘会弹出,但在文本字段中输入 1 个字母后它就会消失,并且会弹出文本字段下方的名称。
即使我从虚拟键盘输入时,comboFilter 也会出现,这很好。但我希望它同时执行,在虚拟键盘上打字时,应该会出现组合过滤器。
这是我创建的代码:
JTextField textfield = (JTextField) txtNameID.getEditor().getEditorComponent();
textfield.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void insertUpdate(DocumentEvent de) {
filter();
}
@Override
public void removeUpdate(DocumentEvent de) {
filter();
}
@Override
public void changedUpdate(DocumentEvent de) {
filter();
}
public void filter(){
SwingUtilities.invokelater(new Runnable() {
public void run() {
comboFilter(textfield.getText());
}});
} });
错误是:
errorcom.MysqL.jdbc.exceptions.jdbc4.MysqLNonTransientConnectionException: Data source rejected establishment of connection,message from server: "Too many connections"
comboFilter() 代码是:
public void comboFilter(String enteredText) {
List<String> filterarray= new ArrayList<String>();
String lname="";
String fname= "";
String mi= "";
String id= "";
try{
String str="SELECT * FROM patient_record WHERE firstname LIKE '"+enteredText+"%' OR lastname LIKE '"+enteredText+"%' OR patient_id LIKE '"+enteredText+"%'";
Class.forName("com.MysqL.jdbc.Driver");
String url = "jdbc:MysqL://localhost/patient";
Connection con = DriverManager.getConnection(url,"root","");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(str);
while(rs.next()){
lname=rs.getString("lastname");
fname= rs.getString("firstname");
mi= rs.getString("middlename");
id= rs.getString("patient_id");
String str1 = lname+","+fname+" "+mi+". \t"+id;
filterarray.add(str1);
}}
catch(Exception ex){
System.out.println("error"+ex);
}
if (filterarray.size() > 0) {
jComboBox1.setModel(new DefaultComboBoxModel(filterarray.toArray()));
jComboBox1.setSelectedItem(enteredText);
jComboBox1.showPopup();
}
else {
jComboBox1.hidePopup();
}
}
我知道我解释的方式很难理解。请多多包涵。你们可以提出进一步的问题以更好地理解我的问题。非常感谢!
解决方法
所以我做了一个小例子来帮助你,但在此之前:
-
您的 SQL 错误“连接过多”,您可能想在所有打开数据库连接的地方执行
con.close()
,如下所示:Connection con = null try { // create the connection and do your database work here } catch (Exception ex) { // log your exception here } finally { if (con != null) { // finally lets close the connection (event in the event of a exception) con.close(); } }
-
DialogVirtualKeyboardReal
代码(不冒犯作者并不是最好的,因为它不能很好地满足键盘不是 modal 的情况),所以你输入时无法显示对话框,除非您将其设为 modal 即将true
传递到DialogVirtualKeyboardReal
构造函数(这就是我的示例所做的),或者更改实际的 { {1}},但这是一个全新的话题。 -
由于我的上述声明,在您键入时显示
DialogVirtualKeyboardReal
弹出窗口是没有意义的,因为它可能会覆盖键盘。
说了这么多,我希望这可以帮助您入门(我的 JComboBox
方法只是模拟响应,就好像它是来自数据库的结果一样):
TestApp.java
comboFilter