jList com ícones de acordo com o caminho do banco de dados e com ação

2 respostas
marcosarantesj

Já tenho um código para adicionar ícones no jList. É usado um jPane(painel) e um jLabel. O jLabel é adicionado dentro do jPane e o jPane é adicionado ao jList. O problema é que deveria ser criado vários jPane de acordo com a quantidade de registros do banco de dados. Depois seria mostrado no jList o ícone da extensão com o caminho do arquivo. O problema é que não consegui adicionar varios jPane de acordo com a quantidade de registro do banco de dados. Ex: No banco de dados tenho 2 registros,cada registro tem um caminho do banco de dados. Queria que fosse criado vários jPane de acordo com a quantidade de registros.
Primeiro registro: C:\Users\MARK\Documents\Carteirinha dos Alunos de Música.doc
Segundo registro: C:\Users\MARK\Documents\carteirinha do leitor2.pdf
Podem ter mais registros também. Olhe o código que tenho

class CustomCellRenderer implements ListCellRenderer {
   public Component getListCellRendererComponent(
JList list, Object value, int index,
    boolean isSelected,boolean cellHasFocus) {
     Component component = (Component)value;
     component.setBackground(isSelected ? Color.yellow : Color.white);
     return component;
     }
   }

Esse abaixo é uma função criada que depois será chamada.Abaixo faço um loop no banco de dados para retornar os registros de acordo com o no filho clicado. O problema é que só criei um jPanel e um jLabel e por isso só estou podendo exibir ao invés de 2 ou mais ícones no jList. o jPane e jLabel devia ser criado comnomes diferentes de acordo com a quantidade ele ia mudando o nome do jPane e jLabel.

