Rozbudowanie programu do obliczania BMI

Rozbudowanie programu do obliczania BMI
KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Warszawa
  • Postów: 1683
1

@Adii69 to jest mała aplikacja, więc jest średnim przykładem. Normalnie to implementujesz sobie logikę i widokowi wystawiasz np. jakiś serwis
BMIService z metodą count, która rzuca wyjątki walidacji. Jak poznasz podstawy to poczytaj o wzorcach projektowych.

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Dlaczego w bloku try po lewej stronie przypisania są tWiek, tWaga i tWzrost? Jest oczywiste, że powinny być wiek, waga i wzrost.

Kopiuj
               int wiek = 0;
               double wzrost = 0.0;
               double waga = 0.0;
               boolean ok = true;
               try
               {
                   tWiek = Integer.parseInt(tWiek.getText().trim());
                   tWaga = Double.parseDouble(tWaga.getText());
                   tWzrost = Double.parseDouble(tWzrost.getText());
               }
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0
Kopiuj
	           {
	               wiek = Integer.parseInt(tWiek.getText().trim());
	               waga = Double.parseDouble(tWaga.getText());
	               wzrost = Double.parseDouble(tWzrost.getText());
	           }

Przy tych 3 mam taki błąd:

Kopiuj
Multiple markers at this line: - Cannot invoke getText() on the primitive type int - wiek cannot be resolved to a variable

dodanie znacznika <code class="none"> - @furious programming

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
1

Tutaj

Kopiuj
public class menuGlowne extends JFrame implements ActionListener
{
    private JTextField tImie, tWiek, tWzrost, tWaga, tWynik;

zdefiniowałeś pola tWiek,tWaga i tWzrost typu JTextField. Z komunikatu błędu wynika, że zdefiniowałeś też zmienne lokalne typu int o takich samych nazwach. A zmienne lokalne przesłaniają pola.

A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0
Kopiuj
package rozbudowaneBMI;
import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class menuGlowne extends JFrame implements ActionListener
{
	private JTextField tImie, tWiek, tWzrost, tWaga, tWynik;
	private JLabel lImie, lWiek, lWzrost, lWaga, lWynik, lCm, lKg, loutput;
	private JButton bWyjście, bOblicz;
	private JTextArea output = new JTextArea(6,30);
	
	
	public menuGlowne()
	{
		setSize(800,500);
		setTitle("Kalkulator indeksu BMI");
		setLayout(null);
		
		lImie = new JLabel("Podaj swoje imię", JLabel.RIGHT);
		lImie.setBounds(30, 60, 100, 50);
		tImie = new JTextField();
		tImie.setBounds(200, 70, 150, 30);
			
		lWiek = new JLabel("Podaj swój wiek ", JLabel.RIGHT);
		lWiek.setBounds(30, 110, 100, 50);
		tWiek = new JTextField();
		tWiek.setBounds(200, 120, 150, 30);
		
		lWzrost = new JLabel("Podaj swój wzrost    ", JLabel.RIGHT);
		lWzrost.setBounds(30, 160, 120, 50);
		tWzrost = new JTextField();
		tWzrost.setBounds(200, 170, 150, 30);
		
		lWaga = new JLabel("Podaj swoją wagę    ", JLabel.RIGHT);
		lWaga.setBounds(30, 220, 120, 50);
		tWaga = new JTextField();
		tWaga.setBounds(200, 230, 150, 30);
		
		
		loutput = new JLabel("Wynik:", JLabel.RIGHT);
		loutput.setBounds(339, 10, 100, 100);
		output = new JTextArea();
		output.setEditable(false);
		output.setBounds(400, 80, 300, 200);
		
		
		lCm = new JLabel("cm", JLabel.RIGHT);
		lCm.setBounds(30, 160, 340, 50);
		lKg = new JLabel("kg", JLabel.RIGHT);
		lKg.setBounds(30, 220, 336, 50);
		
		
		add(lImie);
		add(tImie);
		add(tWiek);
		add(lWiek);
		add(tWzrost);
		add(lWzrost);
		add(lCm);
		add(lKg);
		add(lWaga);
		add(tWaga);
		add(output);
		add(loutput);
	
		bOblicz = new JButton("Oblicz BMI");
		bOblicz.setBounds(250, 300, 100, 50);
		bOblicz.addActionListener(this);
		
		bWyjście = new JButton("Wyjście z programu");
		bWyjście.setBounds(550, 380, 200, 60);
		bWyjście.addActionListener(this);
		
		
		add(bOblicz);
		add(bWyjście);
		
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		Object źródło = e.getSource();
		if (źródło==bWyjście)
		{
			dispose();
		}
		else if (źródło==bOblicz)
		{
			
		
		}
	}
	
	
	
	public static void main(String[] args) 
	
	{
	
		menuGlowne app = new menuGlowne();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		app.setVisible(true);          	   	
		
	}
	
	class Liczydlo implements ActionListener
	   {
	       public void actionPerformed(ActionEvent ae)
	       {
	           output.setText("");
	           String answer = "";
	           int wiek = 0;
	           double wzrost = 0.0;
	           double waga = 0.0;
	           boolean ok = true;
	           try
	           {
	               wiek = Integer.parseInt(tWiek.getText().trim());
	               waga = Double.parseDouble(tWaga.getText());
	               wzrost = Double.parseDouble(tWzrost.getText());
	           }
	           catch(Exception e)
	           {
	               ok = false;
	           }
	           if(ok)
	           {
	               double bmi = (waga/Math.pow(wzrost/100,2));
	               output.setText("Twój indeks BMI = "+bmi);
	           }
	           else
	           {
	               output.setText(tImie.getText()+" głupoty piszesz");
	           }
	       }
	   }       
	}

stanąłem w tym miejscu, wszystko niby się zgadza ale jak teraz zrobić żeby po przyciśnięciu przycisku program wykonał obliczenie BMI?

próbowałem coś tutaj działać ale nic nie wychodziło

Kopiuj
		else if (źródło==bOblicz)
		{
			
		
		}
	}
