@trickstival escreveu:
Oi gente, eu estou com um problemão aqui que não consigo resolver de jeito nenhum.
Bom, eu to usando o ImageIO do Java pra tentar carregar imagens na minha tabela do Javafx, permitindo que eu altere essas imagens. A parte de inserir as imagens e as informações estão dando certo, como podem ver:
Então eu fiz um método no meu Controller pra que quando o usuário clicasse duas vezes num registro da tabela, ele carregasse esse registro em uma outra tela .No caso, a tela Cadastro, que é essa daqui:
(ignorem as imagens desalinhadas)
Então, até aí tudo bem. O meu método de carregamento é esse aqui (Obs: leiam os comentários):
private void carregar() { //descobre qual o pet selecionado Pet selecionado = tabelaPet.getSelectionModel().getSelectedItem(); if (selecionado == null) { return; } //preenche os TextFields pra edição txtNome.setText(selecionado.getNomePet()); txtNomeDono.setText(selecionado.getDono().getNomeDono()); this.selecionado = selecionado.getDono(); txtObs.setText(selecionado.getObservacoes()); txtRaca.setText(selecionado.getRaca()); //formata o valor que veio do banco pra bater com o valor que tá no choicebox (espécie é um enum) String especieString = selecionado.getEspecie().toString().toLowerCase(), primeiroCaracter = new Character(especieString.charAt(0)).toString(); choiceEspecie.setValue(especieString.replaceFirst(primeiroCaracter, primeiroCaracter.toUpperCase())); choicePorte.setValue(selecionado.getPorte()); choiceSocial.setValue(selecionado.getConvivioSocial()); //define as duas imagens que vão ser usadas Image imagemFoto, imagemCarteirinha; try { //esses métodos get uri na realidade não tem uri, eles tem uma string em um formato tipo file:/C:/imagensPet/pastaDaFoto/foto.extensão fotoPetselecionada = new File(selecionado.getUriFoto()); imagemFoto = new Image(selecionado.getUriFoto()); } catch (NullPointerException e) { fotoPetselecionada = null; imagemFoto = null; } try { cadernetaSelecionada = new File(selecionado.getUriCarteirinha()); imagemCarteirinha = new Image(selecionado.getUriCarteirinha()); } catch (NullPointerException e) { imagemCarteirinha = null; cadernetaSelecionada = null; } //o imageCarteirinha e o imageFoto são dois imageViews imageCarteirinha.setImage(imagemCarteirinha); imageFoto.setImage(imagemFoto); //aqui que tá o pulo do gato. Pra diferenciar as inserções das edições dos Pets, eu criei //um campo chamado carregado (que é um Pet). quando esse carregado está nulo, o programa faz inserção //e quando ele está preenchido, o programa faz edição. Vou explicar mais disso no próximo método carregado = selecionado; //aqui é mudada a tela tabPane.getSelectionModel().select(tabCadastro); //essa é uma mensagem que sobe no canto da tela só MensagensNotificacao.mostrarSucesso("Pet carregado"); }
O carregamento acontece normalmente, mas o problema está quando o usuário clica no botão confirmar, pois então é disparado um método chamado cadastrar. Leiam os comentários novamente:
private void cadastrar() { //O método controiPet retorna uma nova instancia de Pet. Vou indexar ele em baixo //desse método cadastrar Pet novo = constroiPet(); //se der algum erro de validação no método constroiPet, ele retorna null, e então a operação é abortada if (novo == null) { return; } //Estamos chegando perto da raiz do problema! O método salvar imagem usa o ImageIO pra ler as imagens postas //em dois campos do tipo File: fotoPetSelecionada e cadernetaSelecionada. No caso, eu estou gerando dois arquivos, //um pra cada if. Vou indexar esse método comentado também. //Obs: esses File.separator são uma barra só. Nos ifs tem também //a condição exists, pra saber se o usuário já não cadastrou aquela foto, não precisando assim gerar um novo arquivo if (novo.getUriFoto() != null && !new File(novo.getUriFoto()).exists()) { salvarImagem(fotoPetselecionada, "C:" + File.separator + "imagensPet" + File.separator + "imagensPerfil" + File.separator); } if (novo.getUriCarteirinha() != null && !new File(novo.getUriCarteirinha()).exists()) { salvarImagem(cadernetaSelecionada, "C:" + File.separator + "imagensPet" + File.separator + "imagensCadernetas" + File.separator); } try { //Aqui que é aplicado aquilo que eu disse do carregado, //que para nulo é inserção e preenchido edição. Quando o usuário clica duas vezes //num registro da tabela, é realizada uma edição if (carregado != null) { //sets carregado.setConvivioSocial(novo.getConvivioSocial()); carregado.setDono(novo.getDono()); carregado.setEspecie(novo.getEspecie()); carregado.setNomePet(novo.getNomePet()); carregado.setObservacoes(novo.getObservacoes()); carregado.setPorte(novo.getPorte()); carregado.setRaca(novo.getRaca()); carregado.setUriCarteirinha(novo.getUriCarteirinha()); carregado.setUriFoto(novo.getUriFoto()); //Aqui é realizado um merge via JPA na base de dados (essa parte está funcionando perfeitamente) petDAO.alterar(carregado); } else { //Aqui é para o caso de inserção (carregado nulo) petDAO.inserir(novo); MensagensNotificacao.mostrarSucesso("Pet de nome " + novo.getNomePet() + " cadastrado com sucesso!"); } //esse método limpa os TextFields e deixa os campos nulos (aqueles Files e o carregado são esses campos) limpar(); //esse método tira todos os itens da tabela e em seguida preenche ela com os valores do banco atualizaTabela(); } catch (Exception e) { FxDialogs.showException("", "", e); MensagensNotificacao.mostrarErro("Erro ao cadastrar o Pet!"); } }
Método salvarImagem (onde ocorre a exceção)
private void salvarImagem(File fotoPetselecionada, String caminho) { //Aqui é o pulo do gato de vez. Vou explicar os parâmetros: //o primeiro é o arquivo que vai ser cadastrado. Como eu disse //antes, são as imagens que são carregadas por um FileChooser. if (fotoPetselecionada == null) { MensagensNotificacao.mostrarErro("Nenhuma foto selecionada para o Pet."); return; } try { //Aqui é assim: peguei uma classe na internet (essa FxDialogs) //pra poder receber as mensagens tipo um sysout. O mais estranho é: //pra algumas imagens... FxDialogs.showInformation("", fotoPetselecionada.toURI().toURL().toString());//<---- esse fotoPetselecionada.toURI().toURL().toString()... //mostra um formato de arquivo e pra outras ele mostra outro formato. //Vou deixar duas imagens com os dois formatos pra vocês tentarem entender o que está acontecendo //aqui é gerada a exceção javax.imageio.IIOException: Can't read input file! BufferedImage img = ImageIO.read(fotoPetselecionada); //Aqui eu pego a extensão do arquivo pra usar no write (é um dos parâmetros) String formato = fotoPetselecionada.getName().substring( fotoPetselecionada.getName().lastIndexOf(".") + 1, fotoPetselecionada.getName().length()); //aqui eu garanto que as pastas estão criadas File path = new File(caminho); path.mkdirs(); //aqui é gerado o arquivo (era pra ser) ImageIO.write(img, formato, new File(caminho + fotoPetselecionada.getName())); } catch (IOException ex) { FxDialogs.showException("", "", ex); MensagensNotificacao.mostrarErro("Erro ao salvar a imagem!"); } }
Vou deixar o método constroiPet aqui caso ajude:
private Pet constroiPet() { if (selecionado == null) { MensagensNotificacao.mostrarErro("Selecione um tutor para cadastrar o Pet."); return null; } //Declarando as variáveis String nomePet = txtNome.getText(), porte = choicePorte.getValue(), convivioSocial = choiceSocial.getValue(), raca = txtRaca.getText(), uriCarteirinha = null, observacoes = txtObs.getText(), uriFoto = null, especieString = choiceEspecie.getValue(); //verificando se as URLs das fotos são válidas if (fotoPetselecionada != null) { try { uriFoto = new File("C:" + File.separator + "imagensPet/imagensPerfil/" + fotoPetselecionada.getName()).toURI().toURL().toExternalForm(); } catch (MalformedURLException ex) { MensagensNotificacao.mostrarErro("Caminho especificado para a foto do Pet é inválidos."); } } if (cadernetaSelecionada != null) { try { uriCarteirinha = new File("C:/i" + "magensPet/imagensCadernetas/" + cadernetaSelecionada.getName()).toURI().toURL().toExternalForm(); } catch (MalformedURLException ex) { MensagensNotificacao.mostrarErro("Caminho especificado para a foto da caderneta de vacinação é inválido."); } } //verificando se algum dos campos está vazio if (raca == null) { raca = "Nenhuma Especificada"; } if (nomePet == null) { MensagensNotificacao.mostrarErro("Informe o nome do Pet a ser cadastrado."); return null; } //transformando espécie string em enum Especie especie = Especie.OUTRO; if (especieString.equals("Gato")) { especie = Especie.GATO; } else if (especieString.equals("Cão")) { especie = Especie.CÃO; } return new Pet(selecionado, nomePet, porte, convivioSocial, raca, especie, uriCarteirinha, observacoes, uriFoto); }
Vou fazer um passo a passo do que acontece em imagens:
1-) Abre o menu de Pets
2-) Clica duas vezes e seleciona um pet
3-) Mudando as fotos
4-)Caminho da primeira imagem:
5-) Caminho da segunda imagem:
6-) Até aí tudo bem, porque eu mudei as duas imagens. Agora vou mudar uma só:
7-) Aqui está aquele formato estranho da URL, que tem dois file:/ (em nenhum momento isso é especificado por mim)!
Exceção gigantesca gerada:
javax.imageio.IIOException: Can't read input file! at javax.imageio.ImageIO.read(ImageIO.java:1301) at trickstival.CadastroPetsController.salvarImagem(CadastroPetsController.java:404) at trickstival.CadastroPetsController.cadastrar(CadastroPetsController.java:284) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771) at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Node.fireEvent(Node.java:8411) at javafx.scene.control.Button.fire(Button.java:185) at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$355(GlassViewEventHandler.java:388) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387) at com.sun.glass.ui.View.handleMouseEvent(View.java:555) at com.sun.glass.ui.View.notifyMouse(View.java:937) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191) at java.lang.Thread.run(Thread.java:745)
Resultado ao carregar o mesmo Pet novamente:
A foto sumiu!!!
Olhando no banco:
A imagem continua!
Mas mesmo reiniciando a aplicação, a imagem não é carregada.Por favor me ajudem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Mensagens: 3
Participantes: 2