private void MostraDadosdaInfo() {
         
        listModel.removeAllElements();
   
        banco = new DB();
        banco.connect();
        Query query1 = new Query(banco.conn);
        Query Anexos = new Query(banco.conn);
        String sql = "SELECT descricao FROM info "
                + "WHERE titulo='" + noSelecionado + "'";
        String sqlAnexos = "SELECT anexos.anexo FROM anexos,info WHERE info.titulo='"
                +noSelecionado +"' AND anexos.info_codigo=info.codigo";
        query1.open(sql);
        Anexos.open(sqlAnexos);
        String anexo;
        String descricao;
  
         while (query1.next()) {
            descricao = query1.fieldbyname("descricao");
            jTextPane1.setText(descricao);
        }
  
                          
       File arq;
      JLabel label = null;
     
//        //Preenche a jList de anexos
        while (Anexos.next()) {
            anexo = Anexos.fieldbyname("anexo");
     jp1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
            arq = new File(anexo);
//            //Pega o ícone do arquivo
//FileSystemView.getFileSystemView().getSystemIcon(arq);
jp1.add(new JLabel(FileSystemView.getFileSystemView().getSystemIcon(arq)));
            try {
                jp1.add(new JLabel(arq.getCanonicalPath()));
                //
            } catch (IOException ex) {
                Logger.getLogger(ifrmSplitPane.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

jList1.setCellRenderer(new CustomCellRenderer());
     listModel.addElement(jp1);
  jList1.setModel(listModel);




    }

Esse abaixo vai no evento jList1MouseClicked

if(evt.getSource()==jp1){
                       //if(jList1.getSelectedIndex()>-1 && evt.getClickCount()==2){
            try {
                Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL "+jList1.getSelectedValue().toString());
            } catch (IOException ex) {
                Logger.getLogger(ifrmCadInfo.class.getName()).log(Level.SEVERE, null, ex);
            }
   }

O outro problema seria que depois de carregado os arquivos em anexo com ícone no jList, o usuário selecionaria um e clicaria nele e abriria o arquivo selecionado. Já tenho o código para abrir o arquivo selecionado. Agora só falta saber o evento via código. Deve ser algo como ActionEvent ou mouseClicked, mas também tem que ser criado outros jPane que pode ser 1,2 ou mais de acordo com a quantidade de regitros do banco de dados e depois clica em uma célula no jList e abre o arquivo selecionado.

2 Respostas

marcosarantesj

Consegui resolver a parte do loop que preenche todos os dados. o que estava errado mesmo é que eu deveria ter colocado
listModel.addElement(jp1); dentro do loop.
Segue o código certo então.

private void MostraDadosdaInfo() {

        //remove os ítens do listModel, no caso tem que remover mesmo do jPanel
        listModel.removeAllElements();

        //Remover todos os ícones do jList (está dentro do jPanel)
        jPanel1.removeAll();
        banco = new DB();
        banco.connect();
        Query query1 = new Query(banco.conn);
        Query Anexos = new Query(banco.conn);
        String sql = "SELECT descricao FROM info "
                + "WHERE titulo='" + noSelecionado + "'";
        String sqlAnexos = "SELECT anexos.anexo FROM anexos,info WHERE info.titulo='"
                + noSelecionado + "' AND anexos.info_codigo=info.codigo";
        query1.open(sql);
        Anexos.open(sqlAnexos);
        String anexo;
        String descricao;

        while (query1.next()) {
            descricao = query1.fieldbyname("descricao");
            //Formata o texto
//            nome = nome.replaceAll("<br>", "\n").replaceAll("<br>", "");
//            nome = nome.replaceAll("<p>", "\t").replaceAll("<p>", "");

            jTextPane1.setText(descricao);
        }
        ArrayList vetor = new ArrayList();

        File arq = null;

//        //Preenche a jList de anexos
        while (Anexos.next()) {
            anexo = Anexos.fieldbyname("anexo");
            jp1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
            arq = new File(anexo);

//            //Pega o ícone do arquivo
            jp1.add(new JLabel(FileSystemView.getFileSystemView().getSystemIcon(arq)));
            try {
                jp1.add(new JLabel(arq.getCanonicalPath()));
                //
            } catch (IOException ex) {
                Logger.getLogger(ifrmSplitPane.class.getName()).log(Level.SEVERE, null, ex);
            }
listModel.addElement(jp1);

        }

        jList1.setCellRenderer(new CustomCellRenderer());

        jList1.setModel(listModel);

    }

Agora só falta mesmo eu definir o evento do click. Quando eu clicar 2x em uma determinada célula no jList, irá abrir o arquivo referente ao path.

Esses arquivos são apenas um exemplo. O usuário vai cadastrar mesmo o que ele quiser e anexar e depois procurar.

marcosarantesj

A parte do código que faltava agora já foi resolvida. Segue abaixo no evento click do jList.

private void jList1MouseClicked(java.awt.event.MouseEvent evt) {                                    
  
        if(jList1.getSelectedIndex()>-1 && evt.getClickCount()==2){
             int index = jList1.locationToIndex(evt.getPoint());
             ListModel dlm = jList1.getModel();
             Object item = dlm.getElementAt(index);
             jList1.ensureIndexIsVisible(index);

             JPanel jp = (JPanel) item;
             Component[] c = jp.getComponents();
            JLabel jl = (JLabel)c[1];
            

            try {
                Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL "+jl.getText());
            } catch (IOException ex) {
                Logger.getLogger(ifrmCadInfo.class.getName()).log(Level.SEVERE, null, ex);
            }
     
   }

Agora sim abre o arquivo clicado corretamente. É claro que dependendo do arquivo, é necessário permissões especiais, mas para arquivos comuns abre normalmente.
Agora vou postar todo o código abaixo que é a maneira mais simples de fazer e com um ótimo visual como dá para ver na resposta anterior.

Primeiro crie a classe que implementa o jList. Criei na mesma tela do programa mesmo.

class CustomCellRenderer implements ListCellRenderer {

        public Component getListCellRendererComponent(
                JList list, Object value, int index,
                boolean isSelected, boolean cellHasFocus) {
            Component component = (Component) value;
            component.setBackground(isSelected ? Color.yellow : Color.white);
            return component;
        }

Agora crie uma função que percorre o banco de dados e então adiciona os elementos no jList na mesma tela do programa se quiser.

private void MostraDadosdaInfo() {

        //remove os ítens do listModel, no caso tem que remover mesmo do jPanel
        listModel.removeAllElements();

        //Remover todos os ícones do jList (está dentro do jPanel)
        jPanel1.removeAll();
        banco = new DB();
        banco.connect();
        Query query1 = new Query(banco.conn);
        Query Anexos = new Query(banco.conn);
        String sql = "SELECT descricao FROM info "
                + "WHERE titulo='" + noSelecionado + "'";
        String sqlAnexos = "SELECT anexos.anexo FROM anexos,info WHERE info.titulo='"
                + noSelecionado + "' AND anexos.info_codigo=info.codigo";
        query1.open(sql);
        Anexos.open(sqlAnexos);
        String anexo;
        String descricao;

        while (query1.next()) {
            descricao = query1.fieldbyname("descricao");
            jTextPane1.setText(descricao);
        }
        ArrayList vetor = new ArrayList();

        File arq = null;

//        //Preenche a jList de anexos
        while (Anexos.next()) {
            anexo = Anexos.fieldbyname("anexo");
            jp1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
            arq = new File(anexo);

//            //Pega o ícone do arquivo
            jp1.add(new JLabel(FileSystemView.getFileSystemView().getSystemIcon(arq)));
            try {
                jp1.add(new JLabel(arq.getCanonicalPath()));
                //
            } catch (IOException ex) {
                Logger.getLogger(ifrmSplitPane.class.getName()).log(Level.SEVERE, null, ex);
            }
           
listModel.addElement(jp1);

        }

        jList1.setCellRenderer(new CustomCellRenderer());

        jList1.setModel(listModel);

    }

Agora colocar no evento MouseClicked do jList o código abaixo

private void jList1MouseClicked(java.awt.event.MouseEvent evt) {                                    
  
        if(jList1.getSelectedIndex()>-1 && evt.getClickCount()==2){
             int index = jList1.locationToIndex(evt.getPoint());
             ListModel dlm = jList1.getModel();
             Object item = dlm.getElementAt(index);
             jList1.ensureIndexIsVisible(index);

             JPanel jp = (JPanel) item;
             Component[] c = jp.getComponents();
            JLabel jl = (JLabel)c[1];
            

            try {
                Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL "+jl.getText());
            } catch (IOException ex) {
                Logger.getLogger(ifrmCadInfo.class.getName()).log(Level.SEVERE, null, ex);
            }
          }

    }

Agora defina como variáveis públicas

private DefaultListModel listModel = new DefaultListModel();
    JPanel jp1 = null;

Somente isso.
Se o moderador quiser deixar isso para muitos que tem dúvidas, este acima é um exemplo completo e muito fácil, sem erro algum. Lembrando que pego os dados de duas tabelas, mas somente na tabela anexo é que preencho o jList baseado no nó que clico no jTree.

Criado 28 de novembro de 2010
Ultima resposta 29 de nov. de 2010
Respostas 2
Participantes 1