【问题标题】:Fetch data from database into Jtextfield when One Jtextfield is Typed键入一个 Jtextfield 时从数据库中获取数据到 Jtextfield
【发布时间】:2012-09-26 22:21:48
【问题描述】:

大家好,我有一个连接到 oracle 数据库的 Swing 应用程序,我希望它一旦我在 JTextField 中键入一个值,JFrame 上的其他 JTextfields 就会加载来自数据库的后续数据,但我没有似乎实现了这一点。我已经尝试了以下代码,但它什么也没得到。

txtNo.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent ke) {
            Connection conn = null;
            try{
                Class.forName("oracle.jdbc.driver.OracleDriver");

        conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "Username", "Password");
        Statement st = conn.createStatement();
        String load = "Select * from Store_info_table where PART_NUMBER = '" + txtNo.getText() + "'";
        ResultSet rs = st.executeQuery(load);
        while(rs.next()){
            txtName.setText(rs.getString("SPARE_DESC"));
        }
            }catch(Exception ae){

            }
        }
    });

【问题讨论】:

  • 你试过修剪getText()吗?
  • 是的,我没有 txtName 上没有任何内容。
  • 调试的时候,你的ResultSet有结果吗?
  • 您可能想看看Hw to write focus listeners,这将允许监控用户何时离开该字段并采取行动

标签: java swing autocomplete oracle11g


【解决方案1】:
  • KeyListener 替换为DocumentListener
  • EDT 上的数据库连接是个坏主意(太慢)。有关更多信息,请参阅 concurrency in Swing 指南
  • 您容易受到 SQL 注入的攻击
  • 避免使用空的catch 语句,否则您根本不知道出了什么问题。如果您不选择适当的错误处理,至少记录堆栈跟踪(仅打印它,或使用Logger)。

