Foco em jTable dentro do jComboBox

5 respostas
C

olá pessoal!! Estou com um problema a algum tempo, então resolvi postar aqui para ver se alguém me da uma luz.
Eu coloquei uma jTable dentro de um jComboBox e tornei o combo editável para que quando o usuário digitar algo, isso seja filtrado na jtable.
O problema que ocorre é que eu não consigo passar o foco para a jtable, talvez por ela estar dentro do jPopMenu do combo, e assim o usuário não pode percorrer as linhas da tabela com o teclado.
Então eu criei um evento keyPressed para que se as teclas UP ou DOWN forem pressionadas as linhas da tabela sejam percorridas, incrementando e decrementando as linhas conforme um índice, como no exemplo.

if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    if (i < jTable1.getRowCount() - 1) {
                        i++;
                    } 

                    jTable1.addRowSelectionInterval(i, i);

                }

                if (e.getKeyCode() == KeyEvent.VK_UP) {
                    if (i >= 1) {
                        i--;
                    }
                        jTable1.addRowSelectionInterval(i, i);
                    
                }

Essa gambiarra ta muito tosca e acontecem alguns problemas referentes ao scroll não acompanhar a mudança das linhas.

Se eu conseguisse fazer a jTable ganhar o foco o problema seria resolvido, porém eu ainda não consegui.
Se alguém souber como eu faço para a jTable ganhar o foco estando dentro do jPopMenu me ajuda por favor.

Obrigado.

5 Respostas

J

Bah, eu estou com a mesma dúvida a tempos! Será que não é possível fazer isso??? :shock:

wellington7

JTable dentro do ComboBox? :shock:
Por que ou pra que?
Em todo caso, poste o código completo (ou um SCCEE), isso facilita agente te ajudar.

C

Aqui está o código, espero que me ajude :D

import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.JTextComponent;


public class comboMulticolumn extends javax.swing.JFrame {

    private String[] colunas = null;
    private String[][] linhas = null;
    private RowFilter<Object, Object> rf = null;
    private TableRowSorter<TableModel> sorter = null;
    private DefaultTableModel tm = new DefaultTableModel();
    private int colFiltro = 0;
    private int i = -1;

    /** Creates new form comboboxMulticolumn */
    public comboMulticolumn() {
        colunas = new String[]{"Sigla", "Estado"};
        linhas = new String[][]{
                    {"DF", "Distrito Federal"},
                    {"ES", "Espírito Santo"},
                    {"GO", "Goias"},
                    {"MA", "Maranhão"},
                    {"MG", "Minas Gerais"},
                    {"PR", "Paraná"},
                    {"RJ", "Rio de Janeiro"},
                    {"RN", "Rio Grande do Norte"},
                    {"RO", "Rondônia"},
                    {"RR", "Rorâima"},
                    {"RS", "Rio Grande do Sul"},
                    {"SC", "Santa Catarina"},
                    {"SE", "Sergipe"},
                    {"SP", "São Paulo"},
                    {"TO", "Tocantins"}
                };


        initComponents();
        jComboBox1.setEditable(true);
        jComboBox1.setUI(new MyComboUI());
        tm = new DefaultTableModel(linhas, colunas);
        jTable1.setModel(tm);
        filtraDados(tm);

    }

    protected class MyComboUI extends MetalComboBoxUI {
//cria o menu pop-up do combobox
        @Override
        protected ComboPopup createPopup() {
            return (ComboPopup) new TableComboPopup(this);
        }
    }

    public class TableComboPopup extends BasicComboPopup implements ListSelectionListener {

        private JScrollPane pane;

        public TableComboPopup(MyComboUI ui) {
            super(jComboBox1);
            jTable1.setAutoCreateRowSorter(true);
            pane = new JScrollPane(jTable1);
            jTable1.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            jTable1.getSelectionModel().addListSelectionListener(this);
        }

        @Override
        public void show() {
            super.removeAll();
            Dimension dim = new Dimension(300, 200);
            pane.setPreferredSize(dim);
            super.add(pane);
            selectRow();
            super.show();
        }

        private void selectRow() {
            jTable1.addMouseListener(new  

                  MouseAdapter( ) {

                    @Override
                public void mouseClicked(java.awt.event.MouseEvent me) {

                    jComboBox1.setPopupVisible(false);
                    final JTextComponent editor = (JTextComponent) jComboBox1.getEditor().getEditorComponent();
                    int posicao = jTable1.getSelectedRow();
                    editor.setText(jTable1.getValueAt(posicao, colFiltro).toString());
                }
            });
        }

        public void valueChanged(ListSelectionEvent e) {
            //jComboBox1.setSelectedIndex(jTable1.getSelectedRow());
        }

        public void jComboBox1ItemStateChanged(ItemEvent e) {
            if (e.getStateChange() == e.DESELECTED) {
                return;
            }
            jTable1.getSelectionModel().removeListSelectionListener(this);
            selectRow();
            jTable1.getSelectionModel().addListSelectionListener(this);
        }
    }

    public void filtraDados(TableModel tm) {
        final JTextComponent editor = (JTextComponent) jComboBox1.getEditor().getEditorComponent();
        sorter = new TableRowSorter<TableModel>(tm);
        jTable1.setRowSorter(sorter);

        editor.addCaretListener(new  

              javax.swing.event.CaretListener  
                   () {

            public void caretUpdate(javax.swing.event.CaretEvent e) {
                String text = "(?i)^" + editor.getText();
                rf = RowFilter.regexFilter(text, colFiltro);
                sorter.setRowFilter(rf);

            }
        });

        editor.addKeyListener(new  

              KeyAdapter( ) {

                @Override
            public void keyPressed(java.awt.event.KeyEvent e) {
                jComboBox1.setPopupVisible(true);
                if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    if (i < jTable1.getRowCount() - 1) {
                        i++;
                    } else {
                        i = 0;
                    }
                    jTable1.addRowSelectionInterval(i, i);

                }

                if (e.getKeyCode() == KeyEvent.VK_UP) {
                    if (i >= 1) {
                        i--;
                        jTable1.addRowSelectionInterval(i, i);
                    } else {
                        i = jTable1.getRowCount() - 1;
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
                    editor.setEditable(true);
                }

                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    int posicao = jTable1.getSelectedRow();
                    editor.setText(jTable1.getValueAt(posicao, colFiltro).toString());

                }

            }
//se a jtable for filtrada e não restar nehum item, a última letra digitada é apagada
            @Override
            public void keyReleased(java.awt.event.KeyEvent e) {
                if (jTable1.getRowCount() == 0) {
                    editor.setText(editor.getText().substring(0, editor.getText().length() - 1));
                }
                if (jTable1.getRowCount() == 0 && editor.getText().length() >= 1) {
                    editor.setText("");
                }

            }
        });

    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jComboBox1 = new javax.swing.JComboBox();

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(jTable1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(106, 106, 106)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(117, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(87, 87, 87)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(97, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new comboMulticolumn().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration

}
C

estou meio enferrujado em swing, mas vamos lá.
Tenta colocar o foco em alguma linha e coluna da jTable
se n me engane tem um método q vc consegue pegar a linha e a coluna da jtable, tente colocar o foco ali, pode ser q dê certo.

C

Com esse método aqui (linha 153) eu seto a seleção de uma linha da tabela de acordo com o índice “i” que é incrementado e decrementado conforme as teclas “up” e “down” são pressionadas

jTable1.addRowSelectionInterval(i, i);

E essa é a gabiarra que eu falei acima. Desse modo o sroll não desce junto com a seleção da linha.
Ô probleminha complicado colocar o foco dentro dessa jTable. Por ela estar dentro do jComboBox não encontro uma maneira de setar o foco.
Já estou desconfiando que não tem como fazer isso mesmo, mas como sou pouco experiente, pode ter uma maneira que eu nem sonhe em conhecer. :shock:
Mas desistir nunca. Estarei aqui tentando fazer funcionar e olhando o tópico para ver se alguém ajuda a me salvar!! :?

Criado 17 de dezembro de 2008
Ultima resposta 7 de jan. de 2009
Respostas 5
Participantes 4