Abrir imagem pelo jFileChooser + MySQL

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 só será mostrado, quando a pergunta tiver uma imagem.

Por favor pessoal, me ajudem!!!

Grata desde já…

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

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?

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:

[quote=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 ;)[/quote]

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?

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?

[code] 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);   
    }  

} [/code]

Dá uma lida:

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?

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.

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, já 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á.

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?

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.

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.[/quote]

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…

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);

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);

[/quote]

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?

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("\\", "/");

[quote=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:

[code]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();
            }
           
           }

} [/code]

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?

Você vai fazer:

seuLabel.setIcon(new ImageIcon(imagem));

O ImageIcon vai carregar aquela imagem e colocar no JLabel.

[quote=ViniGodoy]Você vai fazer:

seuLabel.setIcon(new ImageIcon(imagem));

O ImageIcon vai carregar aquela imagem e colocar no JLabel.[/quote]

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?

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.