Обновление модели JTable не отображается во время фильтрации TableRowSorter
У меня есть JDialog для редактирования цвета, где пользователь может добавлять / удалять / редактировать цвет. Цвета отображаются в Jtable, который заполняется из БД. Пользовательский интерфейс содержит txtField, который позволяет выполнять фильтрацию благодаря TableRowSorter. Jtable использует defaultTableModel, и после того, как пользователь решит удалить строку, например, я делаю model.removeRow(tableau.getSelectedRow()), чтобы обновить модель.
Моя проблема заключается в следующем: когда пользователь не использует сортировщик и нажимает на удаление, все идет хорошо, и JTable немедленно обновляется для представления этого действия, то есть соответствующая строка удаляется из JTable, но когда он делает то же самое вещь с введенным фильтром (TableRowSorter выполняет свою фильтрацию), визуальная обратная связь в Jtable не происходит, то есть удаленная строка все еще видна.
1) Нет фильтрации: я выбираю строку с FooColor7
2) Затем я нажимаю кнопку удаления: строка с FooColor7 удаляется, и JTable показывает это.
Теперь "глючит" поведение:
3) Фильтрация по: я выбираю строку с FooColor3
4) Затем я нажимаю кнопку удаления: нет изменений в пользовательском интерфейсе, даже если строка правильно удалена из БД...
И вот что-то вроде SSCCE (вроде как потому, что не работает без зависимостей, которые здесь слишком долго помещать):
public class DialogEditColors extends JDialog implements ActionListener, KeyListener
{
final TableRowSorter<TableModel> sorter;
private JTable table = null;
private DefaultTableModel model = null;
private JPanel panelBoutons = null;
private JTextField txtFieldSearch;
private JLabel lblTitle;
private JButton btnAdd , btnDelete, btnEdit;
private JButton btnCancel, btnSave;
private JScrollPane scroller;
private ColorDao colorDao= new ColorDao(Share.connection);
public DialogEditColors()
{
super();
setSize(439, 313);
setTitle(" Edition couleurs");
getContentPane().setLayout(null);
setModal(true);
setResizable(false);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
btnSave = new JButton("Enregistrer");
btnSave.setBounds(317, 247, 89, 26);
btnSave.addActionListener(this);
btnCancel = new JButton("Annuler");
btnCancel.setBounds(214, 247, 89, 26);
btnCancel.addActionListener(this);
btnAdd = new JButton("");
btnAdd.setBounds(new Rectangle(10, 8, 33, 26));
btnAdd.addActionListener(this);
btnDelete = new JButton("");
btnDelete.setBounds(new Rectangle(53, 8, 33, 26));
btnDelete.addActionListener(this);
btnEdit = new JButton("");
btnEdit.setBounds(new Rectangle(96, 8, 33, 26));
btnEdit.addActionListener(this);
panelBoutons = new JPanel();
panelBoutons.setBorder(new LineBorder(Color.GRAY));
panelBoutons.setBounds(27, 11, 378, 43);
panelBoutons.setLayout(null);
txtFieldSearch = new JTextField("", 10);
txtFieldSearch.setBounds(193, 9, 175, 24);
panelBoutons.add(txtFieldSearch);
txtFieldSearch.addKeyListener(this);
Object[][] data = new Object[colorDao.findAll().size()][2];
String[] title = { "Couleur", "Description" };
int i = 0;
for (Couleur coul : colorDao.findAll())
{
data[i][0] = coul.getNom();
data[i][1] = coul.getDescription();
i++;
}
model = new DefaultTableModel(data, title);
table = new JTable(model)
{//THIS ALLOWS TO ALTERNATE THE BACKGROUND COLOR OF ROWS
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Component returnComp = super.prepareRenderer(renderer, row, column);
Color alternateColor = new Color(242, 242, 242);
Color whiteColor = Color.WHITE;
if ( !returnComp.getBackground().equals(getSelectionBackground()) )
{
Color bg = (row % 2 == 0 ? alternateColor : whiteColor);
returnComp.setBackground(bg);
bg = null;
}
return returnComp;
};
};
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true);
sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
scroller = new JScrollPane(table);
scroller.setBounds(27, 65, 378, 171);
addComponents();
setVisible(true);
}//END OF CONSTRUCTOR
private void addComponents()
{
getContentPane().add(scroller);
getContentPane().add(btnSave);
getContentPane().add(btnCancel);
panelBoutons.add(btnAdd);
panelBoutons.add(btnDelete);
panelBoutons.add(btnEdit);
getContentPane().add(panelBoutons);
}////END OF METHOD
public void actionPerformed(ActionEvent e)
{
if ( e.getSource() == btnDelete )
{
if ( table.getSelectedRowCount() != 0 )
{//THERE IS A CHOSEN ROW IN JTABLE
String selectedColor = (table.getValueAt(table.getSelectedRow(), table.getSelectedColumn())).toString();
//TEST THE READONLY ATTRIBUTE OF THE COLOR
if ( colorDao.findByNom(selectedColor).get(0).getReadOnly() == true )
{//THE COLOR'S READONLY ATTRIBUTE IS TRUE
JOptionPane.showMessageDialog(this, "This item is readOnly: impossible to delete it!");
}
else
{//THE COLOR'S READONLY ATTRIBUTE IS FALSE
int response = JOptionPane.showConfirmDialog(this, "Are you sure you
want to delete this color?", "Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if ( response == 0 ) //CONFIRMED
{//FIRST DELETE THE COLOR FROM DB
colorDao.delete(colorDao.findByNom(selectedColor).get(0));
//THEN REFRESH JTABLE TO TAKE DELETION INTO ACCOUNT
model.removeRow(table.getSelectedRow());
table.repaint();
}
}
}
else
{//NO CHOSEN COLOR
JOptionPane.showMessageDialog(this, "No chosen color!");
}
}
else if ( e.getSource() == btnCancel )
{
this.dispose();
}
}//END OF METHOD
public void keyReleased(KeyEvent e)
{
if ( e.getSource() == txtFieldSearch )
{
String text = txtFieldSearch.getText();
if ( text.length() == 0 )
{
sorter.setRowFilter(null);
}
else
{
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
}
((AbstractTableModel) table.getModel()).fireTableDataChanged();
}
}//END OF METHOD
}////END OF CLASS
Любая идея?
1 ответ
model.removeRow(table.getSelectedRow()); table.repaint();
нет необходимости перекрашивать. TableModel уведомит таблицу, когда данные будут изменены, и таблица перекрасится сама
Поскольку вы сортируете свои данные, возможно, вы удаляете неправильную строку из TableModel. Сначала вам нужно преобразовать индекс вида в модельный индекс:
Например:
int modelIndex = table.convertRowIndexToModel( table.getSelectedIndex() );
model.removeRow( modelIndex );