OOP Dezimalzahl in Binärzahl mit GUI - Problem

haui95

Bekanntes Mitglied
Guten Abend,
habe mich mal wieder an Java heran gewagt und ein Programm geschrieben, womit man Dezimalzahlen in Binärzahlen umwandeln kann. Ich bin zwar mittlerweile fertig, doch das Programm läuft nicht so, wie ich es mir gedacht habe, da es mir lediglich eine Exception ausgibt. Es ist schon Schade, dass der Java Compiler nicht gerade benutzerfreundlich ist und für Anfänger sehr unverständliche oder gar keine Fehlermeldungen ausgibt. Vielleicht liegt es auch einfach nur daran, dass ich im Moment immer noch sehr viel mit Delphi arbeite und die Fehler, die Delphi einem meldet, jeder Laie versteht.
Ich bedanke mich schon einmal im Voraus ! 🙂

Hier der Quelltext:

Java:
package dectobin;

public class DecToBin 
{
    public static void main(String[] args) 
    {
        new GUI();
    }
}

Java:
package dectobin;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class GUI 
{
    JFrame form1;
    GridLayout layout1;
    JButton button1, button2;
    JTextField edit1, edit2;
    JLabel label1, label2;
    
    public GUI()
    {
        form1 = new JFrame("Zahlensysteme");
        layout1 = new GridLayout(3,2);
        button1 = new JButton("Beenden");
        button1.addActionListener(new Buttonhandler());
        button2 = new JButton("Umwandeln");
        button2.addActionListener(new Buttonhandler());
        edit1 = new JTextField("");
        edit2 = new JTextField("");
        label1 = new JLabel("Dezimalzahl:");
        label2 = new JLabel("Binärzahl:");

        form1.add(label1);
        form1.add(edit1);
        form1.add(label2);
        form1.add(edit2);
        form1.add(button1);
        form1.add(button2);
        
        form1.setLayout(layout1);
        form1.setSize(500, 300);
        form1.pack();
        form1.setVisible(true);
        form1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
   }
    
    String Reverse(String eingabe)
    {
        int i;
        String result;
        result = "";
        
        for (i = eingabe.length(); i > 1; i --)
          result = result + eingabe.charAt(i);
        
        return result;
    }
    
    String DecToBin(int eingabe)
    {
        String result, ergebnis;
        result = "";
        ergebnis = "";
        
        do 
        {
            ergebnis = ergebnis + ergebnis.valueOf(eingabe % 2);
            eingabe = eingabe / 2;
        }
        while (eingabe != 0);
        
        result = Reverse(ergebnis);
        
        return result;
    }  
    
    class Buttonhandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == button1)
            {
                System.exit(0);
            }
            else if (e.getSource() == button2)
            {
                int i = Integer.parseInt(edit1.getText());
                
                edit2.setText(DecToBin(i));
            }
        }
    }
}
 
Wenn eine Exception fliegt, hast Du keinen syntaktischen Fehler gemacht. D.h. der Compiler kann nicht erkennen, dass ein Fehler vorliegt. Eine Exception ist ein Zeichen für einen Fehler zur Laufzeit. Hier hat der Compiler seine Arbeit schon getan. Prominentestes Beispiel ist die NullPointer-Exception, die dann fliegt, wenn man auf eine null-Referenz zugreift. Z.B. hier:
Java:
// nicht sehr sinnvoll, stell Dir vor, das wäre ein Parameter einer Methode
String eingabe=null;

// Hier fliegt die NullPointerException
eingabe.trim();
Für eine Analyse Deines Fehlers poste bitte die Exception inkl. Stacktrace (die ganzen Zeilen, die nach der Exception kommen).
 
Wenn du mal angibst, welche Exception in welcher Zeile, dann
  • müssen wir nicht lange suchen
  • können wir dir helfen
  • weißt du wo du dein System.out.println einbauen musst
  • wirst du die Fehlermeldungen blitzschnell genausogut verstehen wie in Pascal.

(Mit Eclipse macht das sogar Spaß!)
 
Ich kenne die Fehlermeldungen von javac nicht wirklich, am besten lade dir Eclipse runter. Das benutzt einen eigenen Compiler und die Exceptions sollte jeder verstehen, auch wenn das Forum regelmäßig das Gegenteil beweißt:

Code:
String index out of range: 5

Java:
String Reverse(String eingabe)
{
    int i;
    String result;
    result = "";
    
    for (i = eingabe.length(); i > 1; i --)
      result = result + eingabe.charAt(i);
    
    return result;
}

charAt(lenght) existiert nicht. charAt(lenght - 1) ist das höchste. (Länge beginnt natürlich bei 1 zu zählen, index bei 0)
 
Fehlermeldung:

Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(Unknown Source)
at de.max96.help.GUI.Reverse(GUI.java:50)
at de.max96.help.GUI.DecToBin(GUI.java:68)
at de.max96.help.GUI$Buttonhandler.actionPerformed(GUI.java:85)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Das heißt, dass du versuchst ein Feld auszulesen, was es nicht gibt, hier fliegt die Exception:

Java:
for (i = eingabe.length(); i > 1; i --)
          result = result + eingabe.charAt(i);

[WR]Edit:
Leider zu langsam, schade 😉
[/WR]
 
Noch klarer ausgedrückt:
Länge des Arrays = 5 bedeutet es gibt Fel[0] bis Feld[4]. Kein Feld[5] !
Das versuchst du aber in deinem 'reverse'.

Dass ein Array mit 1 beginnt musst du dir in Java im Gegensatz zu Pascal abgewöhnen.
(oder du sogar den Anfangswert festlegen kannst: NIXDA!
Code:
[STRIKE]Array [1950..2050] of String;[/STRIKE]
. )
 
Hier nochmal die Exception des Compilers:

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:504)
at java.lang.Integer.parseInt(Integer.java:527)
at dectobin.GUI$Buttonhandler.actionPerformed(GUI.java:83)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:703)
at java.awt.EventQueue.access$000(EventQueue.java:102)
at java.awt.EventQueue$3.run(EventQueue.java:662)
at java.awt.EventQueue$3.run(EventQueue.java:660)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:676)
at java.awt.EventQueue$4.run(EventQueue.java:674)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:673)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)


Die Exception bekomme ich genau dann, wenn ich den button2 drücke, also die Dezimalzahl in eine Binärzahl umwandeln möchte.

@AquaBall
Wofür brauche ich in meinem Programm die Instruktion System.out.println , wenn ich einen Grafische Oberfläche mit ActionListenern für die 2 Buttons benutze und die Ein- und Ausgabe über die 2 Textfelder passiert ? Du meintest ja, ich könnte anhand der Compiler Meldung heruasfinden, wo ich System.out.println setzen muss ?
 
Um herauszufinden welche Variable welchen Wert hat oder wo die VM arbeitet, wenn du keinen Debugger benutzt.
Aber um die Exception zu verstehen braucht man auch keinen Doktor-Titel: Der eingehende String "" kann in keine Number formatiert werden.
 
😀 einen Doktor-Titel braucht man dafür wirklich nicht, aber ich habe mich noch nie richtig mit diesen Exceptions auseinandergesetzt und bis jetzt habe ich auch noch nie wirklich eine gehabt, außer bei diesem Programm und so einem Programm zum Sortieren von Strings.

So, hier der neue Code:

Java:
String Reverse(String eingabe)
    {
        int i;
        String result;
        result = "";
        
        for (i = eingabe.length(); i > 1; i --)
          result = result + eingabe.charAt(i - 1);
        
        return result;

Nun habe ich endlich keine Exception mehr 😀
Dennoch gibt das Programm mir eine falsche Binärzahl aus, nachdem ich eine Dezimalzahl eingegeben habe. Bsp.: 10 -> 101 anstatt 1010
0 -> "" anstatt 0
1 -> "" anstatt 1

MfG

Hauke
 
So? Die Namen solltest du aber nochmal überdenken, sieht mehr nach GUI-Builder als "richtiges" Programm aus. ^^

Java:
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class GUI {
	JFrame form1;
	GridLayout layout1;
	JButton button1, button2;
	JTextField edit1, edit2;
	JLabel label1, label2;

	public GUI() {
		form1 = new JFrame("Zahlensysteme");
		layout1 = new GridLayout(3, 2);
		button1 = new JButton("Beenden");
		button1.addActionListener(new Buttonhandler());
		button2 = new JButton("Umwandeln");
		button2.addActionListener(new Buttonhandler());
		edit1 = new JTextField("");
		edit2 = new JTextField("");
		label1 = new JLabel("Dezimalzahl:");
		label2 = new JLabel("Binärzahl:");

		form1.add(label1);
		form1.add(edit1);
		form1.add(label2);
		form1.add(edit2);
		form1.add(button1);
		form1.add(button2);

		form1.setLayout(layout1);
		form1.setSize(500, 300);
		form1.pack();
		form1.setVisible(true);
		form1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	String decToBin(int eingabe) {
		StringBuilder builder = new StringBuilder();
		do {
			builder.append(eingabe % 2);
			eingabe = eingabe / 2;
		} while (eingabe != 0);

		return (builder.reverse().toString());
	}

	class Buttonhandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == button1) {
				System.exit(0);
			} else if (e.getSource() == button2) {
				String src = edit1.getText();
				if(isNumericString(src)) {
					int i = Integer.parseInt(edit1.getText());
					edit2.setText(decToBin(i));	
				}
			}
		}
		private boolean isNumericString(String src) {
			int srcSize = src.length();
			if(srcSize == 0) {
				return(false);
			}
			
			for(int i = 0; i < srcSize; i++) {
				if(!Character.isDigit(src.charAt(i))) {
					return(false);
				}
			}
			return(true);
		}
	}
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				new GUI();					
			}
		});
	}
}
 
Naja wenn du schon viel in Pascal gearbeitet hast, dann dürft das auch keine große Herausforderung sein:

Nun hast du eine Stelle zu wenig!

Was du zuerst "Hinten zuviel" gehabt hast, hast du nun "vorne zuwenig".

Java:
for(i = eingabe.length(); i > 1; i --)
geht halt nur solange >1, also mindestens =2.
=> 2-1 = 1
und Feld[1] ist nicht das erste Feld, sondern das 2.Feld.
Das erste hieße Feld[0] (= Feld[1-1])

(Mit System.out mein' ich Kontrollzeilen, wenn du einen Fehler suchst.)
 
Zuletzt bearbeitet:
So, endlich geht es ! 🙂)

Hier noch einmal der Code mit Zählgesteuerter Schleife zum Umdrehen des Strings.

Java:
String Reverse(String eingabe)
    {
        int i;
        String result;
        result = "";
        
        for (i = eingabe.length(); i > 0; i --)
          result = result + eingabe.charAt(i - 1);
        
        return result;
    }
    
    String DecToBin(int eingabe)
    {
        String result, ergebnis;
        result = "";
        ergebnis = "";
        
        do 
        {
            ergebnis = ergebnis + ergebnis.valueOf(eingabe % 2) ; // + ergebnis;
            eingabe = eingabe / 2;
        }
        while (eingabe != 0);
        result = Reverse(ergebnis);
        
        return result;
    }  
    
    class Buttonhandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == button1)
            {
                System.exit(0);
            }
            else if (e.getSource() == button2)
            {
                int i;
                i = Integer.parseInt(edit1.getText());
                
                edit2.setText(DecToBin(i));
            }
        }
    }
}

Und hier ein Alternativer Code:

Java:
String DecToBin(int eingabe)
    {
        String result;
        result = "";
        
        do 
        {
            result= result.valueOf(eingabe % 2) + result;
            eingabe = eingabe / 2;
        }
        while (eingabe != 0);
        
        return result;
    }  
    
    class Buttonhandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == button1)
            {
                System.exit(0);
            }
            else if (e.getSource() == button2)
            {
                int i;
                i = Integer.parseInt(edit1.getText());
                
                edit2.setText(DecToBin(i));
            }
        }
    }
}
 
Das sieht imo nach Kunstwerk aus:

Java:
for (i = eingabe.length(); i > 0; i --)
	result = result + eingabe.charAt(i - 1);

Java:
for (i = eingabe.length() - 1; i >= 0; i --)
	result = result + eingabe.charAt(i);
 

Zurück
Oben