Erro ao clicar em botão em uma JTable[RESOLVIDO]

Olá pessoal, eu to com um erro na hora em que eu clico em um botao em uma JTable.

E assim: eu abro a tela de consulta, os dados estão aparecendo corretamente. Daí clico no botão e ele abre uma janela com os detalhes.

Depois, fecho e faço uma consulta aproximada. ele abre normal. Quando repito o procedimento acima ele da o seguinte erro:

[code]Exception in thread “AWT-EventQueue-0” java.lang.IndexOutOfBoundsException: Index: 2, Size: 1
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at UsuarioTableModel.setValueAt(UsuarioTableModel.java:141)
at javax.swing.JTable.setValueAt(JTable.java:2710)
at javax.swing.JTable.editingStopped(JTable.java:4712)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:125)
at javax.swing.AbstractCellEditor.stopCellEditing(AbstractCellEditor.java:68)
at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(BasicTableUI.java:980)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:263)
at java.awt.Component.processMouseEvent(Component.java:6285)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4235)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

[/code]

Se puderem me ajudar…

fala ai cara posta o codigo, mas chutar de cabeça

caso tiver passando isso:

Coloque < ao inves de <=.

Ele esta passando tanto pela posicao 0 e 1 do array.

pois Listas e Arrays tem como posição inicial 0 (zero), não 1 (um). Pense nisso!

O código do botão que puxa os dados da JTable