bogdans
  • Rejestracja: dni
  • Ostatnio: dni
1

Jeśli masz tak:

Kopiuj
bOblicz.addActionListener(this);

to klasa Liczydlo jest zbyteczna, przepisz kod jej metody actionPerformed

Kopiuj
        else if (źródło==bOblicz)
        {
                // <- tu
 
        }

Możesz też zrobić tak jak jest w moim kodzie

Kopiuj
bOblicz.addActionListener(new Liczydlo());

wtedy fragment

Kopiuj
        else if (źródło==bOblicz)
        {
 
 
        }

jest niepotrzebny.

A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

Tak wygląda póki co programik:

user image

a oto kod:

Kopiuj
package rozbudowaneBMI;
import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class menuGlowne extends JFrame implements ActionListener
{
	private JTextField tImie, tWiek, tWzrost, tWaga, tWynik;
	private JLabel lImie, lWiek, lWzrost, lWaga, lWynik, lCm, lKg, loutput, lInfo;
	private JButton bWyjście, bOblicz ,bNorma;
	private JTextArea output = new JTextArea(6,30);
	
	
	public menuGlowne()
	{
		setSize(800,500);
		setTitle("Kalkulator indeksu BMI");
		setLayout(null);
		
		lImie = new JLabel("Podaj swoje imię:", JLabel.RIGHT);
		lImie.setBounds(30, 60, 100, 50);
		tImie = new JTextField();
		tImie.setBounds(200, 70, 150, 30);
			
		lWiek = new JLabel("Podaj swój wiek: ", JLabel.RIGHT);
		lWiek.setBounds(30, 110, 100, 50);
		tWiek = new JTextField();
		tWiek.setBounds(200, 120, 150, 30);
		
		lWzrost = new JLabel("Podaj swój wzrost:    ", JLabel.RIGHT);
		lWzrost.setBounds(30, 160, 120, 50);
		tWzrost = new JTextField();
		tWzrost.setBounds(200, 170, 150, 30);
		
		lWaga = new JLabel("Podaj swoją wagę:    ", JLabel.RIGHT);
		lWaga.setBounds(30, 220, 120, 50);
		tWaga = new JTextField();
		tWaga.setBounds(200, 230, 150, 30);
		
		
		loutput = new JLabel("Wynik:", JLabel.RIGHT);
		loutput.setBounds(339, 10, 100, 100);
		output = new JTextArea();
		output.setEditable(false);
		output.setBounds(400, 80, 300, 200);
		
		lInfo = new JLabel("Kalkulator BMI v1.1", JLabel.HEIGHT);
		lInfo.setBounds(650, 400, 130, 100);
		
		
		lCm = new JLabel("cm", JLabel.RIGHT);
		lCm.setBounds(30, 160, 340, 50);
		lKg = new JLabel("kg", JLabel.RIGHT);
		lKg.setBounds(30, 220, 336, 50);
		
		
		
		
		add(lImie);
		add(tImie);
		add(tWiek);
		add(lWiek);
		add(tWzrost);
		add(lWzrost);
		add(lCm);
		add(lKg);
		add(lWaga);
		add(tWaga);
		add(output);
		add(loutput);
		add(lInfo);
		
		
	
		bOblicz = new JButton("Oblicz BMI");
		bOblicz.setBounds(250, 300, 100, 50);
		bOblicz.addActionListener(this);
		
		bWyjście = new JButton("Wyjście z programu");
		bWyjście.setBounds(550, 380, 200, 60);
		bWyjście.addActionListener(this);
		
		bNorma = new JButton("Podaj normę");
		bNorma.setBounds(250, 360, 150, 50);
		bNorma.addActionListener(this);
				
		
		
		add(bOblicz);
		add(bWyjście);
		add(bNorma);
		
		
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		Object źródło = e.getSource();
		if (źródło==bWyjście)
		{
			dispose();
		}
		else if (źródło==bOblicz)
		{
			bOblicz.addActionListener(new Liczydlo());	
		}
		else if (źródło==bNorma)
		{
			output.setText("Indeks BMI powinień oscylować w \nprzedziale od 18 do 25 punktów. \n \n Wynik poniżej 18 punktów oznacza niedowagę. "
					+ "\n Wynik powyżej 25 punktów oznacza nadwagę."
					+ "\n \n Jeżeli wynik znacznie odbiega od normy, \n należy jak najszybciej skontaktować się z lekarzem.");
		}
	}
	
	public static void main(String[] args) 
	
	{
	
		menuGlowne app = new menuGlowne();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		app.setVisible(true);          	   			 
		
	}
	
	class Liczydlo implements ActionListener
	   {
	       public void actionPerformed(ActionEvent ae)
	       {
	           output.setText("");
	           String answer = "";
	           int wiek = 0;
	           double wzrost = 0.0;
	           double waga = 0.0;
	           boolean ok = true;
	           try
	           {
	               wiek = Integer.parseInt(tWiek.getText().trim());
	               waga = Double.parseDouble(tWaga.getText());
	               wzrost = Double.parseDouble(tWzrost.getText());	         
	           }	       
	           catch(Exception e)
	           {
	               ok = false;
	           }
	           if(ok)
	           {
	               double bmi = (waga/Math.pow(wzrost/100,2));
	               if(bmi<16)
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
		            	   		+ "Twój indeks BMI jest skrajnie niski. \n Koniecznie skonsultuj się z lekarzem!");
	               }
	            	   
	               else if(bmi<18)
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
	            	   		+ "Niestety Twój indeks BMI jest za niski. \n Zmień tryb życia oraz zacznij się lepiej odżywiać!");
	               }
	               else if (bmi>25 && bmi<=30)
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
		            	   		+ "Niestety Twój indeks BMI jest za wysoki. \n Zmień tryb życia, pora na odchudzanie!");
	               }
	               else if (bmi>30 && bmi<=35)
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
		            	   		+ "Niestety Twój indeks BMI jest za za wysoki. \n Wskazuje on na I stopień otyłości! \n "
		            	   		+ "Zaczerpnij porady dietetyka, \ni natychmiastowo zmień dietę!");
	               }
	               else if (bmi>=35)
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
		            	   		+ "Niestety Twój indeks BMI jest za za wysoki. \n Wskazuje on na II stopień otyłości! \n "
		            	   		+ "Natychmiastowo zmień dietę!\n Czas na poważne odchudzanie, to już nie są żarty!");
	               }
	               else
	               {
	            	   output.setText("Witaj " +tImie.getText()+"!" + "\n\nTwój indeks BMI wynosi: " + bmi + " \n\n "
		            	   		+ "Gratulacje, Twój indeks BMI jest w normie!\n Tak trzymać!");
	               }
	               
	           }
	           else
	           {
	               output.setText(tImie.getText()+"Podaj poprawne dane! \n \n -wiek musi być liczbą całkowitą. "
	               		+ "\n -waga lub wzrost może zostać podane w postaci \n   liczby dziesiętnej");
	           }
	       }
	   }       
	}
	

