【问题标题】:JTable keypressed event is fired only for the first key pressedJTable keypressed 事件仅在按下的第一个键时触发
【发布时间】:2012-09-06 15:12:51
【问题描述】:

我正在创建一个计费软件,我想显示数据库中与我的 JTable 的项目列中键入的值相匹配的项目名称。为此,我添加了一个 KeyListener。一切正常,除了只有第一个键,keypressed 事件被触发。如果我按回车键然后再次输入,它会再次被触发。我希望为连续输入到列中的每个键触发 keyevent,任何人都可以帮我....?

我将给出代码 sn-p...我希望 DB 中的项目显示在 itable 中...

     public void keyPressed(KeyEvent e) {
        rows=table.getSelectedRow();
        cols=table.getSelectedColumn();
        if(cols==2){
           String code=(String)table.getValueAt(rows, cols);

           Statement stmt = null;
           ResultSet rs = null;

           for (int i =model1.getRowCount();i>0; i--) {
              model1.removeRow(i-1);
            }
            table.changeSelection(rows,cols, false, false);

           itable.setVisible(true);
           int i=0;
           String SQL = "SELECT * FROM items where name like\'"+code+"%\' or
                           code=\'"+code+"\' order by name";

           try{
               stmt =  (Statement) dbcon.con.createStatement();
               rs = stmt.executeQuery(SQL);
               while (rs.next()) {
                    model1.insertRow((i),new Object[]{""});
                    itable.setValueAt((Object)rs.getString("name"), i, 0);
                     i++;
                }

            }
            catch(Exception e1){
                  table.editCellAt(rows,cols,null);
                  return;

            }}
        }

【问题讨论】:

标签: java swing jdbc autocomplete


【解决方案1】:

这可能是因为您不再在 JTable 中,而是在表格的 CellEditor 中。

创建一个带有键侦听器的 JTextField。将其作为表格的编辑器(通过 getColumn().setCellEditor()) 并使用“textCellEditor.setClickCountToStart(1);”定义您的单元格编辑器

【讨论】:

  • 不,错误请检查@trashgod评论中链接的代码
【解决方案2】:
  • 不要将KeyListener 用于Swing JComponents,此Listener 既不是为JTextComponents 指定的,也不是为Compound JComponents 指定为JTableJSpinnerJComboBox

  • 不要在每个事件上都对ResultSet运行Database,也不要打开JDBC Connection,因为这两个操作可能需要很长时间,并且GUI在这种形式中等待直到ResultSet结束

  • ConnectionResultsetStatement 必须是 close(),并进入 finally 块 (try - catch - finally) 否则会留在内存中,数据库也可以减少连接数,您可以获取OutOfMemory 或数据库可以拒绝打开新连接,因为您超载了打开的最大并发连接数

  • 您的代码谈论将减少的记录数加载到AutoCompleted JComboBox or JTextField,仅在应用程序启动时一次,

  • 那你可以问一个新问题How to .....

【讨论】:

    【解决方案3】:

    问题是,一旦您在选定表格的情况下键入一个键,该表格就会开始编辑该选定项目(并且以下所有键事件都将被定向到该“TableCellEditor”)。

    假设您不希望以这种方式编辑任何数据,一个简单的解决方案是覆盖“DefaultTableModel”,这样所有数据都不可编辑。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    
    public class TestProject extends JPanel{
    
        public TestProject(){
            super();
    
            //Use default table model - only make it so no cells are editable
            final DefaultTableModel model = new DefaultTableModel(0, 5){
                @Override
                public boolean isCellEditable(int row, int column){
                    return false; // makes no table cells editable
                }
            };
    
            //Create table off of Table Row
            final JTable table = new JTable(model);
            for(int i = 0; i < 20; i++){
                model.addRow(new String[]{i+".1", i+".2",i+".3",i+".4",i+".5",});
            }
    
            add(table, BorderLayout.CENTER);
    
            //Add Key Listener
            table.addKeyListener(new KeyAdapter() {         
                 public void keyPressed(KeyEvent e) {
                     System.out.println("pressed");
                     char key = e.getKeyChar();
                     int selectedColumn = table.getSelectedColumn();
    
                     //Update info in table
                     for(int i = 0; i < model.getRowCount(); i++){
                         String value = (String)model.getValueAt(i, selectedColumn);
                         model.setValueAt(value + key, i, selectedColumn);
                     }
                 }
            });
        }
    
        public static void main(String args[])
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                    frame.setContentPane(new TestProject());    
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      相关资源
      最近更新 更多