# Ungültige Eingaben: Fehler ausgeben



## Aucass (19. Feb 2016)

Guten Tag zusammen,

heute ist mein 3 Tag mit Java und ich spiele mal hier und dort etwas rum um es besser zu verstehen.
Jetzt habe ich aber mal eine Frage, da ich dazu leider keine Antworten gefunden habe.

Ich habe eine kleine Anwendung erstellt, die mir die Differenz zwischen zwei Uhrzeiten ausgibt und mir sagt ob die Minutenanzahl von 175 erfüllt ist oder nicht.
Gebe ich nun wie gefordert meine Uhrzeiten im Format von HH:MM an, klappt alles wunderbar.

Ich möchte jedoch, dass er mir in einem GUI-Dialog einen Fehlertext ausgibt, sobald das Format von HH:MM falsch ist (Egal ob falsches Format oder Zeichen wie z.b Buchstaben). Wie stelle ich das an?

Wenn ihr noch ein paar Tip's habt, was man an diesem Code noch ändern könnte oder es einfacher gestallten könnte, immer her damit! Aber denkt dran, ich bin erst seit 3 Tagen dabei 


```
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;


public class Uhrzeiten2 {

   public static void main(String[] args) throws ParseException {
      DateFormat df = new SimpleDateFormat("HH:mm");
    
      String zeit1 = javax.swing.JOptionPane.showInputDialog( null, "Beginn: (HH:MM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
      String zeit2 = javax.swing.JOptionPane.showInputDialog( null, "Ende: (HH:MM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
    
    Date datum1 = df.parse(zeit1);
    Date datum2 = df.parse(zeit2);
    
    long dif = datum2.getTime()- datum1.getTime();
    long dif2 = dif/1000/60;
    
    JOptionPane.showMessageDialog(null, dif2 < 175 ? "Zeit nicht erfüllt \n" + dif2 +" Minuten von 175 Minuten!" : "Zeit erfüllt \n" + dif2 +" Minuten von 175 Minuten!", "Zeitenberechnung", JOptionPane.INFORMATION_MESSAGE);
    
   }
}
```


----------



## Joose (19. Feb 2016)

Hier die Dokumentation zur Klasse "SimpleDateFormat"
https://docs.oracle.com/javase/7/do...se(java.lang.String, java.text.ParsePosition)
Die Methode "parse" liefert "null" zurück fall es einen Fehler gibt. 
Sprich du musst prüfen ob datum1 oder datum2 == null sind, wenn ja gab es einen Fehler.


----------



## Aucass (19. Feb 2016)

> Die Methode "parse" liefert "null" zurück fall es einen Fehler gibt.
> Sprich du musst prüfen ob datum1 oder datum2 == null sind, wenn ja gab es einen Fehler.



Sorry, aber das musst du mir etwas genauer erklären. Grade mal etwas probiert, aber komme zu keinem Ergebnis!
Wie fange ich den "null" ab, falls es ausgegeben wird?


----------



## Joose (19. Feb 2016)

Die Methode "parse" liefert dir entweder ein Date Objekt zurück oder eben "null" (nichts).
Jetzt musst du prüfen ob deine Variable "datum1" bzw. "datum2" Objekte enthalten oder eben "null". Das kannst du mittels if-Bedingung (!= null) feststellen.


----------



## Aucass (19. Feb 2016)

Ich glaube ich denke einfach zu umständlich!
Ich habe es jetzt so umgesetzt, wie ich es verstanden habe und so passt es nicht!
Egal welche Eingabe ich tätige, die if-Anweisung ist immer erfüllt.
Er gibt mir also jedes mal Ungültige Eingabe aus, selbst wenn die Eingabe richtig ist.

Vielleicht kannst du mir mal ein Beispiel geben? 


```
if (datum1 != null)
       System.out.println("Beginn: Ungültige Eingabe");
       
    if (datum2 != null)
       System.out.println("Ende: Ungültige Eingabe");
```


----------



## Tarrew (19. Feb 2016)

Du benutzt nicht die verlinkte parse() Methode von Joose, sondern diese:
https://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#parse(java.lang.String)

Im Fehlerfall wird eine ParseException geworfen, die du im Moment einfach throwst. Deswegen beendet sich dein Programm einfach. Du solltest die Exception catchen und dann einen Fehler ausgeben:

```
Date datum1 = null;
        try {
            datum1 = df.parse(zeit1);
        } catch (ParseException e) {
            System.out.println("Beginn: Ungültige Eingabe");
            return;
        }
```


----------



## Joose (19. Feb 2016)

Da hat Tarrew natürlich recht, dass ich die falsche Parse Methode verlinkt habe.


----------



## Viktim (19. Feb 2016)

Für des Fenster mit der GUI kannst du einfach ein JOptionePane nehmen...
sähe dann so aus:

```
JOptionPane.showMessageDialog(null, "Text");
```


----------



## Aucass (19. Feb 2016)

Joose hat gesagt.:


> Da hat Tarrew natürlich recht, dass ich die falsche Parse Methode verlinkt habe.


Macht nix, passiert 


ParseException hat ->fast<- wunderbar geklappt! Ich habe es vorher schon gesehen, bin mit try & catch aber nicht so vertraut. Kommt alles noch 

Ich habe es jetzt wie folgt:

```
Date datum1 = null;
    try {
       String zeit1 = javax.swing.JOptionPane.showInputDialog( null, "Beginn: (HHMM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
    datum1 = df.parse(zeit1);
    } catch (ParseException e) {
       JOptionPane.showMessageDialog( null, "Ungültige Eingabe");
    return;
    }
```

Und das gleiche natürlich für datum2.
Gebe ich nun in das Dialogfenster "Hallo" ein, gibt er mir die ungültige Eingabe aus - So wie es soll!
Gebe ich aber z.b fünf Zeichen ein, obwohl nur 4 gefordert werden (HHmm), passiert nix!

Eingabe: 08:00 -> Ausgabe: Ungültige Eingabe -> Richtig!
Eingabe: 0800 -> Ausgabe: Richtige Eingabe -> Richtig!
Eingabe: 08001 -> Ausgabe: Richtige Einagabe -> Falsch, da 5 Zeichen!

Und noch kurz eine andere Frage:
Wenn eine ungültige Eingabe passiert, soll das Eingabefenster erneut erscheinen!
Wie realisiert man sowas am simpelsten?
Ich habe was von LineNumberReader gelsen, ist das sinnvoll?
Oder macht es auch eine normale while-Schleife?


----------



## Aucass (19. Feb 2016)

Okay, dass nur 4 Zeichen erlaubt sind, habe ich mit einer Raute in

```
DateFormat df = new SimpleDateFormat("HHmm#");
```

gelöst! Ist das so die optimale Vorgehensweise?

Und wie geht es nun mit der Schleife?
So wie ich den Sinn einer While-Schleife verstanden habe, sollte es doch so funktionieren?!:

```
while (true){
         try {
             String zeit1 = JOptionPane.showInputDialog( null, "Beginn: (HHMM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
             datum1 = df.parse(zeit1);
             break;
         } catch (ParseException e) {
             JOptionPane.showMessageDialog( null,"Ungültige Eingabe! \nFormat beachten!" );
             return;
    }
      }
```

Das klappt aber nicht.


----------



## Tarrew (19. Feb 2016)

Nimm das return raus  Sonst returned die Funktion und die Schleife wird verlassen.


----------



## Aucass (19. Feb 2016)

Tarrew hat gesagt.:


> Nimm das return raus  Sonst returned die Funktion und die Schleife wird verlassen.


Ja, das dachte ich mir auch! Funktioniert an sich auch, aber nun gibt er mir selbst die richtige Eingabe als falsch aus 
Hier nochmal mein aktueller Code:

```
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

public class Zeitenrechner {

   public static void main(String[] args) throws ParseException {
      DateFormat df = new SimpleDateFormat("HHmm#");
      Date datum1 = null;
      Date datum2 = null;
     
         while (true){
         try {
             String zeit1 = JOptionPane.showInputDialog( null, "Beginn: (HHMM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
             datum1 = df.parse(zeit1);
             break;
         } catch (ParseException e) {
             JOptionPane.showMessageDialog( null,"Ungültige Eingabe! \nFormat beachten!" );
         }
         }     
    try {
         String zeit2 = JOptionPane.showInputDialog( null, "Ende: (HHMM) ", "Zeitenberechnunug", JOptionPane.PLAIN_MESSAGE);
         datum2 = df.parse(zeit2);
    } catch (ParseException e) {
         JOptionPane.showMessageDialog(null, "Ungültige Eingabe" );
    return;
    }
     
     
    long dif = datum2.getTime()- datum1.getTime();
       long dif2 = dif/1000/60;             
           
       if (dif2 <175){
             JOptionPane.showMessageDialog(null,"Zeit nicht erfüllt! \n" + dif2 +" Minuten von 175 Minuten!");
        }
     
       else if  (dif2 >175){
             JOptionPane.showMessageDialog(null,"Zeit erfüllt! \n" + dif2 +" Minuten von 175 Minuten!");
       }
    }
}
```

Danke für eure Geduld. Aller Anfang ist schwer


----------



## Tarrew (19. Feb 2016)

Das liegt an deinem Raute-Zeichen '#' beim SimpleDateFormat. Wie kommst du darauf, dass man damit die Länge begrenzt? Hab davon noch nie gehört.

Hier wäre mal eine Lösung für einen strikten Parser:
http://stackoverflow.com/questions/...er-of-characters-in-pattern/19503019#19503019


----------



## Aucass (19. Feb 2016)

Okay, danke!
Habe es mir mal angeguckt, aber nach 3 Tagen Java brauche ich einfach etwas mehr Erfahrung.

Ich gebe mich vorerst damit zufrieden, dass die Anzahl der Zeichen nicht begrenzt ist.
Aber trotzdem funktioniert, soweit alles! Danke


----------



## Bitfehler (19. Feb 2016)

Ich habe auch noch eine kleine Anmerkung:

Wenn dif2 gleich 175 ist, muss dann nicht auch etwas passieren. So habe ich das zumindest im ersten Post verstanden. Aktuell werden nur die Wertebereiche unter und über 175 behandelt.


----------



## Aucass (19. Feb 2016)

Bitfehler hat gesagt.:


> Ich habe auch noch eine kleine Anmerkung:
> 
> Wenn dif2 gleich 175 ist, muss dann nicht auch etwas passieren. So habe ich das zumindest im ersten Post verstanden. Aktuell werden nur die Wertebereiche unter und über 175 behandelt.


Aber klar, Danke 
Habe es jetzt auf <175 und >174 gesetzt!


----------



## Joose (19. Feb 2016)

```
while (true){
```
Nur als Hinweis: Man sollte solche Endlosschleifen vermeiden und immer eine Abbruchbedingung definieren!
Bei kleinen Probe-/Test-/Übungsprogrammen natürlich akzeptabel


----------

