In der Methode "IsNumeric" mag er die erste Zeihle im try-Block nicht, da im JTextField immer ein Object bzw. String übergeben wird. Ich dachte eigentlich wenn ich den übergebenden String nur Zahlen rein schreibe sollte er nicht in den catch-Block springen. Dem ist aber nicht so!
Weiß jemand wie ich ganz simpel in meiner "IsNumeric"-Methode überprüfen kann ob die übergebene "value" nur Zahlen enthälten? Wenn ein String (Buchstaben) übergeben wurde dann soll er in den catch-Block springen.
Indem ich meinen Code geschrieben habe und er immer in den catch Block springt. Egal was für ein Wert ich dem value übergebe. Glaub mir.. ich wundere mich genau so. Deswegen hab ich mich ans Internet gewedet.
entryInput.getText() gibt einen String zurück.
Warum erwartest du dann ein Object in der isNumeric Methode. Integer.parseInt(value); erwartet einen String. Also entweder value.toString() oder isNumeric(Object value) in isNumeric(String value) ändern.
Indem ich meinen Code geschrieben habe und er immer in den catch Block springt. Egal was für ein Wert ich dem value übergebe. Glaub mir.. ich wurde mich genau so.
Der Code wird nicht einmal kompiliert, wie soll er dann in den catch-Block springen? Wie @max40 schon geschrieben hat, hat Integer keine Methode parseInt mit der passenden Signatur (Object).
Da habt ihr recht. Das habe ich falsch hier geschrieben. Also in meinem Code ist es ein String, das übergeben wird. Aber das ändert leider nichts an der Tatsache dass er trotzdem immer in den Catch-Block springt. Ich hoffe ich stell mich nicht einfach nur dumm an aber ich bekomm nicht raus warum.
Ist ja auch klar, es gibt kein Integer:arseInt(Object). Übergib der Methode einen String. du solltest auch DefaultListModel<String> entsprechend verwenden.
Das isInt Feld sollte auch auf keinen Fall static sein.
Es ist auch ein unschöner Programmierstil eine Exception für sowas zu missbrauchen. Besser wären Ansätze wie z.B. mit Regex oder Character::isDigit(char)
Java:
else{return;}
Total überflüssiger Code.
Außerdem rufst du die Add-Methode noch garnicht auf, ich hätte vermutet, dass beim ActionEvent add aufgerufen werden müsste
Dein Catch Block kann auch erreicht werden, wenn die eingegebene Zahl > Integer.MAX_VALUE ist. Auch aus diesem Grund wäre eine andere vorgehensweise für isNumeric zu empfehlen.
Ok so wies aussieht habe ich euch und mich nur damit verwirrt indem ich nur einen Teil des Codes rein geschickt habe. Ich dachte es wäre so Übersichtlicher. Zu deiner Frage @max40 ich übergeben ihr ein ganz normalen Integer (wie z.B.: 2131). Ich schicke euch mal meinen ganzen Code:
Der Code ist nicht schön, da ich in diesem Thema noch sehr neu bin aber ich hoffe wenigstens ihr werdet schlau draus.
Java:
packageToDo;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Container;importjava.awt.Dimension;importjava.awt.GridLayout;importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;importjavax.swing.DefaultListCellRenderer;importjavax.swing.DefaultListModel;importjavax.swing.JButton;importjavax.swing.JDialog;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JList;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;importjavax.swing.JViewport;importjavax.swing.ScrollPaneConstants;importjavax.swing.border.Border;importjavax.swing.plaf.TextUI;/**
* Source Code für AP Aufgabe vom 12/10/2018
* ToDo Liste
* @author fschwarz
*/@SuppressWarnings("serial")publicclassToDoListEntryextendsJFrame{publicstaticvoidmain(String[] args){newToDoListEntry();}privatefinalJTextField input;privatefinalJTextField entryInput;privatefinalDefaultListModel<String> listModel;privatefinalDefaultListModel<String> listEntry;// String => Integer to complete my CodeprivatefinalJList<String> listM;privatefinalJList<String> listE;// String => Integer to complete my Codeprivatestaticboolean isInt;publicToDoListEntry(){/**
* Konstruktor setzt den Titel von dem JFrame automatisch mit also anstatt:
* <code>
* super();
*
* setTitle("Title");
* </code>
*/super("ToDo List");/**
* Container der JFrame:
* hier werden später alle anderen komonenten hinzugefügt
*/finalContainer container =getContentPane();
container.setLayout(newBorderLayout());/**
* Alle UI komponenten iniziallisiert
*/
input =newJTextField();
entryInput =newJTextField();
listModel =newDefaultListModel<>();
listEntry =newDefaultListModel<>();
listM =newJList<>(listModel);
listE =newJList<>(listEntry);// Die JScrollPane nimmt eine Componente als parameter, dieser wird dann innerhalb dargestellt: JListfinalJButton add =newJButton("add");finalJButton remove =newJButton("remove");finalJButton removeAll =newJButton("remove all");finalJButton exit =newJButton("exit");// Dieses JPanel wird die Buttons haltenfinalJPanel buttons =newJPanel();// Dieses JPanel wird das ScrollPanel behandelnJPanel scroll =newJPanel();finalJScrollPane scrollPane =newJScrollPane(scroll);
scroll.add(listM);
scroll.add(listE);// Designs the ScrollPane
scroll.setBackground(Color.WHITE);DefaultListCellRenderer rendererModel =(DefaultListCellRenderer) listM.getCellRenderer();
rendererModel.setHorizontalAlignment(JLabel.LEFT);DefaultListCellRenderer rendererEntry =(DefaultListCellRenderer) listE.getCellRenderer();
rendererEntry.setHorizontalAlignment(JLabel.RIGHT);// Diese JPanel wird die Input Felder haltenfinalJPanel inputs =newJPanel();// Inputs dem JPanel hinzufügen
inputs.add(input);
inputs.add(entryInput);// GridLayout für die Inputs
inputs.setLayout(newGridLayout(0,2));// GridLayout für die Buttons, damit alle gleich groß sind
buttons.setLayout(newGridLayout(0,1));// Buttons dem JPanel hinzufügen
buttons.add(add);
buttons.add(remove);
buttons.add(removeAll);
buttons.add(exit);// Die Buttons rechts am Container hinzufügen
container.add(buttons,BorderLayout.EAST);// Das Input Feld oben am Container hinzufügen
container.add(inputs,BorderLayout.NORTH);// Die Liste mittig am Container hinzufügen
container.add(scrollPane,BorderLayout.CENTER);// Windows Adapter hinzufügen, um Application richtig zu beenden wenn x gedruckt wirdaddWindowListener(newWindowAdapter(){@OverridepublicvoidwindowClosing(WindowEvent e){exit();}});// Einen KeyListener zum JTextField hinzufügen um Key Press abzufragen
input.addKeyListener(newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER){add();}}});
entryInput.addKeyListener(newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER){add();}}});
add.addActionListener(e ->isNumeric(entryInput.getText()));// Wenn der "add" Butten gedrückt wurde, füge Text dem ListModel hinzu
add.addActionListener(e ->add());// Wenn der "remove" Button gedrückt wurde, entferne alle selektierten Elemente
remove.addActionListener(e ->remove());// Wenn der "remove all" Button gedrückt wurde, entferne alle Elemente des ListModels
removeAll.addActionListener(e -> listModel.removeAllElements());
removeAll.addActionListener(e -> listEntry.removeAllElements());// Wenn der "exit" Button gedrückt wurde, beende die Application
exit.addActionListener(e ->exit());/**
* Setzt die größe des JFrame in Pixel
* Vorsicht: Container ist kleiner als die defeinierten Dimensionen
* Da hier padding mit einberechnet ist
*/setSize(400,250);/**
* Setzt JFrame in das Center des primären Bildschirms
*/setLocationRelativeTo(null);/**
* Macht das JFrame sichtbar
*/setVisible(true);}/**
* Beendet die Application
*/privatevoidexit(){System.exit(0);}privatestaticbooleanisNumeric(String value){try{System.out.println(value);Integer.parseInt(value);return isInt =true;}catch(NumberFormatException e){return isInt =false;}// if ( value instanceof Integer) {// return isInt = true;// }// else {// System.out.println("Im 2. Inputfeld wurde kein Integer eingetragen");// return isInt = false;// }}/**
* fügt den Text des JTextFields zum ListModel hinzu
*/privatevoidadd(){//Stellt sicher dass der Input nicht null oder empty ist
listModel.addElement(input.getText());// Setzt das JTextField auf einen leeren wert
input.setText("");// Setzt den Cursor im JTextField (optional)
input.requestFocus();String intInput = entryInput.getText();if(isInt){
listEntry.addElement(intInput);System.out.println(intInput);
entryInput.setText("");
entryInput.requestFocus();}else{return;}}/**
* Entfernt eins oder mehrere selektierte Elemente
*/privatevoidremove(){// Speichert alle selektierten Elemente Index in einem Arrayint[] selectedValuesM = listM.getSelectedIndices();int[] selectedValuesE = listE.getSelectedIndices();// Wenn kein Element selektiert ist, mach nichts!if(selectedValuesM.length <1|| selectedValuesE.length <1){return;}else{// Enternt die Elemente aus dem ListModel
listModel.remove(selectedValuesM[0]);
listEntry.remove(selectedValuesE[0]);// Wiederhole remove() für die restlichen Elementeremove();}}}
add.addActionListener(e ->isNumeric(entryInput.getText()));// Wenn der "add" Butten gedrückt wurde, füge Text dem ListModel hinzu
add.addActionListener(e ->add());
add.addActionListener(e ->isNumeric(entryInput.getText()));// Wenn der "add" Butten gedrückt wurde, füge Text dem ListModel hinzu
add.addActionListener(e ->add());
Das funktioniert so - wenn überhaupt - nur zufällig, weil die Reihenfolge der Event-Benachrichtigungen nicht definiert ist.
Du hast eine Aktion "Hinzufügen" und die muss machen, was sie tun soll.
Abgesehen davon, wird der catch-Block freilich durchlaufen, wenn Du keine Zahl eingibst...
Ahhh perfekt. @max40 dein Lösungsvorschlag funktioniert, auch wenn ich nicht genau checke warum auf einmal. Aber das werde ich hoffentlich schon noch. Vielen Dank für eure schnelle Hilfe! Ohne euch würde ich sicher noch den ganzen Tag an dem Problem sitzen.
P.S.: Ich hoffe ich hab mich nicht zu dumm angestellt Wie gesagt ich lerne das alles noch.
Insgesamt ist der Code für einen Anfänger gar nicht so schlecht. Ich habe mal ein wenig rumgeschraubt und die entsprechenden Stellen kommentiert.
Java:
packageToDo;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Container;importjava.awt.Dimension;importjava.awt.GridLayout;importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;importjavax.swing.DefaultListCellRenderer;importjavax.swing.DefaultListModel;importjavax.swing.JButton;importjavax.swing.JDialog;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JList;importjavax.swing.JPanel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;importjavax.swing.JViewport;importjavax.swing.ScrollPaneConstants;importjavax.swing.border.Border;importjavax.swing.plaf.TextUI;/**
* Source Code für AP Aufgabe vom 12/10/2018
* ToDo Liste
* @author fschwarz
*/@SuppressWarnings("serial")publicclassToDoListEntryextendsJFrame{publicstaticvoidmain(String[] args){newToDoListEntry();}privatefinalJTextField input;privatefinalJTextField entryInput;privatefinalDefaultListModel<String> listModel;privatefinalDefaultListModel<String> listEntry;// String => Integer to complete my CodeprivatefinalJList<String> listM;privatefinalJList<String> listE;// String => Integer to complete my Code// REMOVEDpublicToDoListEntry(){/**
* Konstruktor setzt den Titel von dem JFrame automatisch mit also anstatt:
* <code>
* super();
*
* setTitle("Title");
* </code>
*/super("ToDo List");/**
* Container der JFrame:
* hier werden später alle anderen komonenten hinzugefügt
*/finalContainer container =getContentPane();
container.setLayout(newBorderLayout());/**
* Alle UI komponenten iniziallisiert
*/
input =newJTextField();
entryInput =newJTextField();
listModel =newDefaultListModel<>();
listEntry =newDefaultListModel<>();
listM =newJList<>(listModel);
listE =newJList<>(listEntry);// Die JScrollPane nimmt eine Componente als parameter, dieser wird dann innerhalb dargestellt: JListfinalJButton add =newJButton("add");finalJButton remove =newJButton("remove");finalJButton removeAll =newJButton("remove all");finalJButton exit =newJButton("exit");// Dieses JPanel wird die Buttons haltenfinalJPanel buttons =newJPanel();// Dieses JPanel wird das ScrollPanel behandelnJPanel scroll =newJPanel();finalJScrollPane scrollPane =newJScrollPane(scroll);
scroll.add(listM);
scroll.add(listE);// Designs the ScrollPane
scroll.setBackground(Color.WHITE);DefaultListCellRenderer rendererModel =(DefaultListCellRenderer) listM.getCellRenderer();
rendererModel.setHorizontalAlignment(JLabel.LEFT);DefaultListCellRenderer rendererEntry =(DefaultListCellRenderer) listE.getCellRenderer();
rendererEntry.setHorizontalAlignment(JLabel.RIGHT);// Diese JPanel wird die Input Felder haltenfinalJPanel inputs =newJPanel();// Inputs dem JPanel hinzufügen
inputs.add(input);
inputs.add(entryInput);// GridLayout für die Inputs
inputs.setLayout(newGridLayout(0,2));// GridLayout für die Buttons, damit alle gleich groß sind
buttons.setLayout(newGridLayout(0,1));// Buttons dem JPanel hinzufügen
buttons.add(add);
buttons.add(remove);
buttons.add(removeAll);
buttons.add(exit);// Die Buttons rechts am Container hinzufügen
container.add(buttons,BorderLayout.EAST);// Das Input Feld oben am Container hinzufügen
container.add(inputs,BorderLayout.NORTH);// Die Liste mittig am Container hinzufügen
container.add(scrollPane,BorderLayout.CENTER);// Windows Adapter hinzufügen, um Application richtig zu beenden wenn x gedruckt wirdsetDefaultCloseOperation(EXIT_ON_CLOSE);// CHANGED// Einen KeyListener zum JTextField hinzufügen um Key Press abzufragen
input.addKeyListener(newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER){add();}}});
entryInput.addKeyListener(newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER){add();}}});// REMOVED// Wenn der "add" Butten gedrückt wurde, füge Text dem ListModel hinzu
add.addActionListener(e ->add());// Wenn der "remove" Button gedrückt wurde, entferne alle selektierten Elemente
remove.addActionListener(e ->remove());// Wenn der "remove all" Button gedrückt wurde, entferne alle Elemente des ListModels
removeAll.addActionListener(e -> listModel.removeAllElements());
removeAll.addActionListener(e -> listEntry.removeAllElements());// Wenn der "exit" Button gedrückt wurde, beende die Application
exit.addActionListener(e ->exit());/**
* Setzt die größe des JFrame in Pixel
* Vorsicht: Container ist kleiner als die defeinierten Dimensionen
* Da hier padding mit einberechnet ist
*/setSize(400,250);/**
* Setzt JFrame in das Center des primären Bildschirms
*/setLocationRelativeTo(null);/**
* Macht das JFrame sichtbar
*/setVisible(true);}// REMOVEDprivatestaticbooleanisNumeric(String value){return value.matches("[0-9]+");// CHANGED}/**
* fügt den Text des JTextFields zum ListModel hinzu
*/privatevoidadd(){//Stellt sicher dass der Input nicht null oder empty ist
listModel.addElement(input.getText());// Setzt das JTextField auf einen leeren wert
input.setText("");// Setzt den Cursor im JTextField (optional)
input.requestFocus();String intInput = entryInput.getText();if(isNumeric(intInput)){// CHANGED
listEntry.addElement(intInput);System.out.println(intInput);
entryInput.setText("");
entryInput.requestFocus();}// REMOVED}/**
* Entfernt eins oder mehrere selektierte Elemente
*/privatevoidremove(){// Speichert alle selektierten Elemente Index in einem Arrayint[] selectedValuesM = listM.getSelectedIndices();int[] selectedValuesE = listE.getSelectedIndices();// Wenn kein Element selektiert ist, mach nichts!if(!(selectedValuesM.length <1|| selectedValuesE.length <1)){// CHANGED// Enternt die Elemente aus dem ListModel
listModel.remove(selectedValuesM[0]);
listEntry.remove(selectedValuesE[0]);// Wiederhole remove() für die restlichen Elementeremove();}}}
Es ist auch ein unschöner Programmierstil eine Exception für sowas zu missbrauchen. Besser wären Ansätze wie z.B. mit Regex oder Character::isDigit(char)
Integer parsen sind so ein Fall, in dem man sinnvoll es nur über die Exception (oder selber parsen) sicher prüfen kann. Zu kleine/große Werte fallen sonst raus
@MoxxiManagarm Vielen Dank Bei dem letzen if-Block meinst du warscheinlich nicht "1" sondern "!" aber ansonsten find ich es echt gut dass mir sogar der Aufwand genommen wurde meinen Code selber zu ändern. Wenn ich noch mal ein Problem habe Melde ich mich.
Ich kanns nicht oft genug sagen, danke Ich bin gerade noch ein bischen baff weil mir in nicht einmal einer Stunde von so vielen Leuten geholfen wurde. Echt super Seite hier!
Integer parsen sind so ein Fall, in dem man sinnvoll es nur über die Exception (oder selber parsen) sicher prüfen kann. Zu kleine/große Werte fallen sonst raus
Wenn er denn tatsächlich ein Integer verwenden würde. Aber aktuell speichert er letztlich nur den String bestehend aus Zahlen. Ich sehe spontan keine Notwendigkeit, dass der String einen Integer darstellen können muss. Die Methode heißt zudem isNumeric, was theoretisch indiziert, dass auch "999999999999999999" true ergeben muss. Zusätzlich würde auch die Eingabe einer Negativen Zahl beim Parsen funktionieren. Ich vermute auch das ist nicht gewollt.