Teraz zastanawiam się nad tym formatowaniem tekstu (trochę bym się tym pobawił) do tego chciałbym zabezpieczyć program przed możliwością wpisania nieprawdziwych danych np. Wiek 12000 lat, wzrost 1500 itd. - ktoś jakieś pomysły ?

pedegie
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 204
0

możesz formatować HTML'em tekst : )

Kopiuj
String htmlText = "<html><FONT SIZE=+3>" +                          
                      "Witaj<font color=red><b> Javo!</b></font><br>" +
                      "<font color=blue>... A witaj!</font></html>";
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0
Kopiuj
Double bmi = new Double(waga/Math.pow(wzrost/100,2));
	        		java.text.DecimalFormat bmif=new java.text.DecimalFormat();
	        		bmif.setMaximumFractionDigits(2);
	        		bmif.setMinimumFractionDigits(2);

W ten sposób skróciłem wynik do dwóch liczb po przecinku, czy w miarę dobrze mi to wyszło ? :D
Niby działa, ale wolę zapytać.

Nadal pozostają 2 ostatnie pytania, nie wiem jak z nimi sobie poradzić ;/

  1. Formatowanie tekstu (trochę bym się tym pobawił), ponoć można html'em, ale gdzie dokładnie kodować?
  2. Do tego chciałbym zabezpieczyć program przed możliwością wpisania nieprawdziwych danych np. Wiek 12000 lat, wzrost 1500 itd. - ktoś jakieś pomysły ?
  3. W jaki sposób dodać jakiś prosty obrazek/i albo ikonkę? - prosił bym o przykład.

