switch w pętli

0

Witam! Mam problem z obsługą jednego case'a w switchu. Po wybraniu odpowiedniego numeru wywołuje metode z innej klasy typu void. Po wykonaniu tej metody pokazuje sie menu i program wyrzuca mi błąd "NoSuchElementException". Co mam zrobić, aby tak nie było i dalej można było odczytać menu z maina? Dodam że cały switch i menu jest w pętli (klawisz "3" przerywa pętle) więc po każdej iteracji wczytuje mi znak na nowo

1

Bez pokazania kodu nikt Ci nie powie co jest źle i co musisz zrobić.

0

Metoda record() wczytuje imiona i nazwiska do momentu wpisania słowa "stop" . Kończy się sout'em.

{
		Scanner scanner = new Scanner(System.in);
		try
			{
				Pracownik.lista1.addAll(File.readingNames());
				Pracownik.lista2.addAll(File.readingSurnames());
			} catch (FileNotFoundException e)
			{
				System.err.println("Nie znaleziono pliku!");
			} catch (IOException e)
			{
				System.err.println("Nieoczekiwany błąd1");
			}
		int option;
		do
			{
				System.out.println("1)Dodaj pracownika");
				System.out.println("2)Losuj pracownika");
				System.out.println("3)Wyjście");

				option = scanner.nextInt();
				switch (option)
				{
				case 1:

				{
					try
						{
							File.record();
						} catch (IOException e)
						{
							System.err.println("Nieoczekiwany błąd!");
							break;
						}
				}
					break;
				case 2:
				{
					Pracownik pracownik = new Pracownik();
					Pracownik pracownik2 = new Pracownik();
					wizytówka(pracownik.getName(), pracownik.getSurname(), pracownik.getAge());
					wizytówka(pracownik2.getName(), pracownik2.getSurname(), pracownik2.getAge());
				}
					break;
				default:
				{
					if (option == 3)
						{
							System.out.println("Miłego dnia!");
						} else
						{
							System.out.println("Spróbuj ponownie!");
						}
				}
				}
			} while (option != 3);
		scanner.close();
	}

0

Tak na szybko to według mnie problemem jest nextInt(). Powinieneś przed wywołaniem nextInt() sprawdzać, czy objekt Scanner hasNextInt().

0

To dlaczego problem jest tylko przy case 1?

0

Tak bez problemu wszystko działa. Tylko z tą jedynką jest problem. Wywołuje ona metode typu void z innej klasy. Ale przecież potem mam napisane break więc nie wiem. Próbowałem zrobic tak że w tamtej metodzie wywołuje metode main z tym menu ale też nie działa :/

0

Wrzuć jeszcze cały komunikat o błędzie wyrzucany przez kompilator.

0

Najlepiej jakbyś wrzucił cały kod na pastebin. Po drugie, zacznij używać automatycznego formatowania kodu przez swoje IDE.

0

Kod z wszystkich 3 klas? :D wolałem tego uniknąć ale ok :P A po drugie używam automatycznego (zmienionego przeze mnie) formatowania. Do tego standardu nie mam na razie ochoty się przyzwyczajać bo najzwyczajniej styl formatowania Java przeszkadza mi źle mi się tak pisze i nie jest czytelne dla mnie :/

kiyo napisał(a):

Wrzuć jeszcze cały komunikat o błędzie wyrzucany przez kompilator.
Wyrzuca mi wyjątek, błędów nie ma podczas kompilacji

Zaraz wrzuce kod z wszystkich 3 klas. Wyrzuca mi wyjątek:

3xMz27zYR7u_FWUiqndM8g.png

0

Jak robisz scanner.close() w klasie File to zamykasz też InputStream'a którego przekazałeś (w Twoim wypadku System.in), dlatego nie możesz zrobić już więcej scanner.nextInt()

0

Nie za bardzo wiem co mam w takiej sytuacji robić. Mam nie zamykać scannera w klasie File? Myślałem że to są dwa różne scannery i nie mają ze soba powiązania :)

0

To jak w takich przypadkach się to robi? Tworzy się nowy scanner? Czy jest na to jakaś inna rada?

0

Jeśli jeden Scanner zamknie Ci System.in, to drugi już z niego nic nie odczyta.

Zazwyczaj jedna klasa ma odpowiedzialność interakcji z kosolowym UI. To że sobie u siebie rozbiłeś na dwie klasy jest dosyć dziwne. Ogólnie, to masz 3 wyjścia (w kolejności od najgorszego do najlepszego).

  • Zostawić kod jak jest, wywalić scanner.close() z File i nie zwalniać zasobów w tym miejscu
  • Współdzielić instancję scannera między klasami (średnie).
  • Przepisać kod tak żeby tylko jedna z tych klasa pobierała i wyświetlała tekst do/od usera.
