0

The following is my code for attempting to add create a JButton which will add a row to the connected JTable.

My variables are shown below, tables and tbm are created but were initialized in another part of the program that is not currently shown. These are all instance variables.

int currentUser = 0;
JTable[] tables = new JTable[5];
DefaultTableModel[] tbm = new DefaultTableModel[5];
JButton[] addRow = new JButton[5]

This is the code to create JButtons with actionlisteners.

for(int i=0;i<tbm.length;i++) {
addRow[i] = new JButton("Add Row");
selectionModel = tables[i].getSelectionModel();
currentUser=i;
addRow[i].addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
Object[] temp = {"",""};
tbm[currentUser].addRow(temp);
selectionModel.setSelectionInterval(tbm[currentUser].getRowCount()-1,tbm[currentUser].getRowCount()-1);
}});
}

I later assemble the JTable and JButton into a JPanel by use of a for loop running from 0-tables.length and put it in a respective JFrame. The issue here is that when I go to press the button, the wrong actionListener is triggered. For instance, pressing "Add Row" in Frame 0 should trigger addRow[0], but instead triggers addRow[4].

user1418454
  • 107
  • 1
  • 9
  • your `ActionListener`s add rows to the `JTable` in `tables` at index [`currentUser`]. So what's `currentUser` set to when you click the button? I can't see that in the code sample you provided. – Dan O Jun 08 '12 at 16:37
  • 1) For better help sooner, post an [SSCCE](http://sscce.org/). 2) Please use a consistent and logical indent for code blocks. – Andrew Thompson Jun 08 '12 at 16:38
  • @ Andrew Thompson, will do! I unfortunately use notepad to program so I got used to the lack of formatting. – user1418454 Jun 08 '12 at 16:54
  • `currentUser` is defined outside of your for() loop. That means it sticks around after your for() loop terminates, and it keeps the last value assigned to it (4, in your case). Then, when the `actionPerformed` method of any `ActionListener` is invoked, it uses whatever is stored in `currentUser` right now, not when the `ActionListener` was created. Hope that all makes sense. – Dan O Jun 08 '12 at 16:54

1 Answers1

1

You're adding a row to the table at tables[currentUser] whenever any button is clicked. It sounds like you want to add a row to table[X] when you click button X. Here's the quick and dirty way to do it:

for(int i=0;i<tbm.length;i++) {
    final int tblIdx = i;
    addRow[i] = new JButton("Add Row");
    selectionModel = tables[i].getSelectionModel();
    currentUser=i;
    addRow[i].addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Object[] temp = {"",""};
            tbm[tblIdx].addRow(temp);
            selectionModel.setSelectionInterval(tbm[tblIdx].getRowCount()-1,tbm[tblIdx].getRowCount()-1);
        }
    });
}

You can't pass i directly into your anonymous ActionListener since it's not a final variable, so at the beginning of each iteration through the loop a temporary final variable tblIdx is created and set to whatever i currently is.

I personally would accomplish this by subclassing ActionListener and passing the table index as a parameter to the constructor, but that's just me.

Dan O
  • 6,022
  • 2
  • 32
  • 50
  • Thanks! I set the final int within the for loop and it works great! I guess using an instance variable was not the way to go. – user1418454 Jun 08 '12 at 16:51