Abrir imagem pelo jFileChooser + MySQL

29 respostas
S

Olá pessoal! É o seguinte:

Trabalho com a IDE NetBeans, onde existe o componente gráfico jFileChooser. Meu programa é um quiz de perguntas e respostas, utilizado pelo professor, para seus alunos.
No jFrame em que o professor inseri perguntas no jogo (e armazena no MySQL), criei uma opção onde ele po inserir uma imagem referente a tal questão.

Ai surge meus problemas:

1º: Não sei como programar o jFileChooser, pois ja pesquisei vários tópicos sobre isso, e não encontrei exatamente o que quero. Queria colocar função nos botões abrir e cancelar;

2º: Queria uma forma de gravar essa imagem no banco, sem a utilização de binário, que é através do caminho da imagem. Pois, toda vez que tal pergunta for mostrada, se existir uma imagem no seu registro, no banco, a mesma também será mostrada junto a pergunta;

3: E por fim, queria que quando a imagem fosse exibida no frame de questão, ela fosse mostrada em um jLabel, que ficara meio que invisivel, onde  será mostrado, quando a pergunta tiver uma imagem.

Por favor pessoal, me ajudem!!!

Grata desde já…

29 Respostas

B

1o - Crie seu JFileChooser como no exemplo:
http://www.exampledepot.com/egs/javax.swing.filechooser/createdlg.html

2o - Use o método copy para copiar a imagem seleciona para um diretório fixo, e grave o nome da imagem no banco. (pode gravar com um nome sequencial para evitar nomes duplicados).
http://www.java2s.com/Code/Java/File-Input-Output/CopyfilesusingJavaIOAPI.htm

3o - Recupere o nome da imagem com o nome, concatene-o com o caminho completo para o diretorio fixo onde ficam todas as images e utilize o código abaixo para setar a imagem na label usando ImageIcon.
*Use o método setIcon e depois chame o setVisible(true) na sua label escondida.
http://www.java2s.com/Code/Java/Swing-JFC/LabelwithImage.htm

S

Mas referente a criação do jFileChooser, eu devo criar uma classe java e colocar o código que vc me passou, ou adicionar esse código, dentro do meu componente swing jFileChooser?

B

Melhor criar uma outra classe, eu já tive problemas com FileChooser do Netbeans.

O Matisse é muito produtivo para aplicativos pequenos, mas quanto mais seu aplicativo cresce mais ele complica :wink:

S

BrunoBastosPJ:
Melhor criar uma outra classe, eu já tive problemas com FileChooser do Netbeans.

O Matisse é muito produtivo para aplicativos pequenos, mas quanto mais seu aplicativo cresce mais ele complica ;)

Ohh, eu consegui montar o filechooser, do jeito que queria na minha aplicação, só que o seguinte:

precisava implementar um código no botão “abrir”, que, o usuário tendo selecionado tal imagem, vai pegar o caminho dessa imagem e jogar num campo especifico do meu banco de dados.

Tem como?

S

Ohh, consegui mandar o siretório pro banco de dados, só q tem um porém: o endereço ta indo sem as barras "\" as que dividem o diretório. Qual será o erro?

private void jButton11ActionPerformed(java.awt.event.ActionEvent evt) {                                          
    // TODO add your handling code here:
    new playerIII();
    try   
        {   
            JFileChooser Image = new JFileChooser(); 
            Image.setCurrentDirectory (new File ("/Meus documentos/Minhas Imagens e Fotos/"));   
            Image.setDialogTitle ("Inserir imagem na pergunta:");      
            int res = Image.showOpenDialog(null);
            if(res == JFileChooser.OPEN_DIALOG)
            {  
               File foto = Image.getSelectedFile();
               String sql = "UPDATE facil SET " +
               "imagem = '"+ foto +"'" +
               "WHERE id = '"+ jTextField7.getText() +"'";
               int r = BD.runSQL(sql);
               new certosom();
               JOptionPane.showMessageDialog(null, "Você escolheu a imagem: " + foto,"Inserir Imagem:",JOptionPane.INFORMATION_MESSAGE); 
            } 
            if(res == JFileChooser.CANCEL_OPTION)
            {
                new fimsom();
                JOptionPane.showMessageDialog(null, "Você não escolheu nenhuma imagem!","Inserir Imagem:",JOptionPane.WARNING_MESSAGE);
            }     
        }   
  
        catch (Exception erro)   
        {   
            JOptionPane.showMessageDialog (null,erro);   
        }  

}
V