0

Chciałem żeby odczytywanie i zapis do pliku było w osobnej klasie. W sumie nie za bardzo wiem jakby to podpiąć. Tak dla mnie było czytelniej i bardziej przejrzyście :P ogólnie nie miałem w zamyśle tego menu więc problemu nie było. Teraz na to wpadłem :D :) co do drugiej metody to powiesz coś więcej? czy to kwestia douczenia się? Jak takie rzeczy się robi/czego szukać w necie? jakoś to się nazywa? :D co do pierwszej metody.. czytałem i słyszałęm cały czas że "wypadałoby" zamknąć scanner. coś się dzieje, jak się go nie zamyka?

0
Adrian Paź napisał(a):

Chciałem żeby odczytywanie i zapis do pliku było w osobnej klasie. W sumie nie za bardzo wiem jakby to podpiąć. Tak dla mnie było czytelniej i bardziej przejrzyście :P ogólnie nie miałem w zamyśle tego manu więc problemu nie było. Teraz na to wpadłem :D :)

No to czemu nie możesz rozdzielić zapisywania/odczytywania danych do jednej klasy, a komunikacji z userem przez konsolę w drugiej? Przecież to są dwie, zupełnie różne odpowiedzialności.

Adrian Paź napisał(a):

co do drugiej metody to powiesz coś więcej? czy to kwestia douczenia się? Jak takie rzeczy się robi/czego szukać w necie? jakoś to się nazywa? :D

No możesz zrobić beznadziejnie (tak jak teraz masz w swoim kodzie) pole statyczne i korzystać w niego wszędzie. Albo zrobić lepiej i przekazać ten Scanner w polu konstruktora klasy w której chcesz z niego skorzystać. Ale jak już mówiłem, zamiast go współdzielić, korzystniej by było lepiej rozplanować odpowiedzialności klas.

Adrian Paź napisał(a):

co do pierwszej metody.. czytałem i słyszałęm cały czas że "wypadałoby" zamknąć scanner. coś się dzieje, jak się go nie zamyka?

Zależnie od platformy jvm zwolni (lub nie) zasoby takiego InputStreama. Im lepsza kontrola takimi zasobami, tylko apka staje się mniej pamięciożerna.

0

Przecież w zapisie do pliku właśnie używam scannera do wpisywania imion do PrintStreama. Nie wiem chyba żeby w klasie Firma podawać imiona do tablicy w pętli i przekazać tą tablice jako parametr do metody record. Bo z tym konstruktorem nie wiem jak zrobić.

0
Adrian Paź napisał(a):

Przecież w zapisie do pliku właśnie używam scannera do wpisywania imion do PrintStreama.

No, może ciężko Ci to zrozumieć na razie ale to nie jest "jedna rzecz". Interakcja usera z aplikacją to jedno, a to co aplikacja robi z danymi (zapis do pliku) to coś innego. Nie należy tego na siłę łączyć. Niby, po ch** zapis do pliku ma cokolwiek wiedzieć o System.in? :D

Adrian Paź napisał(a):

Nie wiem chyba żeby w klasie Firma podawać imiona do tablicy w pętli i przekazać tą tablice jako parametr do metody record.

Tablica, stringi/zmienne, wszystko jedno (ja bym wybrał zmienne). Tak, to jest całkiem spoko rozwiązanie.

Adrian Paź napisał(a):

Bo z tym konstruktorem nie wiem jak zrobić.

Nie wiesz, bo używasz tylko metod statycznych (które, btw, nie są zbyt eleganckim rozwiązaniem).

0

Używam metod statycznych żeby nie tworzyć za każdym razem nowych obiektów tak wydawało mi się jest szybciej i wygodniej xD

1
Adrian Paź napisał(a):

Używam metod statycznych żeby nie tworzyć za każdym razem nowych obiektów tak wydawało mi się jest szybciej i wygodniej xD

screenshot-20180505212510.png

0

hahaha czemu? :D czyli powinno się zawsze tworzyć te instancje?

0

Zainteresuj się zasadami SOLID (a w szczególności Dependency Inversion). Możesz też pogooglać "OOP" ale to dużo bardziej obszerny temat. Chodzi o kilka implementacji tego samego interfejsu i polimorfizm. To są bardzo przydatne mechanizmy, nie mówiąc o większej testowalności i maintainability.

1 użytkowników online, w tym zalogowanych: 0, gości: 1