JTable com JComboBox não está obedecendo à tecla TAB

2 respostas
Roger75

Olá pessoal,

Tenho uma aplicação em que mostro um JTable que tem algumas colunas com JComboBox e outra que mostra células simples.

O problema é que quando eu clico na tecla TAB a seleção deveria mudar de célula a célula da tabela, mas o que está acontecendo é que só as células simples estão ficando com foco.

Alguém já teve este problema?

Código abaixo:

package teste.jcombo1;
import java.awt.Component; 
import java.util.ArrayList; 
import java.util.EventObject; 
import java.util.List; 

import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.event.CellEditorListener; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableCellEditor; 
import javax.swing.table.TableCellRenderer; 



public class ComboTable { 
    public static void main(String args[]) { 
        SwingUtilities.invokeLater(new Runnable() { 
            public void run() { 
                new ComboTable(); 
            } 
        }); 
    } 

    public ComboTable() { 
        MyModel model = new MyModel(); 
        JTable table = new JTable(model); 
        table.setDefaultRenderer(JComboBox.class, new ComboRenderer()); 
        table.setDefaultEditor(JComboBox.class, new ComboEditor()); 
        JScrollPane scroller = new JScrollPane(table); 
        JFrame f = new JFrame(); 
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        f.getContentPane().add(scroller); 
        f.setSize(500, 500); 
        f.setVisible(true); 
    } 
} 

class ComboRenderer implements TableCellRenderer { 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
        return (JComboBox) value; 
    } 
} 

class ComboEditor implements TableCellEditor { 
    private java.util.Vector listeners = new java.util.Vector(); 

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
        table.setRowSelectionInterval(row, row); 
        table.setColumnSelectionInterval(column, column); 
        return (JComboBox) value; 
    } 

    public boolean shouldSelectCell(EventObject o) { 
        return true; 
    } 

    public void removeCellEditorListener(CellEditorListener l) { 
        listeners.remove(l); 
    } 

    public void addCellEditorListener(CellEditorListener l) { 
        listeners.add(l); 
    } 

    public void cancelCellEditing() { 
    } 

    public Object getCellEditorValue() { 
        return null; 
    } 

    public boolean isCellEditable(EventObject o) { 
        return true; 
    } 

    public boolean stopCellEditing() { 
        return true; 
    } 
} 

class MyModel extends AbstractTableModel { 
    String[] headers = { "Coluna 1", "Coluna 2" ,"Coluna 3"}; 

    Class[] columnTypes = { JComboBox.class, String.class ,JComboBox.class}; 

    Object[] items = {"A", "B", "C", "D"}; 
    
    List data; 
    
    public MyModel() { 
        data = new ArrayList(); 
        List linha = new ArrayList(); 
        linha.add(new JComboBox(items)); 
        linha.add(new String("XXXXX"));
        linha.add(new JComboBox(items)); 
        data.add(linha); 
        
        linha = new ArrayList(); 
        linha.add(new JComboBox(items)); 
        linha.add(new String(""));
        linha.add(new JComboBox(items)); 
        data.add(linha); 
       
    } 

    public int getRowCount() { 
        return data.size(); 
    } 

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

    public Class getColumnClass(int col) { 
        return columnTypes[col]; 
    } 

    public String getColumnName(int col) { 
        return headers[col]; 
    } 

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

    public Object getValueAt(int row, int col) { 
        java.util.List myRow = (java.util.List) data.get(row); 
        return myRow.get(col); 
    } 
}

Obrigado

2 Respostas

Roger75

Essa parece que está difícil, ninguém respondeu…

Bem, procurando na Internet vi um exemplo que faz mais ou menos o que eu quero (apresenta algumas falhas), mas está melhor que o código anterior. O código está logo abaixo.

O problema é que quando o foco está na célula de JComboBox as teclas “arrow keys” (setas) não funcionam, para selecionar as opções do combobox. O TAB funciona, pelo menos.

Pessoal, parece frescura este problema mas o cliente está enchendo o meu saco por causa disso. Na verdade o código exato não é nem esse, é bem mais complexo, mas acredito que resolvendo o do código abaixo resolverei no meu sistema.

Abraço

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;




public class TesteJComboJTable extends JFrame{
    public TesteJComboJTable(){
        Container pane = getContentPane();
		pane.setLayout(new BorderLayout());
        JTable table = new JTable();
	    DefaultTableModel model = (DefaultTableModel)table.getModel();
	    
	    // Add some columns
	    //model.addColumn("A", new Object[]{"item1"});
	    //model.addColumn("B", new Object[]{"item2"});
	    
	    model.addColumn("A", new Object[]{"item1","item3"});
	    model.addColumn("B", new Object[]{"item2","item4"});
	    model.addColumn("C", new Object[]{"item2","item4"});
	    
	    // These are the combobox values
	    String[] values = new String[]{"item1", "item2", "item3"};
	    String[] values2 = new String[]{"item11", "item22", "item33"};
	    // Set the combobox editor on the 1st visible column
	    int vColIndex = 0;
	    TableColumn col = table.getColumnModel().getColumn(vColIndex);
	    col.setCellEditor(new MyComboBoxEditor(values));
	    
	    // If the cell should appear like a combobox in its
	    // non-editing state, also set the combobox renderer
	    col.setCellRenderer(new MyComboBoxRenderer(values));
	    
	    vColIndex = 2;
	    TableColumn col2 = table.getColumnModel().getColumn(vColIndex);
	    col2.setCellEditor(new MyComboBoxEditor(values2));
	    
	    // If the cell should appear like a combobox in its
	    // non-editing state, also set the combobox renderer
	    col2.setCellRenderer(new MyComboBoxRenderer(values2));
	    
		final JTable jtable1=table;
		final DefaultTableModel modelo1=model;
		table.addKeyListener(new KeyAdapter() {
				public void keyPressed(KeyEvent e) {
					//int linha = jtable.getSelectedRow() ;
					int linha = jtable1.getSelectedRow() ;
					//if (e.getKeyCode() == KeyEvent.VK_ENTER){
					int tot_linhas, tot_colunas;
					tot_linhas=jtable1.getRowCount();
					tot_colunas=jtable1.getColumnCount();
					int coluna=jtable1.getSelectedColumn();
					System.out.println("Nro de colunas:"+jtable1.getColumnCount());
					System.out.println("Coluna selecionada:"+jtable1.getSelectedColumn());
					
					//if (e.getKeyCode() == KeyEvent.VK_TAB && jtable1.getSelectedColumn()==(jtable1.getColumnCount()-1)){
					if (e.getKeyCode() == KeyEvent.VK_TAB && (tot_linhas-1==linha) && (tot_colunas-1==coluna)){
						modelo1.addRow(new String[]{"",""});

						jtable1.changeSelection(linha++,0,true,true );
						//contlinhas++;
						//numlinhas++;	 										
					}
				}
		});		
	    
	    
	    JScrollPane jsp = new JScrollPane(table);
		pane.add(jsp, BorderLayout.CENTER);
    }
	public static void main(String[] args) {
			    

	    //*****
		TesteJComboJTable stt = new TesteJComboJTable();
		stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		stt.setSize(400, 300);
		stt.setVisible(true);
	    
	    //*****


	}
}



import java.awt.Component;

import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;


public class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
    public MyComboBoxRenderer(String[] items) {
        super(items);
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            super.setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }

        // Select the current value
        setSelectedItem(value);
        return this;
    }
}




import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;


public class MyComboBoxEditor extends DefaultCellEditor {
    public MyComboBoxEditor(String[] items) {
        super(new JComboBox(items));
    }
}
F

ótimo post Roger… Só tem um problema: O TableCellEditor, como está no segundo código não permite criar o Model conforme o primeiro.

Criado 23 de junho de 2005
Ultima resposta 26 de set. de 2007
Respostas 2
Participantes 2