Results 1 to 11 of 11
  1. #1
    ZackO is offline Member
    Join Date
    Oct 2010
    Posts
    6
    Rep Power
    0

    Default ArrayIndexOutOfBounds, JTable.getValueAt

    Not sure if this should be in New to Java or AWT/Swing, but here goes.

    I've got a JTable. The JTable has a ListSelectionListener.

    Java Code:
    public void valueChanged(ListSelectionEvent l)
    { 
           int row = table1.getSelectedRow();
           int column = table1.getSelectedColumn();
           boolean isAdjusting = l.getValueIsAdjusting(); 
    		
           String value = (String) table1.getValueAt(row, 0);
    [...]
    Whenever I run the program, the first two clicks on the JTable throw double (mousePressed, mouseReleased) ArrayIndexOutOfBoundsExceptions: -1. They point to the last line above. After that, everything works as planned.

    Any help appreciated.

    Thanks,

    ~Zack

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by ZackO View Post
    Not sure if this should be in New to Java or AWT/Swing, but here goes.

    I've got a JTable. The JTable has a ListSelectionListener.

    Java Code:
    public void valueChanged(ListSelectionEvent l)
    { 
           int row = table1.getSelectedRow();
           int column = table1.getSelectedColumn();
           boolean isAdjusting = l.getValueIsAdjusting(); 
    		
           String value = (String) table1.getValueAt(row, 0);
    [...]
    Whenever I run the program, the first two clicks on the JTable throw double (mousePressed, mouseReleased) ArrayIndexOutOfBoundsExceptions: -1. They point to the last line above. After that, everything works as planned.
    I'm not sure how we can guess the cause of the error based on a small amount of non-running code. I think that your best bet will be to create an SSCCE and post it here.

    Best of luck.

  3. #3
    ZackO is offline Member
    Join Date
    Oct 2010
    Posts
    6
    Rep Power
    0

    Default

    Perfect example of the problem. Code should print out "valid" and the contents of the first column, same row cell if the selected cell is in the second column, and "invalid" and the contents of the first column, same row cell if the selected cell is in the first. Instead, the first two clicks throw errors.

    The code is a bit messy, but works.

    Java Code:
    import javax.swing.*;
    import javax.swing.event.*;
    import java.awt.*;
    
    public class test
    {
    	JTable table;
    	
    	public static void main(String[] args)
    	{
    		new test();
    	}
    	
    	public test()
    	{
    		String[] columns = {"One", "Two"};
    		String[][] data = {{"bla", "bla"}, {"more", "and more"}};
    		
    		JFrame frame = new JFrame("Title");
    		JPanel panel = new JPanel(new BorderLayout());
    		table = new JTable(data, columns);
    		JScrollPane pane = new JScrollPane(table);
    		
    		panel.add(pane);
    		frame.add(panel);
    		
    		table.setRowSelectionAllowed(true);                                
            table.setColumnSelectionAllowed(true);                            
            table.setCellSelectionEnabled(true); 
    		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    		
    		thing listener = new thing();
    		ListSelectionModel listSelectionModel = table.getSelectionModel();
            listSelectionModel.addListSelectionListener(listener);
    		table.setSelectionModel(listSelectionModel);
    		table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
    		
    		frame.setVisible(true);
    		frame.setSize(400, 400);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	}
    	
    	class thing implements ListSelectionListener
    	{	
    		public void valueChanged(ListSelectionEvent l)
    		{ 		
    			int row = table.getSelectedRow();
    			int column = table.getSelectedColumn();
    			boolean isAdjusting = l.getValueIsAdjusting(); 
    			
    			String value = (String) table.getValueAt(row, 0);
    			
    			if (!isAdjusting)
    			{
    				if (column != 0)
    				{
    					System.out.println("valid: " + value);
    				}
    				if (column == 0)
    				{
    					System.out.println("invalid: " + value);
    				}
    			}
    		}
    	}
    }
    Thanks,

    ~Zack
    Last edited by ZackO; 10-17-2010 at 12:37 AM. Reason: for default close operation

  4. #4
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    So what is the value of row at the time you get the AIOOBE? It may well be that you have a value that causes JTable to choke when you call getValueAt().

  5. #5
    ZackO is offline Member
    Join Date
    Oct 2010
    Posts
    6
    Rep Power
    0

    Default

    According to a
    System.out.println(row);
    before the erroneous line, the value of row is -1 regardless of where I click. However, that's only true for the first two clicks. I'm pretty confused.

    ~Zack

  6. #6
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    Are you sure you are getting this error for the first two clicks and not getting this error twice for the first click. This is what I'm seeing... if I click on two cells in the same column. If I click on two cells in the same row I can generate lots of errors.

    Since you only want value if the list selection is not changing put the "value=" line inside the if block.

  7. #7
    ZackO is offline Member
    Join Date
    Oct 2010
    Posts
    6
    Rep Power
    0

    Default

    Quote Originally Posted by pbrockway2 View Post
    Are you sure you are getting this error for the first two clicks and not getting this error twice for the first click. This is what I'm seeing... if I click on two cells in the same column. If I click on two cells in the same row I can generate lots of errors. Damn, I hadn't noticed that.

    Since you only want value if the list selection is not changing put the "value=" line inside the if block. Actually I always want value (the first column has a list of times and I want to get the time associated with the row of the selected cell), but putting the "value =" inside the if block seems to work.
    This was my original code (inside the valueChanged method):

    Java Code:
    int row = table1.getSelectedRow();
    int column = table1.getSelectedColumn();
    boolean isAdjusting = l.getValueIsAdjusting(); 
    String value = (String) table1.getValueAt(row, 0);
    	
    if (!isAdjusting)
    {
    	if (column != 0)
    	{
    		setInfoPanelEnabled(true);
    		thetime1.setText("Time:       " + value);
    	}
    	if (column == 0)
    	{
    		setInfoPanelEnabled(false);
    		thetime1.setText("Time:               N/A");
    	}
    }
    and this is the code now:

    Java Code:
    int row = table1.getSelectedRow();
    int column = table1.getSelectedColumn();
    boolean isAdjusting = l.getValueIsAdjusting(); 
    		
    if (!isAdjusting)
    {
    	if (column != 0)
    	{
    		String value = (String) table1.getValueAt(row, 0);
    		setInfoPanelEnabled(true)		
                    thetime1.setText("Time:       " + value);
    	}
    	if (column == 0)
    	{
    		setInfoPanelEnabled(false);
    		thetime1.setText("Time:               N/A");
    	}
    }
    It works, but I'm still not sure why. Thanks for the help anyway.

    ~Zack

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    You're welcome. As regards the understanding, I'm in the same boat as you. So I guess we have until one of the Swing guys swing by.

    (You say you always want value but the method gets called twice per click. So long as the first doesn't result in an exception you will catch value the second time around.)

    With your code I am able to see any number of exceptions by clicking alternately on the two cells in the top row. But if I slow down and click s-l-o-w-l-y on one of the cells the selection "takes" and the exceptions disappear.

    [Edit]

    I swear that was the behaviour a couple of hours ago. After restarting this computer I don't see it. Now the original code gives 2 exceptions on the first click. row==-1 can be avoided by just saying "if(row == -1) return;" before the calculation of value. Note that with either of these solutions the listener method gets called 4 times on the first click which I think has something to do with the problem.
    Last edited by pbrockway2; 10-17-2010 at 06:07 AM.

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,196
    Rep Power
    19

    Default

    I guess we have until one of the Swing guys swing by.
    Aw, c'mon, it's the weekend and they're out swingin' ;) I'll try to fill in for them.

    Some notes:

    1. Please indent your code consistently and correctly. It makes it easier to read and can get you better help sooner. In this case, I glanced at the code, kept the browser tab open and only came back to it when there was nothing else to interest me on 4 forums, and that only because just a few lines were wrongly indented. (Where the indenting appears totally random, I don't come back.)

    2. The first two lines of these three are redundant. Take a look at the JTable source for the last method called to know why.
    Java Code:
    table.setRowSelectionAllowed(true);
    table.setColumnSelectionAllowed(true);
    table.setCellSelectionEnabled(true);
    1A. Please remove trailing spaces as a courtesy to members who have limited bandwidth.

    3. The last line of these three is redundant. Can you see why?
    Java Code:
    ListSelectionModel listSelectionModel = table.getSelectionModel();
    listSelectionModel.addListSelectionListener(listener);
    table.setSelectionModel(listSelectionModel);
    4. "thing" is an extremely poor choice of name for a class on two accounts: a class name should be descriptive, and should start with an uppercase letter.

    5. The same listener is added to both the table's ListSelectionModel and the table's ColumnModel's ListSelectionModel. So when both row and column change, two valueChanged events are generated. Since AWT and Swing do not specify the sequence of event delivery, the initially selected column may change while the selected row is still -1 (no selection) or vice versa. Your code has to deal with this.

    After you've made necessary changes, post the new code if you still have any problems.

    db

  10. #10
    ZackO is offline Member
    Join Date
    Oct 2010
    Posts
    6
    Rep Power
    0

    Default

    Quote Originally Posted by Darryl.Burke View Post
    Aw, c'mon, it's the weekend and they're out swingin' ;) I'll try to fill in for them.

    Some notes:

    1. Please indent your code consistently and correctly. It makes it easier to read and can get you better help sooner. In this case, I glanced at the code, kept the browser tab open and only came back to it when there was nothing else to interest me on 4 forums, and that only because just a few lines were wrongly indented. (Where the indenting appears totally random, I don't come back.) To be fair, that's the fora's fault. I indent all my code perfectly, but the texteditor likes to screw it up. And really, was it that bad?

    2. The first two lines of these three are redundant. Take a look at the JTable source for the last method called to know why. True. I'd forgotten to take them out.
    Java Code:
    table.setRowSelectionAllowed(true);
    table.setColumnSelectionAllowed(true);
    table.setCellSelectionEnabled(true);
    1A. Please remove trailing spaces as a courtesy to members who have limited bandwidth. Will do.

    3. The last line of these three is redundant. Can you see why? Yeah.
    Java Code:
    ListSelectionModel listSelectionModel = table.getSelectionModel();
    listSelectionModel.addListSelectionListener(listener);
    table.setSelectionModel(listSelectionModel);
    4. "thing" is an extremely poor choice of name for a class on two accounts: a class name should be descriptive, and should start with an uppercase letter. I know, I know. Just temporary.

    5. The same listener is added to both the table's ListSelectionModel and the table's ColumnModel's ListSelectionModel. So when both row and column change, two valueChanged events are generated. Since AWT and Swing do not specify the sequence of event delivery, the initially selected column may change while the selected row is still -1 (no selection) or vice versa. Your code has to deal with this.


    The reason I'm adding the listener twice is because if I only add it to the table's ListSelectionModel, it won't pick up column changes. So I understand that two events are being generated, but how do I deal with the possibility of the row being -1?

    After you've made necessary changes, post the new code if you still have any problems.

    db
    Java Code:
    import javax.swing.*;
    import javax.swing.event.*;
    import java.awt.*;
    
    public class test
    {
       JTable table;
    	
       public static void main(String[] args)
       {
            new Test();
       }
    	
       public Test()
       {
            String[] columns = {"One", "Two"};
    	String[][] data = {{"bla", "bla"}, {"more", "and more"}};
    	
    	JFrame frame = new JFrame("Title");
    	JPanel panel = new JPanel(new BorderLayout());
    	table = new JTable(data, columns);
    	JScrollPane pane = new JScrollPane(table);
    	
    	panel.add(pane);
    	frame.add(panel);
    		                          
            table.setCellSelectionEnabled(true); 
    	table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    	
    	TableListener listener = new TableListener();
    	ListSelectionModel listSelectionModel = table.getSelectionModel();
            listSelectionModel.addListSelectionListener(listener);
            table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
    		
    	frame.setVisible(true);
    	frame.setSize(400, 400);
    	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       }
    	
       class TableListener implements ListSelectionListener
       {	
    	public void valueChanged(ListSelectionEvent l)
    	{ 		
    		int row = table.getSelectedRow();
    		int column = table.getSelectedColumn();
    		boolean isAdjusting = l.getValueIsAdjusting(); 
    		
    		System.out.println(row);
    		String value = (String) table.getValueAt(row, 0);
    		
    		if (!isAdjusting)
    		{
    			if (column != 0)
    			{
    				System.out.println("valid: " + value);
    			}
    			if (column == 0)
    			{
    				System.out.println("invalid");
    			}
    		}
    	}
       }
    }
    ~Zack

  11. #11
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,196
    Rep Power
    19

    Default

    I indent all my code perfectly, but the texteditor likes to screw it up.
    That's a result of mixing spaces and tabs. All editors don't expand a tab character to the same number of spaces.

    I know, I know. Just temporary.
    And one of those things that might deter members from taking and interest.

    I'm pointing out the ways for you to get better help sooner. I have no other interest in voicing criticism.

    The reason I'm adding the listener twice is because if I only add it to the table's ListSelectionModel, it won't pick up column changes.
    Sure, you do need a listener on both the selection models.

    So I understand that two events are being generated, but how do I deal with the possibility of the row being -1?
    With a boolean test. And remember that it could be the column that's -1.

    Untested code.
    Java Code:
      class TableListener implements ListSelectionListener {
    
        @Override
        public void valueChanged(ListSelectionEvent l) {
          if (l.getValueIsAdjusting()) {
            return;
          }
          
          int row = table.getSelectedRow();
          int column = table.getSelectedColumn();
          if (row == -1 || column == -1) {
            return;
          }
          System.out.println(row);
          
          if (column == 0) {
            System.out.println("invalid");
          } else {
            System.out.println("valid: " + table.getValueAt(row, 0));
          }
        }
    If the columns are movable, you may need to convertColumnIndexToModel.

    db

Similar Threads

  1. ArrayIndexOutofBounds Exception
    By atul.goldenstring in forum New To Java
    Replies: 10
    Last Post: 04-10-2010, 10:47 AM
  2. Adding New JTable in JTable
    By anilkumar_vist in forum New To Java
    Replies: 0
    Last Post: 01-27-2010, 08:27 AM
  3. ArrayIndexOutOfBounds
    By SwEeTAcTioN in forum New To Java
    Replies: 6
    Last Post: 12-07-2009, 12:59 AM
  4. Add a row in JTable
    By makpandian in forum AWT / Swing
    Replies: 4
    Last Post: 04-15-2009, 08:48 PM
  5. Replies: 2
    Last Post: 05-15-2008, 10:15 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •