Erro na primeira execução

Boas, estou com um problema e já andei ás voltas mas não consigo descobrir o que causa este problema. É o seguinte: Eu criei um programa com uma interface gráfica que pede ao utilizador para escolher o seu sexo, introduzir a idade, altura e peso. Após o utilizador introduzir os dados ele carrega no botão calcular. O botão “calcular”, quando clicado, gera um método que atribui os valores da idade, altura etc… a outras variáveis que irão ser utilizadas numa fórmula. Quando o sexo é masculino, um conjunto de valores é atribuido a variáveis, e quando é feminino outros valores são atribuídos ás mesmas variáveis.

Até aqui tudo bem, o programa recebe a informação, captura os dados necessários para colocar na fórmula e retornar o resultado. Mas não sei porque raio ás vezes ele mostra valores completamente descabidos, por exemplo: “-infinity” e “0.0”. São 3 fórmulas e quase sempre na primeira execução do programa dois resultados estão sempre mal, apenas um está sempre correcto e no entanto a fórmula está implementada da mesma forma. Isto acontece só na primeira execução do programa depois de X tempo. Deverei usar threads? uma vez que ele faz 3 fórmulas ao mesmo tempo…mas ele só retorna o valor depois de feitas as contas…não percebo.

Na primeira vez seu programa esta fazendo uma divisão por zero.
Verifique se a atribuiçao de valores a suas variaveis está correta. Faça um debug da sua aplicaçao.

Uma coisa de cada vez.

Se seu programa está retornando -infinity, verifique se você não está fazendo nenhuma divisão por zero. Você poderia colocar as fórmulas aqui no GUJ?

Quanto a rodar fórmulas ao mesmo tempo, sim, você terá que usar Threads. Você pode fazer isso através de um Runnable e um Join ou, se estiver usando o Java 5, acho que o jeito mais fácil é através da interface Callable, do ExecutorService e de um Future. Você pode ver o exemplo de como fazer isso aqui:
http://www.guj.com.br/posts/list/50321.java#264645

Mas ao carregar no Calcular ele faz a atribuição de valores às variáveis que estavam definidas como 0.

Vejam o código:

Ficheiro gui.java (main)

[code]import java.awt.;
import java.awt.event.
;
import javax.swing.*;

public class gui {

static JFrame janela = new JFrame();
static JButton calc = new JButton(“Calcular”);
static JRadioButton m = new JRadioButton(“Masculino”);
static JRadioButton f = new JRadioButton(“Feminino”);
static ButtonGroup sex = new ButtonGroup();
static JLabel sexo = new JLabel("Sexo: ");
static JLabel idade = new JLabel("Idade: ");
static JLabel altura = new JLabel("Altura: ");
static JLabel altura2 = new JLabel(“Cm”);
static JLabel peso = new JLabel("Peso: ");
static JLabel peso2 = new JLabel(“Kg”);
static JTextField txidade = new JTextField();
static JTextField txaltura = new JTextField();
static JTextField txpeso = new JTextField();

public static void mostrar() {

// Criar e mostrar GUI

janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
janela.setLayout(null);
janela.setSize(255,215);
janela.setResizable(false);
janela.setLocationRelativeTo(null);
sex.add(m);
sex.add(f);
janela.getContentPane().add(m);
janela.getContentPane().add(f);
janela.getContentPane().add(sexo);
sexo.setBounds(10,10,50,15);
m.setBounds(50,10,100,15);
f.setBounds(50,30,100,15);
janela.getContentPane().add(idade);
janela.getContentPane().add(txidade);
idade.setBounds(10,65,50,15);
txidade.setBounds(55,65,32,20);
janela.getContentPane().add(altura);
janela.getContentPane().add(txaltura);
janela.getContentPane().add(altura2);
altura.setBounds(10,95,50,15);
txaltura.setBounds(55,95,32,20);
altura2.setBounds(90,97,50,15);
janela.getContentPane().add(peso);
janela.getContentPane().add(txpeso);
janela.getContentPane().add(peso2);
peso.setBounds(10,125,50,15);
txpeso.setBounds(55,125,45,20);
peso2.setBounds(103,127,100,15);
janela.getContentPane().add(calc);
calc.setBounds(150,150,90,30);
janela.setVisible(true);

}
public static void main(String args[]) {
mostrar();

MouseListener m1 = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
calcular.f1 = 4; // Para o homem
calcular.f2 = 66;
calcular.f3 = 13.7f;
calcular.f4 = 5.0f;
calcular.f5 = 6.8f;
}
};

m.addMouseListener(m1);

MouseListener m2 = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
calcular.f1 = 2; // Para Mulher
calcular.f2 = 665;
calcular.f3 = 9.5f;
calcular.f4 = 1.8f;
calcular.f5 = 4.7f;
}
};

f.addMouseListener(m2);

MouseListener m3 = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
calcular.calcular();
}
};

calc.addMouseListener(m3);
}
}
[/code]

