4

I am creating an UI class in which everything will run (a different class will work as the runner). In this class I have a table and the table is supposed to create TableModeEvents when changed, but it doesn't seem to do so.

The console is supposed to print out "test" whenever I do anything to the table, but it is not. I've made other SSCCE and they work fine as long as I keep everything in one program (in the main method and with only subclasses and anonymous classes) but I can't seem to get it to work across classes.

Any idea what I'm doing wrong?

package SSCCE;

import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

public class SSCCE {

static Object[][] data = { {"Abyss", Boolean.FALSE},{"Scepter", Boolean.FALSE},{"FoN", Boolean.FALSE} };
public static void main(String[] args){

    //table model------------------------------------------
    TableModel model = new AbstractTableModel(){
        Object[][] rowData = { {"Abyss", Boolean.FALSE},{"Scepter", Boolean.FALSE},{"FoN", Boolean.FALSE} };
        String[] columnNames = {"Name","Boolean"};

        public int getColumnCount() {return columnNames.length;}

          public String getColumnName(int column) {return columnNames[column];}

          public int getRowCount() {return rowData.length;}

          public Object getValueAt(int row, int column) {return rowData[row][column];}

          public Class getColumnClass(int column) {return (getValueAt(0, column).getClass());}

          public void setValueAt(Object value, int row, int column) {rowData[row][column] = value;}

          public boolean isCellEditable(int row, int column) {return (true);}
    };


    JTable table = new JTable(model);
    //tableChanged------------------------------------------
    model.addTableModelListener(new TableModelListener(){
        public void tableChanged(TableModelEvent e) {
            System.out.println("test");
        }

    });

    //frame stuff, ignore-----------------------------------
    JFrame frame = new JFrame();
    frame.setLayout(new BorderLayout());
    frame.add(table,BorderLayout.CENTER);
    frame.setSize(500,400);
    frame.setLocation(400,200);
    frame.setDefaultCloseOperation(3);
    frame.setVisible(true);

}

}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nacht
  • 10,488
  • 8
  • 31
  • 39
  • 1
    I don't think that there's any way to tell what you're doing wrong based on the code and text you've posted so far. Consider creating and posting an [SSCCE](http://SSCCE.org) that shows your problem and sure that uses more than one class (but put them in one file) and you'll likely have better results here. – Hovercraft Full Of Eels Oct 04 '11 at 00:33
  • @Hovercraft Full Of Eels +1 for pointing out that one source file can contain more than one class. To quote from the ['Correct' section](http://pscode.org/sscce.html#co) of the SSCCE document. *"If the language specifies only a single public class per source code file, demote all the other classes to default. This allows the example to be compiled without being split into separate files."* – Andrew Thompson Oct 04 '11 at 01:23

1 Answers1

14

When you change the value of any of the table cells, the setValueAt method is being called, but there's no event being fired.

Try adding the fireTableCellUpdated(row, column) method call to your setValueAt method, like so:

public void setValueAt(Object value, int row, int column) {
    rowData[row][column] = value;
    fireTableCellUpdated(row, column);
}

Note that you could also fireTableDataChanged(), but that will fire the most general event, and it's advised that you fire the most specific as it avoids unnecessary work and is capable of maintaining the selection state.

Nate W.
  • 9,141
  • 6
  • 43
  • 65
  • This hold listener thing is confusing to me. I thought everything was done internally, seems not. And now to learn DnD. – Nacht Oct 04 '11 at 06:04
  • 3
    correct advice, but wrong event: fireTableCellUpdated instead. General rule is to always fire the most limited event type to keep the reaction as small as possible (dataChanged clears selection, f.i.) – kleopatra Oct 04 '11 at 07:59
  • @Nacht everything (nearly) that _could_ be done independently of the concrete implementation is indeed done :-) – kleopatra Oct 04 '11 at 08:01
  • -1 for sticking to dataChanged - even as a side-note, it's not a viable option – kleopatra Oct 04 '11 at 22:20
  • @kleopatra: Really? Wow. I disagree - it's worth mentioning so the OP doesn't see it and say "I'll just use this instead, it's easier" without knowing the differences between the two methods. – Nate W. Oct 04 '11 at 22:33
  • disagreeing with facts is not option as well ;-) – kleopatra Oct 05 '11 at 06:52
  • I actually figured it out that it was fireTableCellUpdate. Turns out, datachanged made some unwanted effects. But after I understood fire events, I just looked it up. Still, thanks for everything! – Nacht Oct 28 '11 at 01:32
  • This answer needs to be linked to so many JTable questions where this method is never mentioned in any answers, 6 years later, thank you. – Chris Phillips Sep 27 '17 at 18:42