【问题标题】:Get selected JComboBox value and add to SQL query for second JComboBox获取选定的 JComboBox 值并添加到第二个 JComboBox 的 SQL 查询
【发布时间】:2017-01-26 22:26:45
【问题描述】:

我正在设计一个简单的数据库应用程序,它在 GUI 中具有 2 个 jComboBoxes。第一个 jComboBox 填充了 SQL 查询的结果。我希望第二个 jComboBox 填充第二个查询的结果,该查询将用户选择的值合并到第一个框中,但我不能让它工作。

我创建了 2 个类,一个用于绘制 GUI 并包含 main 方法,另一个用于查询我的 Oracle 数据库。

我的 GUI 类:

public class TestUI extends javax.swing.JFrame {
     // Create new form TestUI
    public TestUI() {
        initComponents();
    }

    @SuppressWarnings("unchecked")

    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jComboBox1 = new javax.swing.JComboBox<>();
        jTextField1 = new javax.swing.JTextField();
        jComboBox2 = new javax.swing.JComboBox<>();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        // Combo box 1 population

        jComboBox1.removeAllItems();
        createConnection c1 = new createConnection();
        c1.getEmployee().forEach((employee) -> {
            jComboBox1.addItem(employee);
        });
        jComboBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBox1ActionPerformed(evt);
            }
        });

        // ComboBox 2 population

        jComboBox2.removeAllItems();


    }                     

    private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {                                           
        // TODO add handling code here:
    }                                    

    public static void main(String args[]) {
        DRAW GUI
    }
}

还有我的数据库类:

import java.util.List;
import java.util.ArrayList;
import java.sql.*;

public class createConnection {

    String empName;

    public Connection createConnection() {
        try {
            Class.forName(driver);
            java.sql.Connection conn = DriverManager.getConnection(DB_URL, DB_username, DB_password);
            return conn;
        } catch (ClassNotFoundException | SQLException e) {
            return null;
        }
    }

    // ComboBox 1
    public List<String> getEmployee() {
        List<String> list = new ArrayList();
        Connection conn = createConnection();
        try {
            Statement stmt = conn.createStatement();
            String query = "SELECT * FROM hr.employees ORDER BY last_name";
            ResultSet results = stmt.executeQuery(query);
            while (results.next()) {
                list.add(results.getString("last_name"));
            }
        } catch (Exception e) {
            System.out.println("Exception = " + e);
        }
        return list;
    }

    // Combo Box 2
    public List<String> getEmpLocation() {
        List<String> list = new ArrayList();
        Connection conn = createConnection();
        try {
            Statement stmt = conn.createStatement();
            String query = "SELECT country_id FROM hr.location WHERE hr.location.emp_name = " + empName;
            ResultSet results = stmt.executeQuery(query);
            while (results.next()) {
                list.add(results.getString("last_name"));
            }
        } catch (Exception e) {
            System.out.println("Exception = " + e);
        }
        return list;
    }    
}

我省略了数据库连接变量和 GUI 坐标等不相关的代码。

我想知道如何正确获取数据库类中的 getEmpLocation() 方法来填充第二个 ComboBox。这将涉及向两个类添加代码并传递变量值,但我无法弄清楚!任何帮助将不胜感激。

【问题讨论】:

标签: java sql oracle swing class


【解决方案1】:

我假设您想从您的第一个 JComboBox 中选择一个值,然后单击一个按钮来处理您选择的数据并将新数据加载到您的第二个 JComboBox。

在这种情况下,您需要 JButton 的 ActionListener 而不是 JComboBox:

jButton1.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        selectedName = (String) jComboBox1.getSelectedItem();                
    }
});

您还需要将您选择的值存储在一个变量中。 getSelectedItem() 方法返回一个对象,因此在您的情况下需要将其转换为字符串。

由于我们向按钮添加了 ActionListener,因此您不需要这个:

jComboBox1.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        jComboBox1ActionPerformed(evt);
    }
});


在您的 createConnection 类 中(按照命名约定,类名应以大写字母开头):

如果你没有使用 try-with-resources 语句,你应该在 catch 块之后关闭你的连接。

    } finally {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

        }
    }

您需要将您的 selectedName 变量传递给getEmpLocation() 方法:

public List<String> getEmpLocation(String name) {

你应该使用 PreparedStatement 而不是 Statement:

String query = "SELECT first_name FROM employees WHERE last_name = ?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString(1, name);            
ResultSet results = ps.executeQuery();

说实话,我不知道您希望通过选择查询实现什么目标。首先,这个选择查询不起作用。表名是 LOCATIONS 而不是位置,并且它没有名为 emp_name 的列。

"SELECT country_id FROM hr.location WHERE hr.location.emp_name = ?"

如果您想获取位置,您应该使用如下查询:

"SELECT dep.department_name, loc.city, cou.country_name
 FROM employees emp, departments dep, locations loc, countries cou
 WHERE emp.last_name = ?
 AND emp.department_id = dep.department_id 
 AND dep.location_id = loc.location_id
 AND loc.country_id = cou.country_id"

您可以选择要使用部门、城市或国家/地区名称的位置。但我的主要问题是,如果您首先选择姓氏并将它们放在 JComboBox 中,那么您很可能只会得到一行数据,因此使用第二个 JComboBox 没有意义。让我们从另一个方面来解决这个问题。如果您先选择位置,然后再选择您的员工怎么办。这可以解决这个问题。


快速示例: 您从数据库中选择所有名字,然后您可以选择正确的姓氏。

从数据库中选择所有名字:

    public List<String> getEmpFirstName() {
        List<String> list = new ArrayList();
        Connection conn = createConnection();

        try {
            Statement stmt = conn.createStatement();
            String query = "SELECT DISTINCT first_name "
                            + "FROM hr.employees "
                            + "ORDER BY first_name";
            ResultSet results = stmt.executeQuery(query);

            while (results.next()) {
                list.add(results.getString("first_name"));
            }
        } catch (Exception e) {
            System.out.println("Exception = " + e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }                    
            }
        }
        return list;
    }

使用 PreparedStatement 根据名字选择姓氏:

    public List<String> getEmpLastName(String name) {
        List<String> list = new ArrayList();
        Connection conn = createConnection();

        try {
            String query = "SELECT last_name "
                            + "FROM employees "
                            + "WHERE first_name = ?";
            PreparedStatement ps = conn.prepareStatement(query);
            ps.setString(1, name);            
            ResultSet results = ps.executeQuery();

            while (results.next()) {
                list.add(results.getString("last_name"));
            }
        } catch (Exception e) {
            System.out.println("Exception = " + e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }                    
            }
        }
        return list;
    }

更新您的 ActionListener:

    jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Store selected value
                selectedName = (String) jComboBox1.getSelectedItem();

                // Create Connection and pass selected value to getEmpLastName
                createConnection c1 = new createConnection();
                names = c1.getEmpLastName(selectedName);

                // Clear your second comboBox and fill with data
                jComboBox2.removeAllItems();                
                for (String lastName : names) {
                    jComboBox2.addItem(lastName);
                }              
            }
        });    

尝试选择常见的名字,如 Alexander、David、James、John、Julia 等。

【讨论】:

  • 嗨,哇,谢谢你对这么多的惊人的深入解释!首先 - 我不希望按钮触发第二个 ComboBox。我希望在第一个 ComboBox 中选择一个值来触发第二个 ComboBox。因此,用户在 box1 中选择一个值,然后 box2 将填充相关值。
  • 关于 SQL - 是的,你说的很对,我想要运行的真正查询实际上与此完全不同。一些数据是私有的,所以我只是使用 HR 模式作为一个简单的例子。然而,我匆忙地举了这个例子,你对演示数据的使用更有意义:) 所以我需要在我认为的 ComboBoxes 中添加一个动作侦听器。这是否以与您用于按钮的方法类似的方式完成?
  • 没错。将 ActionListener 添加到您的 JComboBox 而不是 JButton。
  • jComboBox2.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionListener e) { String selectedName = (String) jComboBox1.getSelectedItem() ; } });我试过这个,但我得到一个错误:不是抽象的,也没有覆盖 ActionListener 中的抽象方法 actionPerformed(ActionEvent) 这个匿名内部类的创建可以变成一个 lambda 表达式。我在这里做错了吗?
猜你喜欢
  • 2019-11-28
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多