【讨论】:

    【解决方案2】:

    罗宾和尼克都是对的。

    这是一个如何实现他们正在讨论的内容的示例......

    public class TestForm02 {
    
        public static void main(String[] args) {
            new TestForm02();
        }
    
        public TestForm02() {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
    
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setLayout(new BorderLayout());
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new MyForm());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
    
                }
            });
        }
    
        protected class MyForm extends JPanel {
    
            private JTextField txtNo;
            private JTextField txtName;
            private String partToLoad;
            private Timer loadTimer;
    
            public MyForm() {
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.insets = new Insets(2, 2, 2, 2);
                gbc.anchor = GridBagConstraints.WEST;
    
                txtName = new JTextField(12);
                txtNo = new JTextField(12);
                txtName.setEnabled(false);
    
                add(new JLabel("Parts #:"), gbc);
                gbc.gridx++;
                add(txtNo, gbc);
    
                gbc.gridy++;
                gbc.gridx = 0;
                add(new JLabel("Description:"), gbc);
                gbc.gridx++;
                add(txtName, gbc);
    
                txtNo.addFocusListener(new FocusAdapter() {
                    @Override
                    public void focusLost(FocusEvent e) {
                        loadParts();
                    }
                });
    
                txtNo.getDocument().addDocumentListener(new DocumentListener() {
                    protected void update() {
                        loadTimer.restart();
                    }
    
                    @Override
                    public void insertUpdate(DocumentEvent e) {
                        update();
                    }
    
                    @Override
                    public void removeUpdate(DocumentEvent e) {
                        update();
                    }
    
                    @Override
                    public void changedUpdate(DocumentEvent e) {
                        update();
                    }
                });
    
                loadTimer = new Timer(250, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        loadParts();
                    }
                });
                loadTimer.setRepeats(false);
                loadTimer.setCoalesce(true);
    
            }
    
            protected void loadParts() {
    
                String text = txtNo.getText();
                // Don't want to trigger this twice...
                if (text == null ? partToLoad != null : !text.equals(partToLoad)) {
                    partToLoad = text;
                    txtNo.setEnabled(false);
                    txtName.setEnabled(false);
                    BackgroundWorker worker = new BackgroundWorker();
                    worker.execute();
                }
    
            }
    
            protected class BackgroundWorker extends SwingWorker<String, String> {
    
                @Override
                protected String doInBackground() throws Exception {
    
                    // Do you're database load here.  Rather then updating the text
                    // field, assign it to variable and return it from here
    
                    String desc = "Some description"; // load me :D
    
                    // Inserted delay for simulation...
                    Thread.sleep(2000);
    
                    return desc;
    
                }
    
                @Override
                protected void done() {
                    try {
                        String value = get();
                        txtName.setText(value);
    
                        txtName.setEnabled(true);
                        txtNo.setEnabled(true);
                    } catch (InterruptedException exp) {
                        exp.printStackTrace(); // Log these some where useful
                    } catch (ExecutionException exp) {
                        exp.printStackTrace(); // Log these some where useful
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      你知道你的数据库连接是否正常吗?例如,您可以在侦听器之外运行数据库部分并且它可以工作吗?

      如果是这样,我建议改用ActionListenerFocusListener。 KeyListeners(虽然有时是必要的)通常很笨拙 - 通常有更好的方法(参见 Java Swing: Using ActionMap 和解释):

      import java.awt.event.*;
      import javax.swing.*;
      
      public class Example extends Box{
      
          JLabel txtName = new JLabel("Nothing Entered");
      
          public temp(){
              super(BoxLayout.Y_AXIS);
              // Add FocusListener to first field
              final JTextField txtNo = new JTextField(20);
              txtNo.addFocusListener(new CustomFocusListener(txtNo));
              add(txtNo);
      
              // Add TextListener to first field
              final JTextField txtNo2 = new JTextField(20);
              txtNo2.addFocusListener(new CustomFocusListener(txtNo2));
              add(txtNo2);
      
              // Add TextListener to first field
              final JTextField txtNo3 = new JTextField(20);
              txtNo3.addFocusListener(new CustomFocusListener(txtNo3));
              add(txtNo3);
      
              add(new JButton("Do Something"));
      
              add(txtName);
      
          }
      
      
          public static void main(String[] args){
              final JFrame frame = new JFrame();
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(new Example());
              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
          }
      
          /**
           * Your custom focust listener that does all your SQL Work
           */
          public class CustomFocusListener extends FocusAdapter{
              JTextField field;
      
              public CustomFocusListener(JTextField field){
                  this.field = field;
              }
      
              @Override
              public void focusLost(FocusEvent e) {
                  //Assuming your database connection works, this gives you an example to follow
                  txtName.setText(field.getText());
                  /*Connection conn = null;
                  try{
                      Class.forName("oracle.jdbc.driver.OracleDriver");
      
                      conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "Username", "Password");
                      Statement st = conn.createStatement();
                      String load = "Select * from Store_info_table where PART_NUMBER = '" + field.getText() + "'";
                      ResultSet rs = st.executeQuery(load);
                      while(rs.next()){
                         txtName.setText(rs.getString("SPARE_DESC"));
                      }
                  }catch(Exception ae){
      
                  }*/
              }
          }
      }
      

      【讨论】:

      • 如果您按 Enter 键,这肯定有效,但我在 Enter 上有默认按钮,我仍然必须在某些 JtextFields 中输入一两个字段...。我怎样才能在 Tab 而不是比输入?
      • 啊——我明白了。那么你真的在寻找FocusListener - 当字段失去焦点时将执行的东西。我将为此更新我的示例。
      • @NickRippe 不,您正在寻找DocumentListener
      • @Robin 我想这取决于您何时想要更新您的字段。但我认为你不能使用DocumentListener 轻松捕捉TAB 字符(因为它被KeyboardFocusManager 消耗)。
      • DocumentListenerFocusListener 都可以。 FocusListener 的问题是焦点必须有一些去处。如果表单上的所有可聚焦组件都被禁用(主要组件除外),焦点将永远不会丢失(我目前在程序中遇到这个问题)。使用DocumentListener,您将希望在文档更改之间有某种延迟,这样您就不会立即尝试加载数据,因为它会被更改......因为那只会令人沮丧。我同意,但是,摆脱KeyListener
      【解决方案4】:

      谢谢大家的帮助。我得到了我想要的使用 Nick 建议的 FocusListener:

       txtNo.addFocusListener(new FocusAdapter() {
              public void focusLost(FocusEvent e) {
                  Connection conn = null;
                  try{
                      Class.forName("oracle.jdbc.driver.OracleDriver");
      
              conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "Username", "Password");
              Statement st = conn.createStatement();
              String load = "Select * from Store_info_table where PART_NUMBER = '" + txtNo.getText().trim() + "'";
              ResultSet rs = st.executeQuery(load);
              while(rs.next()){
                  txtName.setText(rs.getString("SPARE_DESC"));
      
              }
                  }catch(Exception ae){
      
                  }
              }
          });
      

      【讨论】:

      • 这里有很多事情让我担心。您仍在 EDT 中调用数据库,这将阻止您的 UI 并可能使您的程序看起来好像挂起。以这种方式建立连接既浪费又耗时。你没有关闭连接或结果集,消耗数据库资源。您没有处理异常,如果您至少从不报告错误并且您希望为任何给定的零件号返回超过一行,您将如何跟踪错误?导致你唯一的每一个显示最后的结果
      猜你喜欢
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多