[code]int row = tabela.getSelectedRow();
if (row != -1){
Usuario objetoClicado = Con_Usuario.modelo.get(row);
// TODO Auto-generated method stub

    		Menu.tabbed.add(new DetalhesUsuario(UsuarioDao.visualizarUsuario
    				(objetoClicado.getId()),Menu.a),"Detalhes de usuários");

[/code]

e o código da filtragem de dados

[code]class FiltraUsuario implements KeyListener{

	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
					
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub	
		if (! modelo.isEmpty()){
			modelo.limpaLista();
		}
		String text = txtPesquisa.getText();
		modelo.adicionaLista(UsuarioDao.listarUsuarios(text)) ;
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
            }[/code]

	static List<Usuario> usuarios;
	   
	public static List<Usuario> listarUsuarios(String nome) {
	      Conexao.conecta();  
	      try{                   
	         // procedimentos para obter os dados de uma tabela  
String SQL = "SELECT * FROM usuario as usu INNER JOIN perfil_acesso as pa ON " +
			"usu.perfil_acesso  =  pa.id_perfil_acesso "+
		         		"WHERE usu.nome LIKE ?";

	         
	         PreparedStatement pstmt = Conexao.connection.prepareStatement(SQL);  
	         pstmt.setString(1, nome + "%");
	         ResultSet rs = pstmt.executeQuery();            
	         usuarios = new ArrayList<Usuario>();
	         while(rs.next()){                         
	            Usuario usuario = new Usuario();

	            usuario.setId(rs.getInt("id"));  
	            usuario.setNome(rs.getString("nome"));  
	            usuario.setLogin(rs.getString("usuario"));  
	            usuario.setPerfilName(rs.getString("pa.perfil_acesso"));
	            usuario.setSituacao(rs.getInt("situacao"));
	            usuario.setPerfil(rs.getInt("perfil_acesso"));
	            usuarios.add(usuario);
	         }  
	         rs.close();                     
	     }  
	      catch(SQLException ex){  
	    	  System.out.print("Ocorreu um erro: ");	
	    	 	System.out.println("SQLException: " + ex.getMessage());
		        System.out.println("SQLState: " + ex.getSQLState());
		        System.out.println("VendorError: " + ex.getErrorCode());
	    	 	
	     }  finally {              
	         Conexao.fecha();  
	     }
		return usuarios;
	    
	}

Olha sua excessão:

. . . java.lang.IndexOutOfBoundsException: Index: 2, Size: 1 at UsuarioTableModel.setValueAt(UsuarioTableModel.java:141)

Você está tentando acessar uma posição que não existe, por isso o IndexOutOfBoundsException.
Debuga seu código, ve onde que vc tá chamando o setValueAt(), e vê quais os parâmetros que estão sendo passados.

Ele ta passando a coluna do botão, mas ela não esta no set value. Abaixo, o código:

[code]public void setValueAt(Object valor, int linha, int coluna) {
Usuario c = usuario.get(linha);

	switch (coluna) {
	case 0:
		c.setNome(valor.toString()); 
		break;
	case 1:
		c.setLogin(valor.toString());
		break;
	case 2:
		c.setPerfilName(valor.toString()); 
		break;
	case 3:
		c.setSituacao(Integer.parseInt(valor.toString())); // mudamos o situacao
		break;
             }[/code]

PS: minha tabela possui tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

Estranho. Ele diz que a linha não existe no seu ArrayList.

Qual é o código do botão?

Você não entendeu cara.

Seu método setValue() espera 3 argumentos (o valor, a linha a ser alterada, e a coluna a ser alterada).

Por algum motivo, o método está recebendo, provavelmente, um número de linha maior que o tamanho da lista usuario.
Portanto quando vc faz usuario.get(linha) ele lança a excessão.

O que vc precisa descobrir é o pq dele estar passando esse valor errado.

Outra coisa que vc não trata caso a coluna passada seja maior que 3.

O código do botão e esse:

[code]
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
int row = tabela.getSelectedRow();
if (row > -1){
Usuario objetoClicado = Con_Usuario.modelo.get(row);

    		Menu.tabbed.add(new DetalhesUsuario(UsuarioDao.visualizarUsuario(objetoClicado.getId()),Menu.a),"Detalhes de usuários");
    		
    		Menu.tabbed.setTabComponentAt(Menu.a,
				new ButtonTabComponent(Menu.tabbed));
    		Menu.abaUsu = Menu.a;
    		Menu.a++;
    		Menu.tabbed.setSelectedIndex(Menu.abaUsu);
    	}[/code]

Acho que já vi esse erro.

Você está clicando no botão antes de terminar a edição da tabela, certo? Ou seja, o seu editor ainda está ativo, não?

Não me lembro de solução elegante para isso. O que fiz foi testar se a linha passada no setValueAt era válida.
E simplesmente retornar se não fosse.

Esse botão so serve para chamar uma tela com os dados do usuario. o problema e que ele ta passando pro setValueAt coluna = 4;

[quote=ElesisLink]Esse botão so serve para chamar uma tela com os dados do usuario. o problema e que ele ta passando pro setValueAt coluna = 4;
[/quote]

Mas não é esse o erro que você está tendo. Leia a sua mensagem de erro. Ela está dizendo que existe 1 linha na sua tabela, mas o setValueAt tentou passar o índice 2.
E note também que quem dispara o erro é o ArrayList.

Uma coluna inválida no seu setValueAt apenas fará com que o switch não caia em caso nenhum.

Será entaum que o erro esta na classe que cria o botao na JTable ?

[code]import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

public class ButtonColumn extends AbstractCellEditor
implements TableCellRenderer, TableCellEditor{

JTable table;
JButton renderButton;
JButton editButton;
String text;

public ButtonColumn(JTable table, int column, ActionListener action,
		String text, ImageIcon ico){   
        
	this.table = table;
    
    editButton = new JButton(text);
    renderButton = new JButton(text);
    editButton.setIcon(ico);
    renderButton.setIcon(ico);
    editButton.setFocusPainted(false);
    editButton.addActionListener(action);

    TableColumnModel columnModel = table.getColumnModel();
    columnModel.getColumn(column).setCellRenderer(this); // quando clicar
    columnModel.getColumn(column).setCellEditor(this); // após clicar

}


public Component getTableCellRendererComponent(
		JTable table, Object value, boolean isSelected,
		boolean hasFocus, int row, int column){
       
	if (hasFocus){
		renderButton.setForeground(table.getForeground());    
		renderButton.setBackground(UIManager.getColor("Button.background"));
	}
	else if (isSelected){      
		renderButton.setForeground(table.getSelectionForeground());
		renderButton.setBackground(table.getSelectionBackground());
	}
	else{
		renderButton.setForeground(table.getForeground());    
		renderButton.setBackground(UIManager.getColor("Button.background"));
	}
	//renderButton.setText( (value == null) ? "Ver" : value.toString() );    
	return renderButton;
}

public Component getTableCellEditorComponent(JTable table,
		Object value, boolean isSelected, int row, int column){

	text = (value == null) ? "Ver" : value.toString();
	//editButton.setText( text ); 
	return editButton;
    
}

public Object getCellEditorValue(){
        
	return text;
    
}

}
[/code]

Insere essa linha no setValueAT:

public void setValueAt(Object valor, int linha, int coluna) { if (linha &lt; 0 || linha &gt;= usuario.size()) return;

Ta dando um outro erro relacionado a esta linha

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Row index out of range
	at javax.swing.JTable.boundRow(JTable.java:2106)
	at javax.swing.JTable.setRowSelectionInterval(JTable.java:2129)
	at Con_Usuario$FiltraUsuario.keyReleased(Con_Usuario.java:127)
	at java.awt.Component.processKeyEvent(Component.java:6249)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2801)
	at java.awt.Component.processEvent(Component.java:6065)
	at java.awt.Container.processEvent(Container.java:2041)
	at java.awt.Component.dispatchEventImpl(Component.java:4651)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Component.dispatchEvent(Component.java:4481)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
	at java.awt.Component.dispatchEventImpl(Component.java:4523)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2478)
	at java.awt.Component.dispatchEvent(Component.java:4481)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
	at java.awt.EventQueue.access$000(EventQueue.java:84)
	at java.awt.EventQueue$1.run(EventQueue.java:602)
	at java.awt.EventQueue$1.run(EventQueue.java:600)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
	at java.awt.EventQueue$2.run(EventQueue.java:616)
	at java.awt.EventQueue$2.run(EventQueue.java:614)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

PS: O outro erro parou de aparecer… :smiley:

Você não pode chamar esse comando numa tabela vazia. Teste se tem algum elemento antes de chama-lo.

Eu vi… acabei de adicionar um If para verificar se a dados na tabela. Se sim, ele usa esse comando. Funcionou… :smiley:

Valeu ViniGodoy, vc é meu salvador… Valeu mesmo, de verdade… :thumbup: