0

My java swing program have this error:

 errorcom.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"

I think maybe it was because I am using DocumentListener. But I can't figure out how to fix it. I am stuck with this error for few days now :(

So this program uses a virtual keyboard to search MySQL database for names in the editable JComboBox.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import virtualkeyboard.gui.DialogVirtualKeyboardReal;

public class test3 extends javax.swing.JFrame {
    public test3() {
        initComponents();
        JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
        textfield.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                Runnable doAssist = new Runnable() {
                    @Override
                    public void run() {
                        comboFilter(textfield.getText());
                    }
                };
                SwingUtilities.invokeLater(doAssist);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                Runnable doAssist = new Runnable() {
                    @Override
                    public void run() {
                        comboFilter(textfield.getText());
                    }
                };
                SwingUtilities.invokeLater(doAssist);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                // plain text components dont fire this
            }
        });
    }

    public void comboFilter(String enteredText) {
        java.util.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) {
            comboBox.setEditable(false); // ADDED THIS LINE
            comboBox.setModel(new DefaultComboBoxModel(filterArray.toArray()));
            comboBox.setSelectedItem(enteredText);
            comboBox.showPopup();
            comboBox.setEditable(true); // ADDED THIS LINE
        }
        else {
            comboBox.hidePopup();
        }
    }
}

public void jButton1ActionPerfomed(java.awt.event.ActionEvent evt) {
    test3 r =this;
    JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
    DialogVirtualKeyboardReal dlg = new DialogVirtualKeyboardReal(r, true, textfield);
}

I already tried putting this after the try-catch for it to close the connection:

finally {
    if (con != null) {
        try {
            // finally lets close the connection (event in the event of a exception)
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(test3.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

But the program hangs or freezes. What should I do? Please help me out. Thank you.

Abra
  • 19,142
  • 7
  • 29
  • 41
  • When I use keyPressed.KeyEvent Listener, it works properly. filterArray will only be populated once a key is pressed. But when I use document Listener, it continously populates filterArray even if only one key is pressed. Resulting hang on my program. – Rica Jacutina Jan 03 '21 at 08:48
  • Please also look into marking [your previous question](https://stackoverflow.com/q/65407319/1133011) as solved if they were before starting a new one. Also put breakpoints on the lines you are concerned about and see how many times are they called. And from where it's being called the documentlistener should only fire an insert or update accordingly – David Kroukamp Jan 03 '21 at 13:04

1 Answers1

0

The code in your question is not a minimal, reproducible example. Nonetheless I believe that I understand your problem. You are entering a sort of infinite loop. In method comboFilter you set the selected item of the comboBox in the following line of your code:

comboBox.setSelectedItem(enteredText);

Because the comboBox is editable, the above line of code is handled in the same way as if the user typed into the comboBox editor. In other words, setting the selection again triggers the DocumentListener which, in turn, sets the comboBox selection which, in turn, triggers the DocumentListener and so on and so on.

In order to prevent this "inifinite loop", I suggest simply making the comboBox not editable just before the above line of your code and then re-setting the comboBox to be editable immediately after you set the selected item.

Here is the code (copied from your question) with my suggested changes. Note that I added two lines and marked them with the following comment:

// ADDED THIS LINE

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import virtualkeyboard.gui.DialogVirtualKeyboardReal;

public class test3 extends javax.swing.JFrame {
    public test3() {
        initComponents();
        JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
        textfield.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                Runnable doAssist = new Runnable() {
                    @Override
                    public void run() {
                        comboFilter(textfield.getText());
                    }
                };
                SwingUtilities.invokeLater(doAssist);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                Runnable doAssist = new Runnable() {
                    @Override
                    public void run() {
                        comboFilter(textfield.getText());
                    }
                };
                SwingUtilities.invokeLater(doAssist);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                // plain text components dont fire this
            }
        });
    }

    public void comboFilter(String enteredText) {
        java.util.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) {
            comboBox.setEditable(false); // ADDED THIS LINE
            comboBox.setModel(new DefaultComboBoxModel(filterArray.toArray()));
            comboBox.setSelectedItem(enteredText);
            comboBox.showPopup();
            comboBox.setEditable(true); // ADDED THIS LINE
        }
        else {
            comboBox.hidePopup();
        }
    }
}

public void jButton1ActionPerfomed(java.awt.event.ActionEvent evt) {
    test3 r =this;
    JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
    DialogVirtualKeyboardReal dlg = new DialogVirtualKeyboardReal(r, true, textfield);
}
Abra
  • 19,142
  • 7
  • 29
  • 41