Dá uma lida:

S

Mas se eu fizer como pede o site (que pelo que entendi ele transforma a imagem em bytes, pra mandar pro banco, e depois “remonta” a imagem de novo) não deixaria meu banco de dados pessado demais?

S

Porque eu consegui mandar o endereço pro banco, assim como estava precisando, só q ele vai sem o contra-barra “”.

No JOptionPane, mostra o endereço da imagem certinho, mas qndo cai no banco, ele fica sem o contra-barra.

V

Ele não transforma a imagem em bytes. Todos os dados do computador são bytes. No fundo, ele só pega a representação binária dos dados da imagem, mas não existe transformação nesse processo. O mesmo vale no caminho inverso.

Quanto à deixar o banco de dados pesado. Existem vantagens e desvantagens de jogar a imagem no banco:

Vantagens:

a) A imagem passa a sofrer backup junto com o banco;

b) As imagens não ficam jogadas numa pasta do sistema de arquivos;

c) Usuários não tem como acidentalmente apagar a imagem, ou a pasta da imagem;

d) É mais rápido carregar a imagem,  que a consulta do banco a retorna diretamente;

e) É mais fácil mudar o banco de lugar, sem surpresas;
Desvantagens:

a) Não é possível alterar a imagem por fora do software;

b) O arquivo do banco de dados fica grande;

c) A menos que você programe, é mais difícil fazer com que dois registros compartilhem a mesma imagem, economizando espaço.

Se você vai gravar no banco mesmo, ou só deixar o endereço da imagem no banco, fica a teu critério. Leve em consideração o quão importante é essa imagem, e o quão vinculada ao próprio registro ela está.

S

Porque a importância de tal imagem no banco, vai depender do professor, que no caso, é o usuário que vai adicionar esa imagem em determinada pergunta (registro) do banco…

Mas pro meu caso, o q vc me aconselha fazer?

V

O que você achar mais fácil. :slight_smile:

Qual é o seu banco de dados? Se for access, guarde só um link. Ele tem problemas sérios ao ficar muito grande.

S

O que você achar mais fácil. :slight_smile:

Qual é o seu banco de dados? Se for access, guarde só um link. Ele tem problemas sérios ao ficar muito grande.

Eu uso o MySQL. Eu disse sobre a questão de endereço, pois meu professor do curso técnico (que foi meu professor orientador de tcc) me aconselhou a questão de endereçamento da imagem, porque ele disse que se eu transformasse a imagem em bytes (imagens q no me caso, ñ seriam pequenas) seria capaz de transformar meu banco de dados em um monstro em poucos dias… rsrsrsrsrsrs…

V

Se seu professor já deu a recomendação, faça como ele pediu. Realmente, o banco de dados fica grande se você armazenar imagens lá dentro. O tamanho dele ficará igual ao tamanho do banco + o tamanho da pasta onde você irá guardar as imagens.

Enfim, é bom saber que existem ambas as alternativas. Você já conseguiu carregar a imagem através do link dela?

Outra coisa. Não use o Statement concatenando Strings como você fez. No lugar, use o PreparedStatement. Ele tem várias vantagens:

  1. Evita que você tenha que concatenar apostrofes para Strings, ou que tenha que formatar datas para o banco;
  2. Deixa o código mais claro, sem concatenações com sinal de +;
  3. Evita que você tenha que tratar a String do usuário (pois o usuário pode ter digitado um apóstrofe ’ o que quebraria sua SQL);
