Dialogbox solange abfragen, bis gültige Wert-Eingabe

maxmuster987

Aktives Mitglied
Ich wollte mal nachfragen, wie man das am besten löst, wenn man eine Dialogbox startet und nur bestimmte Werte akzeptiert.
Und wenn man einen falschen Wert eingibt (Zahl und/oder Buchstaben), dann soll die Dialogbox automatisch neu gestartet werden für eine Neueingabe.

Bisher habe ich das immer mit einer do-while Schleife realisiert im einfachsten Fall.

Java:
        do {
            String eing = JOptionPane.showInputDialog("Geben Sie den Wert 1 ein:");
            int wert = Integer.parseInt(eing);
        }
        while(wert!=1)

Da würde er mir die Dialogbox solange aufrufen, bis ich eine 1 eingegeben habe. Das ist natürlich zu einfach.
Wie mache ich das für den Anwendungsfall wie oben beschrieben? Wenn bspw. Zahlen von 1-10 gültig sind und alles andere zur Neueingabe führt und eine 0 zum Programmabbruch.

Bei einem Prof habe ich immer "etwas" von nachfolgender Struktur gesehen, bei der ich aber keine Ahnung habe, wie sie funktioniert mit diesem "boolean ende = true" und while(ende), ende=false etc.

Java:
import javax.swing.*;

public class Neueingabe {
    public static void main (String [] args) {
      
        boolean ende = true;
        int wert=0;
      
        while(ende) {
            String eing = JOptionPane.showInputDialog("Geben Sie einen Wert ein");
            wert = Integer.parseInt(eing);
            if (wert<=10|wert>0) {
                System.out.println("Eingabe ist korrekt und wird weiterverarbeitet");
                ende = false;
            }
            else {
                System.out.println("Fehleingabe, bitte neu eingeben.");
            } 
        }
      
        switch(wert) {
            case 1:
            System.out.println("1 wurde eingegeben");
            break;
            case 2:
            System.out.println("2 wurde eingegeben");
            break;

        }
    }
}

Der Code hier oben ist nicht korrekt, sondern soll nur das grobe Schema widerspiegeln, ich weiß leider auch nicht, wie der in korrekter Ausführung wäre.




Nachtrag:

Wenn ich den Code von ganz ganz oben verwende also mit der do-while Schleife, dann könnte ich das doch auch realisieren wie folgt:
Java:
        do {
            String eing = JOptionPane.showInputDialog("Geben Sie einen Wert 1-10 eim:");
            wert = Integer.parseInt(eing);
        }
        while(wert>10|wert<0);

Wenn ich außerhalb des Wertebereichs von 1-10 bin, dann öffnet sich die Box ständig erneut.

Aber trotzdem würde mich das mit dem boolean, ende, true interessieren, wie das funktioniert. Vielleicht ist das ja die bessere Option für solche Angelegenheiten.
 
Zuletzt bearbeitet:
Das Schema ist schon fast soweit korrekt, nur eben ist es etwas zu kompliziert umgesetzt und daher schwer verständlich. Und es gibt paar Flüchtigkeitsfehler wie wert <= 10 ODER Wert > 0 - was immer erfüllt ist 🙂

Der Ansatz aus meiner Sicht ist immer, dass man sich erst genau überlegt, was genau passieren soll. Und dass ist ja folgendes:

- So lange
--> Eine Zahl abfragen
- wie Zahl nicht gültig ist

Formulierungen kann man schon so wählen, dass diese zu Java Sprachkonstrukten passen ... So lange ... machen wie ... ist z.B. eine Beschreibung der do while Schleife.

Java:
int userAuswahl;
do {
    userAuswahl = frageZahlAb();
} while (!istGueltig(userAuswahl));

Damit hast Du dann auch das Problem aufgeteilt in Teilprobleme:

Methode frageZahlAb, welche eine Zahl zurück gibt. Wenn der Benutzer aber keine Zahl eingibt, dann schlägt das Parsen ja mit einer Exception fehl - die möchte man dann ja abfangen und reagieren ... da hast Du aber dann eine klare, konkrete Stelle, bei der dies passieren könnte.
- die Methode istGueltig hat dann die Validierungsregel.

Wenn sowas an mehreren Stellen gebraucht würde, dann hat man das auch direkt verfügbar - man muss sowas nicht doppelt haben.

Und der Code wird sehr lesbar. Du musst nicht überlegen, was der Code macht. Der Code lässt sich so ja schon direkt lesen.
 
Wenn der Benutzer aber keine Zahl eingibt, dann schlägt das Parsen ja mit einer Exception fehl - die möchte man dann ja abfangen und reagieren

