2
I’m wearing a TableModel
(not the DefaultTableModel
) which I populate with data from banco
(MySQL
), I also use a Class to filter through what I type into a JTextField
.
It is working correctly, but I would like to, after performing the filtering through the data entered in JTextField
be able to select only the data that "remained" in the JTable
. Because until now I select the first line after the filter,and I have as return the first line of the original model ( through the event mouseClicked
). The image below illustrates perhaps more clearly:
I believe you must somehow "create a new modelo
with the resulting data after the filter". Can anyone help adapt this same class, or with information so that I can achieve my goal?
Thank you very much!
Class to make the filter:
package Converter;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.table.TableRowSorter;
import org.jdesktop.beansbinding.Converter;
public class RowSorterToStringConverter extends Converter {
private JTable table;
public JTable getTable() {
return table;
}
public void setTable(JTable table) {
this.table = table;
}
@Override
public Object convertForward(Object value) {
return value.toString();
}
@Override
public Object convertReverse(Object mask) {
TableRowSorter sorter = new TableRowSorter(table.getModel());
String m = mask.toString();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < m.length(); i++) {
char c = m.charAt(i);
sb.append('[').append(Character.toLowerCase(c)).append(Character.toUpperCase(c)).append(']');
}
sorter.setRowFilter(RowFilter.regexFilter(".*" + sb + ".*"));
return sorter;
}
}
Linking of JTextField
with the Classe
RowSorter
Mouse event:
private void jtableCLicked() {
saveButton.setEnabled(false);
Condutor condutor = modelo.getCondutor(jTableCondutor.getSelectedRow());
condutorIdField.setText((String.valueOf(condutor.getId())));
condutorNomeField.setText(condutor.getNome());
jCSetorDescr.setSelectedItem(condutor.getSetor());
jCPessoaDescr.setSelectedItem(condutor.getPessoa());
jCEmpresaDescr.setSelectedItem(condutor.getEmpresa());
jCStatusDescr.setSelectedItem(condutor.getStatus());
botoesEdicao();
}
Update:
I’ve made the following changes:
private void jTextFieldBuscaKeyReleased(java.awt.event.KeyEvent evt) {
String stringBusca = jTextFieldBusca.getText();
filter(stringBusca);
}
private void filter(String stringBusca) {
TableRowSorter<TableModel> tr = new TableRowSorter<TableModel>(modelo);
jTableCondutor.setRowSorter(tr);
tr.setRowFilter(RowFilter.regexFilter(stringBusca));
}
private void jtableCLicked() {
if (jTableCondutor.getRowSorter() != null) {
try {
int rowSel = jTableCondutor.getSelectedRow();
int indexRowModel = jTableCondutor.getRowSorter().convertRowIndexToModel(rowSel);
Condutor condutor = modelo.getCondutor(indexRowModel);
condutorIdField.setText((String.valueOf(condutor.getId())));
condutorNomeField.setText(condutor.getNome());
jCSetorDescr.setSelectedItem(condutor.getSetor());
jCPessoaDescr.setSelectedItem(condutor.getPessoa());
jCEmpresaDescr.setSelectedItem(condutor.getEmpresa());
jCStatusDescr.setSelectedItem(condutor.getStatus());
botoesEdicao();
} catch (Exception e) {
System.out.println("Erro " + e.getMessage());
}
}
else{
try{
Condutor condutor = modelo.getCondutor(jTableCondutor.getSelectedRow());
condutorIdField.setText((String.valueOf(condutor.getId())));
condutorNomeField.setText(condutor.getNome());
jCSetorDescr.setSelectedItem(condutor.getSetor());
jCPessoaDescr.setSelectedItem(condutor.getPessoa());
jCEmpresaDescr.setSelectedItem(condutor.getEmpresa());
jCStatusDescr.setSelectedItem(condutor.getStatus());
botoesEdicao();
} catch (Exception e) {
System.out.println("Erro " + e.getMessage());
}
}
}
Now it’s all the way I needed it, except that after performing a filter, in this case only "a few lines in the JTable
,"if I edit a row (a objeto
Conductor) occurs to Exception:
java.lang.IndexOutOfBoundsException:invalid range
After editing call these two methods:
public void limpaLista() {
if (condutores.size() > 0) {
int i = condutores.size();
condutores.clear();
fireTableRowsDeleted(0, i - 1);
}
}
public void preencherTabela() {
CondutorDao condutorDao = new CondutorDao();
modelo.adicionaLista(condutorDao.consultarCondutores());
}
Update 2:
I created these code snippets:
private void jTBuscarRegistroKeyReleased(java.awt.event.KeyEvent evt) {
tr.setRowFilter(RowFilter.regexFilter("(?i)" + jTBuscarRegistro.getText()));
}
class MyListSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if (!lsm.isSelectionEmpty()) {
try {
int rowSel = jTableCondutor.getSelectedRow();
int indexRowModel = jTableCondutor.getRowSorter().convertRowIndexToModel(rowSel);
Condutor condutor = modelo.getCondutor(indexRowModel);
condutorIdField.setText((String.valueOf(condutor.getId())));
condutorNomeField.setText(condutor.getNome());
jCSetorDescr.setSelectedItem(condutor.getSetor());
jCPessoaDescr.setSelectedItem(condutor.getPessoa());
jCEmpresaDescr.setSelectedItem(condutor.getEmpresa());
jCStatusDescr.setSelectedItem(condutor.getStatus());
botoesEdicao();
} catch (Exception ee) {
System.out.println("Erro Ao Carregar Dados " + ee.getMessage());
}
}
}
;
}
And at the builder:
jTableCondutor.setRowSorter(tr);
jTableCondutor.getSelectionModel().addListSelectionListener(new MyListSelectionListener());
Now it worked properly, without Exception
, can select after the filter, and when cleaning the JTextField
of the search, returns the original model with the changes made in the lines.
In this answer I’ll explain something similar, see if you can understand and adapt. If you can’t, add a [mcve] so you can try to create something testable for the posted code.
– user28595
Just to see if I understood you, in this post you indicated deals with the case of selecting the line after doing the filter, because in my code is doing the search correctly, I just can’t select the data after the filter, always selects data according to the model loaded the first time. Thank you.
– Rodrigo