Interaction with JTable, which is quickly updated with new lines.

A brief description of the problem.

Suppose JTable and the user interact with it in some way. Table The model of this table is constantly changing. How to make sure that when a user tries to get some information from a table, referring to some constant column and the row currently selected (by its rowIndex, which he received from JTable), he will not get into the situation when the TableModel is changed, but its rowIndex received from JTable no longer matches a single value in the TableModel.

The following is an initial question that explains the problem in more detail:

Consider the following situation:

  • There is a JTable that shows information about users in the current run of queries on some system

  • When a new query enters the system, a new row is added to the table

  • The user can interact with the table by right-clicking on a row (a single row selection model is used in the table) and selecting an item in the menu (for example: interrupt, postpone, try again, etc.)

  • there is a separate class that implements the ActionListener interface (listens to the table) and processes all user interactions

  • When a user performs an action on a table, this class validates the currently selected row and assigns some values ​​to the user action (basically it takes the index of the selected row and then calls tableModel.getValueAt (indexOfSelectedRow, someValuableDataColumnIndex))

, -, . , , , , , ( , , ). , , inits - .

, . :

  • - invokeAndWait() ( , imo ) ​​

  • , , TableModel. , , , , . ( , )

, .

, , - , .

+5
2

, , , TableModel EDT, , .

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class TestJTableInsert {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                final DefaultTableModel model = new DefaultTableModel(0, 1);
                new Timer(500, new ActionListener() {
                    private final Random random = new Random();
                    private int data = 1;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        model.insertRow(random.nextInt(model.getRowCount() + 1),
                                new Object[] { data++ });
                    }
                }).start();

                final JTable table = new JTable(model);
                JPopupMenu popup = new JPopupMenu();
                popup.add(new AbstractAction("Which row is this?") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(table,
                                "This is row " + table.getValueAt(table.getSelectedRow(), 0));
                    }
                });
                table.setComponentPopupMenu(popup);
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
+4

- , .

, ( , "" :

final DefaultTableModel model = new DefaultTableModel(0, 1);
for (int i = 0; i < 50; i++) {
    model.addRow(new Object[] {i});
};

final JXTable table = new JXTable(model);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setRowSelectionInterval(25, 25);
Action l = new AbstractAction("random insert") {
    Random random = new Random();
    @Override
    public void actionPerformed(ActionEvent e) {
        int row = random.nextInt(model.getRowCount());
        model.insertRow(row, new Object[] {"inserted at: " + row});
        table.scrollRowToVisible(table.getSelectedRow());
    }

};
new Timer(100, l).start();
+3

All Articles