Ajuda no debug de um código com herança

Gostaria de uma ajuda para debugar um código que fiz hoje.

Por alto é uma herança entre a superclasse Mamifero e uma subclasse Macaco. A seguir o código e ao final a dificuldade.

Classe Mamifero

public class Mamifero {
	
	protected int idadeAmamentacao;
	protected int idadeVida;
	protected String descricaoEspecie;
	protected long tamanhoNormal;
	
	public Mamifero () {
	}
}

Classe Macaco

public class Macaco extends Mamifero {
	
	private String porte;
	
	public Macaco() {		
		this.idadeAmamentacao = (Integer.parseInt(Leitura.janelaEntrada("Entre com a idade de amamentação do animal", "Amamentação")));
		this.idadeVida = (Integer.parseInt(Leitura.janelaEntrada("Entre com a idade de vida do animal", "Idade")));
		this.descricaoEspecie = Leitura.janelaEntrada("Entre com a descrição do animal", "Descrição");
		this.tamanhoNormal = (Long.parseLong(Leitura.janelaEntrada("Entre com o tamanho normal do animal", "Tamanho")));
		this.setPorte((Leitura.janelaEntrada("Entre com o porte do animal", "Porte")));;
	}

	public String getPorte() {
		return porte;
	}

	public void setPorte(String porte) {
		this.porte = porte;
	}
}

Main

import java.util.ArrayList;


public class Principal {

	public static void main(String[] args) {
		boolean loop = false;
		ArrayList<Mamifero> cadastro = new ArrayList<Mamifero>();
		
		
		System.out.println("Cadastrando macaco");
		Macaco macaco = new Macaco();
		cadastro.add(macaco);
		
		
		//  AQUI DENTRO INSTANCIAR O OBJETO MACACO NÃO ABRE AS TELAS JOPTIONPANE SÓ ACIMA.
		
		/*
		do {
			int opcao = Leitura.lerOpcao();
			switch (opcao) {
			case 1: {
				System.out.println("Cadastrando macaco");
				Macaco macaco = new Macaco();
				cadastro.add(macaco);
				loop=false;
			}				
			}
		} while (loop==true);
		*/	
		
		
		
		System.out.println(cadastro.get(0).descricaoEspecie);
	}
}

Classe Leitura

import java.util.Scanner;

import javax.swing.JOptionPane;

public class Leitura {
	
	public static String janelaEntrada (String mensagem, String titulo) {
		String entrada = JOptionPane.showInputDialog(null, mensagem, titulo, JOptionPane.QUESTION_MESSAGE);
		return entrada;
	}
	
	public static Integer lerInt () {
		Scanner ler = new Scanner(System.in);
		return ler.nextInt();					
	}
	
	public static Integer lerOpcao () {
		boolean loop = false;
		int opcao = 0;
		do {
			try {
				opcao = lerInt();
				loop = Validacao.isOpcao(opcao);
			} catch (java.util.InputMismatchException ime) {
				System.out.println("\nDigite apenas um número !\n");
				System.out.print("Entre novamente com a opção : ");
				loop = true;
			}
		} while(loop==true);
		return opcao;
	}
}

Classe Validação

public class Validacao {
	
	public static boolean isOpcao (int opcao) {
		if (opcao==1||opcao==2||opcao==3||opcao==4)
			return false;
		else {
			System.out.println("\nOpcão inválida !\n");
			System.out.print("Entre novamente com a opção : ");
			return true;
		}			
	}
}

Na classe Principal crio uma instância do objeto macaco e as telas do JOptionPane aparecem solicitando os dados. Ao comentar esse trecho do código e retirar os comentários do trecho com loop do e switch case, a instanciação da classe Macaco exibe as telas do JOptionPane.

Alguém poderia me dar uma luz ?

ps. Na validação existem outras opções de um menu que apresento para cadastrar outros objetos como baleia e elefante mas foquei em macaco pois acredito que quando resolver é só replicar a solução.

Muito obrigado !

Opa ja obtive um retorno sobre o acoplamento forte na utilização dos métodos de leitura no construtor da classe.

Mesmo assim gostaria de um retorno do porquê os métodos que usam JOptionPane não estão “funcionando”.

Obrigado !

Nao sei se te entendi direito, sou novato também, mas se não to enganado, tu tá instanciando duas vezes a classe macaco.

linhas 11, 12 e 13

System.out.println("Cadastrando macaco"); Macaco macaco = new Macaco(); cadastro.add(macaco);

