0

Hi I want my JTable to implement TableModelListener, so it can react if the data of the TableModel changed. However as soon as I implement the TableModelListener in my JTable subclass, the Table is not displayed in the frame anymore.

If I create a subclass of JTable everything works well and the Table is shown in the frame:

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;


public class JTableDisappears extends JFrame {
    private DefaultTableModel watchlistTableModel;
    private WatchlisttTable watchlistTable;

    public JTableDisappears() {
        super();
        setSize(200,200);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        createTable();
        setVisible(true);
    }

    private void createTable() {
        String[] zeilenNamen = { "Name", "Symbol", "Price", "%" };
        String[][] data = { { "1", "AAPL", "3", "4" }, { "A", "2", "C", "D" }, { "2", "B", "3", "4" } };
        watchlistTableModel = new DefaultTableModel(data, zeilenNamen);
        watchlistTableModel.setColumnIdentifiers(zeilenNamen);
        watchlistTable = new WatchlisttTable(watchlistTableModel);
        add(new JScrollPane(watchlistTable));
        
    }

    public static void main(String[] args) {
        new JTableDisappears();

    }

}

class WatchlisttTable extends JTable {

    public WatchlisttTable(TableModel tableModel) {
        super(tableModel);
    }

}

But if I let my JTable subclass implement a TableModelListener like this:

class WatchlisttTable extends JTable implements TableModelListener{

    public WatchlisttTable(TableModel tableModel) {
        super(tableModel);
        
        
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        
    }

}

the Table is not shown in the frame anymore. Why? And what can I do to solve this issue?

  • The Oracle tutorial, [How to Use Tables](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html) will show you how to use a JTable and a TableModelListener. – Gilbert Le Blanc Jun 26 '21 at 09:38
  • As a general rule, don't extend `JTable` (or `JFrame` for that matter). Extending components and windows makes some sense if doing custom painting (e.g. in a `JPanel`), but few other times. – Andrew Thompson Jun 26 '21 at 10:14
  • *I want my JTable to implement TableModelListener, so it can react if the data of the TableModel changed.* - To listen for a change it the data add the `TableModelListener` to the `TableModel`. See: https://stackoverflow.com/questions/3540661/tablemodellistener-and-multiple-column-validation/3541876#3541876 for a basic example. The example also shows how to create Swing components on the `Event Dispatch Thread (EDT)`. All Swing components should be created and changed on the EDT. – camickr Jun 26 '21 at 14:30

3 Answers3

0

I believe it is because JTable already implements TableModelListener? I might be wrong, as I have never used a Jtable, but I feel like you might be trying to implement the same thing twice.
You should first check the documentation:
(https://docs.oracle.com/javase/8/docs/api/javax/swing/JTable.html)

Here is a possible code sample:

class WatchlisttTable extends JTable{
    public WatchlisttTable(TableModel tableModel) {
        super(tableModel);
    }
    @Override
    public void tableChanged(TableModelEvent e) {
    
    }
}
The Blind Hawk
  • 1,199
  • 8
  • 24
0

This is because JTable already implements TableModelListener (see https://docs.oracle.com/javase/8/docs/api/javax/swing/JTable.html, list of the implemented interfaces) and it's tableChanged() method is essential in the function of the JTable class.

If you need to do additional things upon a tableChanged() event you must call the method from JTable too:

class WatchlisttTable extends JTable {

    public WatchlisttTable(TableModel tableModel) {
        super(tableModel);
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        super.tableChanged(e);
    }
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
0

if you defined your own TableModel extend AbstractTableModel in your class then use specific fire...(...) methods; e.g.:

public void addRow(final Object... row) {
    lines.add(row);
    fireTableRowsInserted(lines.size() - 1, lines.size() - 1);
}

@Override
public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
    lines.get(rowIndex)[columnIndex] = aValue;
    fireTableCellUpdated(rowIndex, columnIndex);
}

This way JTable will automatically see your model changes.