Ficheiro calcular.java

[code]public class calcular {

public static int f1 = 0;
public static int f2 = 0;
public static float f3 = 0.0f;
public static float f4 = 0.0f;
public static float f5 = 0.0f;
public static float pesoid = 0.0f; // Peso ideal
public static float imc = 0.0f; // Indice de massa corporal
public static float neb = 0.0f; // Necessidades energeticas basais

//Peso ideal

public static void calcular() {

float altura = (Float.parseFloat(gui.txaltura.getText()));
float idade = (Float.parseFloat(gui.txidade.getText()));
float altura2 = (Float.parseFloat(gui.txaltura.getText())/100);
float peso = (Float.parseFloat(gui.txpeso.getText()));

float a = altura;
float i = idade;
float p = peso;
float a2 = altura2;

pesoid = (float) (a - 100 - ((a -150) / f1) + ((i-20) /4 ));
System.out.println(pesoid);

//IMC

imc = (float) ( § / (a2*a2) );
System.out.println(imc);

//Neb

neb = (f2 + (f3p) + (f4a) - (f5*i));
System.out.println(neb);
}
}
[/code]

Eu bem gostava de usar threads, mas não compreendo muito bem a matéria e a verdade é que não sei implementar, ou não compreendo a sua implementação, em aplicações. Sei do que se trata mas manipular threads é uma coisa que quero aprender á força. Também não sei se de facto seria necessário recorrer a threads para este caso…o problema só ocorre ás vezes e só na primeira execução.

Obrigado desde já :wink:

Raios! Sr. Fábio uhauhauauauah

Tenta escrever 20.0 em vez de 20, faz isso com todos os literais…

Você não precisa de threads…

Threads é quando você quer rodar várias coisas ao mesmo tempo, ou então, rodar um processo demorado em background, como a fatoração de um número grande num programa GUI. Você clica no botão e aquele código roda em “paralelo”, deixando o usuário livre para mexer em outras partes do programa…

Parcialmente ficou resolvido :slight_smile: mas não sei se vai voltar a dar o erro, tenho de ir testando. Muito obrigado pela vossa ajuda :wink:

Apareceu-me o “bug” de novo. Mas acho que já o resolvi. Reparei que as fórmulas que davam valores erráticos eram as que utilizavam as variáveis f(f1,f2,f3,f4 e f5)…acontece que algumas desses variáveis não estavam definidas como float, talvez tenha sido esse o problema. Entre essa modificação também coloquei a definição das variáveis na classe gui, isto faz com que na execução do programa todas as variáveis fiquem com um valor nulo(0.0f). Espero que agora dê resultado

Espero que tu bem te sucedas! :smiley:

Epá continua com a mesma treta, acho que não posso fazer mais nada senão restruturar todo o programa e fazer de outra maneira, mas não faz sentido nenhum esse “erro”…ainda menos quando só ocorre muito raramente. Reparei que quando compilei as classes que criei foram gerados mais do que dois ficheiros.class. Foram gerados os seguintes ficheiros: gui.class, gui$1.class, gui$2.class, gui$3.class e calcular.class. Porque razão isto acontece? peço desculpa se a pergunta é estúpida, mas ainda sou muito iniciado nestas bandas. Obrigado.

Raios novamente Sr. Fábio! O $ são sub-classes dentro de tua classe! Como as manipuladoras de evento!

Tu usas Eclipse? Ele tem um depurador…

Com o depurador tu depuras o código, e vais a observar com o “watch” o valor de cada variável, a cada linha executada, então poderás capturar o momento exato que os erros ocorrem :smiley:

Pois, eu não uso eclipse… uso apenas o terminal para fazer as compilações e correr. Vou tentar arranjar um depurador, este problema já me está a dar cabo do juízo…se alguma coisa estivesse errada então o programa dava sempre os mesmos valores…mas não, dá uma vez e depois quando fecho e volto a abrir já está tudo direito. Parace que é da VM.

Não entendi Sr. Fábio, você digita as mesma coisas na GUI e os resultados são diferentes? Acaso estais a usar threads, mesmo sem saberes?

Exactamente. Eu explico melhor. Abro o programa, ele mostra a GUI e eu coloco os valores (idade,peso, altura e sexo), clico no botão calcular e ele dá-me os valores errados, posso alterar todos os valores que duas das 3 fórmulas darão sempre o mesmo resultado errado. Se eu fechar o programa e voltar a abrir já fica tudo normal. As fórmulas que retornam o valor errado são as que usam as variáveis ‘f’ cujo seu valor é atribuído consoante o parâmetro sexo no momento em que o botão calcular é clicado. Pois já pensei nisso, realmente poderia ser um erro de threads, mas tive o cuidado de iniciar a gui numa thread em separado e ocorre sempre o mesmo.

Bom, se eu não conseguir resolver isso tenho de reestruturar o programa todo de novo usando outra metodologia para elaborar as fórmulas.