I want to improve my gui-lag-free "live search" of a database with a JTextField.
Imagine you got a large database with entries like 0001, 0002, ... up to a million (just an example; entries could also contain strings). Every time when I press a key I start a Swingworker searching for the current content of a jTextfield (within an added DocumentListener), because I want the search to start immediately after every press of a key.
Lets assume I'd like to search for "123" and enter that into the JTextField...
The first swingworker starts immediately when I enter "1" and searches for all entries which contain a "1" and in it's done()-method sets the model of a jTable:
public static class Xrefreshen_speed_up extends SwingWorker<Void, Void> {
public JXTable JXTabelle;
public String sql_anweisung;
public ResultSet mySQLresultset;
public String get_sql() {
return sql_anweisung;
}
public Xrefreshen_speed_up(JXTable jXT, String str) {
this.JXTabelle = jXT;
this.sql_anweisung = str;
}
@Override
public Void doInBackground() {
try {
Thread.sleep(100);
System.out.println("Following query is now executed: " + sql_anweisung);
Thread.sleep(100);
mySQLresultset = Operationen_MySQL.getInstance().ResultSet_aus_Anweisung(sql_anweisung);
Thread.sleep(100);
} catch (Exception e) {
if (!e.getMessage().contains("sleep")) {
JOptionPane.showMessageDialog(null, "jXTable refresh: Could not refresh table:\n" + e.getMessage());
}
}
return null;
}
@Override
public void done() {
try {
if (!isCancelled()) {
Thread.sleep(100);
if (!isCancelled()) {
TableModel resultSetToTableModel = DbUtils.resultSetToTableModel(this.mySQLresultset);
if (!isCancelled()) {
JXTabelle.setModel(resultSetToTableModel);
JXTabelle.packAll();
}
//Boolean bool = get();
} else {
System.out.println("Another Swingworker interrupted execution.");
}
} else {
System.out.println("Tabellenfüllung von anderer Tabellenfüllung unterbrochen");
}
} catch (Exception e) {
}
}
}
But because I entered "123" there are 2 more Swingworkers: One searching for all entries containing "12" and one searching for "123". Obviously searching for "1" will give more results and therefore that swingworker will take longer than the swingworker searching for "12" or "123"... So the last swingworker ("123") will finish first and will set the TableModel of my JTable... but after that the "12"-Swingworker will overwrite the model...and then the "1"-Swingworker... you get it...
So I tried following in the documentlistener of the jTextfield and put multiple Thread.sleep into the Swingworker (see code above):
if(swingworker != null){
swingworker.cancel(true);
}
swingworker = new swingworker_class(null);
swingworker.execute();
But somehow the "1"- and "12"-Swingworkers still won't stop and both overwrite the TableModel... So I end up with the results of the "1"-swingworker...