S

Se seu professor já deu a recomendação, faça como ele pediu. Realmente, o banco de dados fica grande se você armazenar imagens lá dentro. O tamanho dele ficará igual ao tamanho do banco + o tamanho da pasta onde você irá guardar as imagens.

Enfim, é bom saber que existem ambas as alternativas. Você já conseguiu carregar a imagem através do link dela?

Outra coisa. Não use o Statement concatenando Strings como você fez. No lugar, use o PreparedStatement. Ele tem várias vantagens:

  1. Evita que você tenha que concatenar apostrofes para Strings, ou que tenha que formatar datas para o banco;
  2. Deixa o código mais claro, sem concatenações com sinal de +;
  3. Evita que você tenha que tratar a String do usuário (pois o usuário pode ter digitado um apóstrofe ’ o que quebraria sua SQL);

Então, eu não consegui chamar a imagem atraves do banco, por dois motivos:

1- qndo eu mando o endereço pro banco, ele manda sem o contra-barra “” , no caso, o endereço vai todo “emendado”…

2- eu ñ sei como chamar a imagem no jLabel, na verdade, saber como chamar eu sei, só ñ sei q método uso. Por exemplo, qndo chamo uma String uso “getString”. Não sei qual método usar para chamar a imagem…

E sobre esse PreparedStatement, vc diz pra mim usa-lo onde? como?

V

Para inserir uma imagem num JLabel, você usa o método setIcon.

Antes de inserir a imagem no banco, altere a \ para / com o comando replace.

String foto = Image.getSelectedFile().getCanonicalPath().replace("\\", "/");
S
ViniGodoy:
Para inserir uma imagem num JLabel, você usa o método setIcon.

Antes de inserir a imagem no banco, altere a \ para / com o comando replace.

String foto = Image.getSelectedFile().getCanonicalPath().replace("\\", "/");

Então, o endereço consegui mandar certinho pro banco, por essa linha de código que vc me corrigiu...

Mas como q vou chamar o endereço do banco em String, e mandar setar como Icon?

pq o meu código q chama o registro (no caso, uma pergunta) é esse aqui:

public void atualizaCampo(){
    if(BD.getConnection())
               {
                try
                {    
                     String query = "SELECT * FROM facil ORDER BY RAND()";
                     BD.setResultSet(query); 
                     while(BD.resultSet.next())
                     {
                         marca=(BD.resultSet.getInt("marca"));   
                         if (marca<1)
                         { 
                         pergunta=(BD.resultSet.getString("pergunta"));
                         alt1=(BD.resultSet.getString("alt1"));
                         alt2=(BD.resultSet.getString("alt2"));
                         alt3=(BD.resultSet.getString("alt3"));
                         alt4=(BD.resultSet.getString("alt4"));
                         resposta=(BD.resultSet.getString("resposta"));
                         cont=(BD.resultSet.getInt("id"));
                         imagem=(BD.resultSet.getString("imagem"));
                         }
                     }

                }
                catch(java.lang.Exception ex)
                {
                    ex.printStackTrace();
                }
               
               }
}

Então, ai eu chamo a variavel imagem do banco como String, q no caso ai é o endereço da imagem...

Mas como vou setar ele como Icon, se ele é String?

V

Você vai fazer:

seuLabel.setIcon(new ImageIcon(imagem));

O ImageIcon vai carregar aquela imagem e colocar no JLabel.

S

ViniGodoy:
Você vai fazer:

seuLabel.setIcon(new ImageIcon(imagem));

O ImageIcon vai carregar aquela imagem e colocar no JLabel.

Ahhh, deu certo!!! Mto obrigada!!!

Só vou pedir só mais um favor: como deixar meu label tamanho padrao. Assim:

Tenho a imagem tamanho x, e o máximo do meu label é y.
Como faço com que minha imagem x, “caiba” no tamanho y, sem aumentar o tamanho da minha janela?

V

Substituia seu JLabel por um JImagePanel:
http://www.guj.com.br/posts/list/56248.java#295271

O JImagePanel não suporta um ImageIcon como parâmetro de entrada, mas suporta um File.

seuImagePanel.setImage(new File(imagem));

As imagens são automaticamente redimensionadas para ficar do tamanho do painel. Então, basta ajusta-lo no seu Netbeans ou Eclipse.

S

Só q tipo, no meu frame de pergunta ta assim:

meu label ta bem pequeno, ai qndo ele chama a imagem, ele aumenta conforme o tamanho da imagem.

Fiz isso pq ñ qria um espço em branco no frame de pergunta, por questao de estética, entende?

se eu usar essa estrutura q vc me falou, e deixar ele como o label, ele vai aumentar conforme a imagem?

V

Ele redimensiona para a imagem para o tamanho dele.
Outra opção é fazer com que ele centralize a imagem.

O que exatamente você quer?

a) Quando a imagem é menor que o painel;
b) Quando a imagem é maior que o painel;

S

Na verdade seria para os dois quesitos.

V

Sim… estava perguntando o que você quer em cada caso?

S

Sim… estava perguntando o que você quer em cada caso?

Ahh, tah, desculpa minha ignorancia… :oops:

Entao, eu queria q meu jLabel se ajustasse conforme um tamanho máximo d tal imagem, q eu definir pra ele, entende?

Só q se a imagem fosse mto grande, ele ñ cortasse a imagem, mas sim, a reduzisse…

V

E se a imagem fosse muito pequena? Você quer que ela estique, ou que ela fique do tamanho certo, mas no centro?

S

Mas acho q ñ vai precisar mais ñ… Falei hj com me professor, e ele disse q ta certo com jLabel, só q eu vou ter q indicar no meu tópico de ajuda, o tamanho maximo da imagem q o usuário pode add na pergunta.

E, pedindo um último favor, sabe onde coloco estas linhas de formatação do jFileChooser? Eu coloquei no main, mas ñ roda em português. Nem dentro do botão que programei o jFileChooser, ele muda…

UIManager.put( "FileChooser.fileNameLabelText", "Nome do Arquivo:" ); UIManager.put( "FileChooser.acceptAllFileFilterText", "Todos os Arquivos (*.*)" ); UIManager.put( "FileChooser.directoryDescriptionText", "Diretório" ); UIManager.put( "FileChooser.filesOfTypeLabelText", "Arquivos do Tipo:" ); UIManager.put( "FileChooser.openButtonText", "Abrir" ); UIManager.put( "FileChooser.openButtonToolTipText", "Abrir arquivo selecionado" ); UIManager.put( "FileChooser.cancelButtonText", "Cancelar" ); UIManager.put( "FileChooser.cancelButtonToolTipText", "Cancelar diálogo file chooser" ); UIManager.put( "FileChooser.lookInLabelText", "Procurar em:" ); UIManager.put( "FileChooser.detailsViewButtonToolTipText", "Detalhes" ); UIManager.put( "FileChooser.listViewButtonToolTipText", "Lista" ); UIManager.put( "FileChooser.newFolderToolTipText", "Criar nova pasta" ); UIManager.put( "FileChooser.upFolderToolTipText", "Um nível acima" );

A

sobre as imagem no banco sem duvida é melhor armazenar no Data Base.

tanto faz de uma forma ou de outra as fotos vam ser armazenadas, o tamanho
va ser sempre o mesmo.

V

Essas linhas de configuração você põe logo no início do seu main, antes de abrir sua primeira tela do Swing.

S

Obrigada mais uma vez ViniGodoy, realmente, era este o problema… :smiley:

Criado 21 de julho de 2010
Ultima resposta 28 de jul. de 2010
Respostas 29
Participantes 4