edit.
I jeszcze jedno pytanko, program wykonuję zadanie dopiero po tym jak kliknę za drugim razem w przycisk oblicz BMI, co może być tego powodem ?

Dzięki z góry! ;)

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
1
  1. Np. tak
Kopiuj
new JLabel("<html>A teraz będzie <b>pogrubione</b></html>"); 
Kopiuj
        bOblicz = new JButton("Oblicz BMI");
        bOblicz.setBounds(250, 300, 100, 50);
        bOblicz.addActionListener(new Liczydlo());

a ten fragment

Kopiuj
        else if (źródło==bOblicz)
        {
            bOblicz.addActionListener(new Liczydlo());    
        }

usuń.
3.

Kopiuj
add(new JLabel(new ImageIcon(scieżka_do_pliku_graficznego))
  1. Chcesz nie pozwolić wpisać durnych danych, czy tylko nie wykonywać obliczeń, gdy dane są durne?
bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Zrób, do odczytywania danych, trzy bloki try.

Kopiuj
               String msg ="";
               boolean ok = true;
               try
               {
                   wiek = Integer.parseInt(tWiek.getText().trim());        
               }           
               catch(Exception e)
               {
                   output.setForeground(Color.RED);
                   output.setText("Wiek musi być liczbą całkowitą");
                   tWiek.requestFocus(); //przenosi kursor do pola tWiek
                   return;
               }
               if(wiek < 3)
              {
                   msg = "Żarty sobie robisz? Wracaj do kojca!";
                   ok = false;
              }
              else if(wiek >120)
              {
                   msg = "Nie wierzę, tylko wampiry żyją tak długo";
                   ok = false;  
              }
              else if(wiek < 8 || wiek >80)
              {
                   msg = "Współczynnik BMI jest wiarygodny tylko dla ludzi z przedziału wiekowego 8-80";
                   ok = false;
              }
              if(!ok)
             {
                  output.setForeground(Color.RED);
                  output.setText(msg);
                  tWiek.requestFocus();
                  return;
             }
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

@up
Wielkie dzięki, już posługuję się Twoim przykładem :)