e também está instanciando ela no do while, por isso quando você tira as linhas de comentario, ele dá o erro e não chama o JOpitonpane.
É isso? Se nao for, esquece meu comentário kkkkk

O problema é o seguinte:

switch (opcao) { 
    case 1: { // Só entra no código abaixo se opcao == 1
        System.out.println("Cadastrando macaco"); 
        ...
   }                
} while (loop==true);

// O método "lerOpcao()" fica no laço enquanto isOpcao retornar FALSE
do {  
    try {  
        opcao = lerInt();  
        loop = Validacao.isOpcao(opcao);  
    } catch (java.util.InputMismatchException ime) {  
        ...
    }  
} while(loop==true);  

// Porém, o método "isOpcao()" só retorna TRUE se opcao != de 1, 2 ou 3
public static boolean isOpcao (int opcao) {  
        if (opcao==1||opcao==2||opcao==3||opcao==4)  
            return false;  
        else {  
            System.out.println("\nOpcão inválida !\n");  
            System.out.print("Entre novamente com a opção : ");  
            return true;  
        }             
    }

Resumindo, enquanto vc estiver digitando o número 1 (que entra no seu código para instanciar Macaco) o loop vai ficar rodando pq seu método isOpcao retorna FALSE, não deveria ser o contrário? Reveja sua lógica q vai dar certo!

[quote=fabiocortolan]O problema é o seguinte:

// O método "lerOpcao()" fica no laço enquanto isOpcao retornar FALSE
do {  
    try {  
        opcao = lerInt();  
        loop = Validacao.isOpcao(opcao);  
    } catch (java.util.InputMismatchException ime) {  
        ...
    }  
} while(loop==true);  

[/quote]

Fábio obrigado pela observação mas o método ler opção só vai ficar em loop quando loop for true e eu fiz o retorno do validaOpcao ser false quando as opções forem as corretas justamente para não entrar em loop o lerOpcao …

Eu fiz uns testes com println e não percebi o erro … faz sentido ou eu não estou vendo algo ?

Muito obrigado !

[quote=gpeixoto]
Fábio obrigado pela observação mas o método ler opção só vai ficar em loop quando loop for true e eu fiz o retorno do validaOpcao ser false quando as opções forem as corretas justamente para não entrar em loop o lerOpcao …

Eu fiz uns testes com println e não percebi o erro … faz sentido ou eu não estou vendo algo ?

Muito obrigado ![/quote]

Foi mal, falha nossa! Acho q estou trabalhando d+ kkkk!

Acabei de testar sua aplicação com calma, aki rodou normalmente sem nenhuma alteração, removi o comentário q vc fez e a única coisa q encontrei de estranho foi que vc não colocou nenhuma mensagem para selecionar a opção, só sabemos quando temos q digitar qdo percebemos q o sistema parou.
De qualquer forma o restante está funcionando. Já tentou debugar p/ ver onde ele pára de rodar?

Ah cara tranquilo acontece :slight_smile:

Olha consegui debugar até onde para mas não entendo o que acontece …

O programa executa até esta linha :

this.idadeAmamentacao = (Integer.parseInt(Leitura.janelaEntrada("Entre com a idade de amamentação do animal", "Amamentação")));

Ao tentar construir o macaco …

Percebi que ele chama roda o construtor padrão de mamifero e quando vai executar o do macaco para na primeira linha.

Sobre não ter mensagens informativas sobre o menu é porquê havia mas deletei executando alguns testes e não retornei com elas :frowning:

Mas uma vez obrigado pela ajuda Fábio !

Ah … dei uma lida sobre o debug do Eclipse e adicionei o breakpoint na linha acima …

Achei interessante que na janela de debug mostra o seguinte :

Thread [AWT-Shutdown] (Running)
Daemon Thread [AWT-Windows] (Running)
Thread [AWT-EventQueue-0] (Running)

Então meio que por alto ele chega a tentar abrir uma janela gráfica mas nada aparece ?

Cara, não sei se vai funcionar pois não sei se o JOptionPane lança alguma excessão, mas tente colocar um bloco try catch no código q abre o JOptionPane, se lançar alguma excessão posta p/ gente ver:

public static String janelaEntrada (String mensagem, String titulo) {  
    try {
        String entrada = JOptionPane.showInputDialog(null, mensagem, titulo, JOptionPane.QUESTION_MESSAGE);  
        return entrada;  
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}