Um auf die Exception zurückzukommen, wie fange ich die ab? Ich kenne bisher nur ArithmeticException e, wenn bspw. durch 0 geteilt wird, dass er dann das Ganze abfängt. Gibt es dafür auch eine extra Exception, die ich noch nicht kenne?

Ich hab den Code jetzt mal damit so geschrieben:

Java:
import javax.swing.*;
public class Uebung {
    public static void main (String [] args) {
        try {
            int menue=0;
            String eing = JOptionPane.showInputDialog("Geben Sie die Anzahl der Maschinen ein:");
            int maschinen = Integer.parseInt(eing);           
            int feld[] = new int[maschinen];
            int gesamtzahl = 0;
            float durchschnitt = 0;
        
        
        
            do {
                System.out.println("=============================================");   
                System.out.println("=== Berechnung Zylinderkopfdichtungen ===");
                System.out.println("=============================================\n");
                System.out.println("(1) Produktionszahlen fuer " +maschinen +" Maschinen eingeben");
                System.out.println("(2) Produktionszahlen ausgeben");       
                System.out.println("(3) - ohne Funktion -");
                System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++");
                System.out.println("(0) Programmende\n");   
                
                String eing2 = JOptionPane.showInputDialog("Geben Sie Ihr Menue ein: ");
                menue = Integer.parseInt(eing2);
                
                switch(menue) {
                    case 0:
                        System.out.println("Programm beendet.");
                        System.exit(0);
                    break;
                    
                    case 1:
                        for(int i=0; i<maschinen; i++) {
                            String eing3 = JOptionPane.showInputDialog("Geben Sie die Produktionszahl fuer Maschine " +(i+1) + " ein");
                            int prodzahl = Integer.parseInt(eing3);
                            feld[i]=prodzahl;
                        }
                    break;
                    
                    case 2:
                        for(int i=0; i<maschinen; i++) {
                            gesamtzahl=gesamtzahl+feld[i];
                        }
                        durchschnitt=((float)(gesamtzahl))/maschinen;
                        System.out.println("Gesamtanzahl:\t " +gesamtzahl);
                        System.out.println("Durchschnitt:\t " +durchschnitt);
                    break;
                    
                    case 3:
                        System.out.println("Noch ohne Funktion.");
                    break;
                    
                    default:
                        System.out.println("Fehleingabe, bitte neu eingeben.");
                    break;           
                }           
            }
            while(menue!=0);
            System.exit(0);
        }
        catch (NumberFormatException ex) {
            System.out.println("Buchstabe eingegeben: " +ex);
        }   
    }
}



Nachtrag: Habe den Code mit NumberFormatException ergänzt, das sollte doch die richtige Exception sein, oder?
 
Zuletzt bearbeitet:
Schau Dir dazu einfach die Dokumentation an. Du rufst Integer.parseInt auf:
NumberFormatException - if the string does not contain a parsable integer.

Damit hast Du die Exception, die Du fangen müsstest.

Dann macht es immer Sinn, die Exception da zu fangen, wo diese auf auftritt. Also nicht die ganze Methode in ein try packen.

Und Du hast es ja schon an zwei Stellen! Einmal in Zeile 6 und dann noch einmal in Zeile 24 - daher macht es durchaus Sinn, das in einer eigenen Methode zu haben. (Oder bist Du noch so am Anfang, dass Du noch keine eigenen Methoden schreiben kannst? Dann wäre das natürlich schwer 🙂 )



Und dann noch ein Hinweis zu lokalen Variablen: Es war früher bei Scripten üblich, Variablen am Anfang zu deklarieren. In der modernen Software Entwicklung ist es aber üblich, die Deklaration nahe an die Nutzung zu packen. Nur als kleines Beispiel schauen wir uns Deine Variable durchschnitt an. Diese verwendest Du ja nur an einer Stelle. Daher reicht es, die Variable dort zu deklarieren:
Java:
                    case 2:
                        for(int i=0; i<maschinen; i++) {
                            gesamtzahl=gesamtzahl+feld[i];
                        }
                        float durchschnitt=((float)(gesamtzahl))/maschinen;
                        System.out.println("Gesamtanzahl:\t " +gesamtzahl);
                        System.out.println("Durchschnitt:\t " +durchschnitt);
                    break;
 
Ich habe jetzt schon bisschen mit Java programmiert, aber ich würde nicht behaupten, dass ich schon wirklich fortgeschritten o.Ä. bin darin, ich bin noch in der Aufbauphase und am lernen. Methoden habe ich auch schon paar geschrieben, wenn es um die Berechnung von bestimmten Formeln etc. ging und ich der Methode dann Werte übergebe.


Am Anfang habe ich tatsächlich auch die Variablen immer nahe an der Nutzung deklariert, aber mit der Zeit habe ich dann beim Kompilieren immer die Fehlermeldung bekommen, dass die Variable noch nicht initialisiert wurde (wird logischerweise an mir liegen, dass ich die irgendwie falsch initialisiert habe) und seitdem mache ich das immer direkt ganz am Anfang und seitdem habe ich diese Probleme selber nicht mehr.

Die Codes, die ich ja schreibe, die sind nicht sonderlich lang, wie es eigentlich üblich ist. Also ich rede hier von 100-200 Zeilen, deswegen ist das Ganze eigentlich noch relativ übersichtlich.
 
der unterschied ist wenn du sie in der klasse ( nahe am anfang ) hinschreibst dann bekommen sie automatisch standard werte wie zb ein int wird automatisch mit 0 gefüllt wenn nix anderses vorgegeben ist


wenn du eine variable in der method deklarierst dann wird die variable nicht automatisch initialisiert
 
Er hat nur eben keine Instanz- oder Klassenvariablen. Er nutzt nur lokale Variablen und er initialisiert sie immer direkt bei der Deklaration.
 
Zeile 7 und Zeile 55. Das ist das, was ich eben angesprochen hatte.
Was hat das mit dem boolean Wert zu tun? Ich verstehe noch nicht, wieso diese Option auch die Dialogbox ständig wieder aufruft. Die Option finde ich irgendwie geschmeidiger und würde die eher nutzen als die do-while Schleife mit konkreten Zahlenwerten, wenn das mehr Sinn ergibt.

Java:
import java.io.*;
import javax.swing.*;
import java.util.*;

public class feldaktualisieren {
    public static void main (String[] args) {
        boolean aktiv = true;
        int i;
        int feld [] = new int [5];
        System.out.println("====================================");      
        System.out.println("==== Ein-/ Ausgabe eines Feldes ====");
        System.out.println("====================================\n");
        System.out.println("(1) Messwerte eingeben");
        System.out.println("(2) Messwerte ausgeben");
        System.out.println("(3) Einzelne Messwerte aktualisieren");
        System.out.println("====================================");
        System.out.println("(0) Programmende");
       
        do {
            String eing = JOptionPane.showInputDialog("Waehlen Sie eine Option:");
            int wahl = Integer.parseInt(eing);
       
            switch(wahl) {
                case 1:
                    for(i=0; i<5; i++) {
                        eing = JOptionPane.showInputDialog("Messwert " +(i+1) +" eingeben: ");
                        int messwert = Integer.parseInt(eing);
                        feld[i]=messwert;
                    }
                break;
               
                case 2:
                    for(i=0; i<5; i++) {
                        System.out.println("Messwert " +(i+1) +": " +feld[i]);
                    }
                break;
               
                case 3:
                    eing = JOptionPane.showInputDialog("Welchen Messwert wollen sie aktualisieren?");
                    wahl = Integer.parseInt(eing);
                    eing = JOptionPane.showInputDialog("Messwert " +wahl + " eingeben:");
                    feld[wahl-1]=Integer.parseInt(eing);
                    System.out.println("");
                break;
               
                case 0:
                System.out.println("Programm beendet.");
                System.exit(0);
               
                default:
                System.out.println("Falsche Eingabe - bitte neu.");
               
            }
        }
        while(aktiv);

        System.exit(0);  
    }
}
 
Das Ergebnis der Validierung wird da einfach nur in einer Variable gespeichert. Du hast also eine Variable, die speichert, ob man noch in der Schleife bleiben soll.
 
Und wie erkennt die Variable, ob sie noch in der Schleife bleiben soll? Mit den konkreten Zahlenwerten kann man das ja noch einfach nachvollziehen, weil da sehe ich "Ah okay, solange ich bspw. innerhalb oder außerhalb von bestimmten Werten liege, soll sich die Box wieder öffnen".
Aber hier scheint mir das noch nicht so offensichtlich zu sein, um das nachvollziehen zu können.
 
Bei deinem letzten Code hast Du das in der Logik vergessen so ich es nicht übersehen habe. In #1 war in der Schleife ja auch:
Java:
            if (wert<=10|wert>0) {
                System.out.println("Eingabe ist korrekt und wird weiterverarbeitet");
                ende = false;
            }

==> Da wurde dann in Schleife geprüft und entschieden: Wir sind fertig.

Das macht so Code halt schwer lesbar. Die Prüfung gehört nun einmal in die Bedingung.
 

Zurück
Oben