0

嗨,伙计们,我有一个连接到 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){

            }
        }
    });
4

4 回答 4

2
  • 替换KeyListenerDocumentListener
  • EDT 上的数据库连接是个坏主意(太慢)。有关更多信息,请参阅Swing指南中的并发性
  • 您容易受到 SQL 注入的攻击
  • 避免空catch语句,否则您不知道出了什么问题。如果您不选择体面的错误处理,至少记录堆栈跟踪(通过打印它,或使用Logger)。
于 2012-10-05T19:10:45.503 回答
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
                }
            }
        }
    }
}
于 2012-10-05T22:14:46.053 回答
1

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

如果是这样,我建议使用ActionListeneror aFocusListener代替。KeyListeners(虽然有时是必要的)通常很笨拙——通常有更好的方法(参见Java Swing: Using ActionMap for and explaination):

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){

            }*/
        }
    }
}
于 2012-10-05T18:15:14.813 回答
0

谢谢你们的帮助。按照尼克的建议,我得到了我想要的使用 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){

            }
        }
    });
于 2012-10-05T19:34:12.257 回答