i tak na szybko:

Kopiuj
			output.setText("<html>Dla osób dorosłych wartość BMI wskazuje na:\n\n Według podstawowej klasyfikacji:\n</html>"
					+ "<html><ul> <li> x < 18,5 – niedowagę </li></html>");

przy komendzie output.setText w jaki sposób mogę formatować tekst?
Znaczniki html nie działają :/

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

W JTextArea nie możesz formatować fragmentów, możesz zmienić tylko format całego tekstu. Użyj komponentu JTextPane.

A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

Ok zaraz popróbuję, a mam pytanie czy jak dodam jakiś obrazek czy ikonę, czy jest możliwość wyświetlania tego pod tekstem i pod polami, jako taki background?

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Tak, schemat jest taki:

Kopiuj
setLayout(null);
setPreferredSize(new Dimension(szerokość_obrazka,wysokość obrazka));
//dodawanie komponentów
JLabel background = new JLabel(new ImageIcon(ścieżka do obrazka));
background.setOpaque(true); //ważne!
background.setBounds(0,0,...,...);
add(background);
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

Dzięki wszystkim za pomoc i wskazówki!
Praca nad programem nadal trwa, powiem wam że odczułem już wyrobienie pewnej wprawy, wiele rzeczy jest dla mnie jeszcze czarną magią, ale z dnia na dzień poznaję nowe rzeczy i ich zastosowania.

Na dzień dzisiejszy programik wygląda tak:

user image

I przy okazji mam jedno pytanie, podczas gdy robię export programu do pliku wykonywalnego jar (chcę normalnie odpalić program z poziomu windowsa) to w programie nie zapisuje się tło, tylko program używa domyślnego. Jak zrobić żeby wyexportowany program odpalał się z moim tłem?

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Skopiuj obrazki do katalogu z jarem, albo umieść je w pliku jar. W drugim przypadku musisz zapewne inaczej je czytać.

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0

Dwa sposoby rozpoznawania czy String s zawiera tylko polskie litery

Kopiuj
boolean onlyLetters(String s)
{
     boolean result = true;
     for(char c:s.toCharArray())
     {
         result = result && Character.isLetter(c);
     }
     return result; 
}
//przy pomocy wyrażeń regularnych
Pattern.matches("[\\p{javaLowerCase}|\\p{javaUpperCase}]*",s);
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0
Kopiuj
		setLayout(null);
		setPreferredSize(new Dimension(700,700));
		JLabel background = new JLabel(new ImageIcon("tlo1.png"));
		background.setOpaque(true); //ważne!
		background.setBounds(0, 0, 700, 700);
		add(background);

Używam tego kodu wysłanego przez Ciebie.

bogdans
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
JLabel background = new JLabel(new ImageIcon(NazwaTwojejKlasy.class.getResource(ścieżka_od_klasy_do_obrazka+"tlo1.png"));

Najprościej, to umieścić plik "tlo1.png" obok klasy, wtedy

Kopiuj
JLabel background = new JLabel(new ImageIcon(NazwaTwojejKlasy.class.getResource("tlo1.png"));
A6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

Witam po krótkiej przerwie, niestety <ort>nie zależnej</ort> ode mnie.
No a więc biorę się za ten background o efektach poinformuję wkrótce, pozdrawiam.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.