# Taschenrechner programmieren



## annalena (9. Mrz 2016)

hallo, habe mit einem Taschenrechner angefangen..hier ist der code und dannach kommen meine fragen 



```
package calc.swing;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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

public class abacus extends JFrame implements ActionListener
{
  private JTextField displayText = new JTextField( 30 );   // textfield 30 charakter
  private JButton[]  button      = new JButton[25];        //number of buttons and order of buttons
  private String[]   keys        = {
                                "MC", "MR", "MS", "M+", "M-",
                                 "7",   "8",   "9",    "/",     "←",
                                 "4",   "5",   "6",    "*",     "C",
                                 "1",   "2",   "3",    "-",     "=",
                                 "0",   "0",   ",",     "+",    "="
                                              };
  private String     numStr1     = "";
  private String     numStr2     = "";
  private char       op;
  private boolean    finput      = true;

  public abacus()
  {
    setTitle( "Abakus" );
    setSize( 290, 250 );
    setLocation( 800, 500 );
    Container pane = getContentPane();
    pane.setLayout( null );
    displayText.setSize( 256, 30 );
    displayText.setLocation( 10, 10 );
    pane.add( displayText );
    int x, y;
    x = 10;
    y = 40;

    for( int indicator = 0; indicator < 25; indicator++ ) //
    {
      button[indicator] = new JButton( keys[indicator] );
      button[indicator].addActionListener( this );
      button[indicator].setSize( 55, 31 );
      button[indicator].setLocation( x, y );
      pane.add( button[indicator] );
      x = x + 50;
      if ( ( indicator + 1 ) % 5 == 0 )
      {
        x = 10;
        y = y + 30;
      }
    }
  
    this.addWindowListener( new WindowAdapter()
    {
      @Override
      public void windowClosing( WindowEvent e )
      {
        System.exit( 0 );
      }
    }
        );
    setVisible( true );
  }


  @Override
  public void actionPerformed( ActionEvent e )
  {
    String resultStr;
    String str = String.valueOf( e.getActionCommand() );
    char ch = str.charAt( 0 );
    switch( ch )

    {
    //      case 'MC':{}
    //      case 'MR':{}
    //      case 'MS':{}
    //      case 'M+':{}
    //      case 'M-':{}

      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':

        if ( finput )
        {
          numStr1 = numStr1 + ch;
          displayText.setText( numStr1 );
        }
        else
        {
          numStr2 = numStr2 + ch;
          displayText.setText( numStr2 );
        }
        break;

      case '+':
      case '-':
      case '*':
      case '/':
        op = ch;
        finput = false;
        break;

      case '=':
        resultStr = auswerten();
        displayText.setText( resultStr );
        numStr1 = resultStr;
        numStr2 = "";
        finput = false;
        break;
      case 'C':
        displayText.setText( "" );
        numStr1 = "";
        numStr2 = "";
        finput = true;

      case '←':
      case ',':

    }
  }

  private String auswerten()
  {
    try
    {
      double nummer1 = Integer.parseInt( numStr1 );
      double nummer2 = Integer.parseInt( numStr2 );
      double resultat = 0;
      switch( op )
      {
        case '+':
          resultat = nummer1 + nummer2;
          break;
        case '-':
          resultat = nummer1 - nummer2;
          break;
        case '*':
          resultat = nummer1 * nummer2;
          break;
        case '/':
          resultat = nummer1 / nummer2;
      }
      return String.valueOf( resultat );
    }
    catch ( ArithmeticException e )
    {
      return "FEHLER: " + e.getMessage();
    }
    catch ( NumberFormatException e )
    {
      if ( numStr1.equals( "" ) ) return "FEHLER: Erste Eingabe Falsch";
      else return "FEHLER: Zweite Eingabe Falsch";
    }
    catch ( Exception e )
    {
      return "FEHLER";
    }
  }

  public static void main( String[] args )
  {
    abacus C = new abacus();
  }
}
```

also...mir geht's natürlich um die speicherknöpfe um sich einen wert zu speichern und wieder aufzurufen..wahrscheinlich ist das voll simple..und den wert einfach in eine variable speichern..aber ich möchte auf dem Display also im Textfeld ein M anzeigen dafür das ich eine zahl im speicher hab.. (MS zahl speichern, MR, zahl aufrufen, MC zahl löschen M+ und M- ~...dann kommt die löschentaste..die die HINTERSTE zahl löschen soll...muss ich da den gesammten string nehmen und einfach nur hinten das letzte zeichen entfernen..oder geht's einfacher? oder professioneller?

wie funktioniert das komma? habs auch schon mit nem punkt ausprobiert..nur der wollte nicht so...

die istgleich taste und die null-taste sollen doppelte größe haben..doch ich baue die Buttons ja der reihe auf...und wie kann ich da nun ne ausnahme regelung bauen? wollte mir ne menge code sparen die tasten alle einzeln zu platzieren...


----------



## Jardcore (9. Mrz 2016)

annalena hat gesagt.:


> muss ich da den gesammten string nehmen und einfach nur hinten das letzte zeichen entfernen..oder geht's einfacher? oder professioneller?


Ja solltest du, nicht wesentlich, und wahrscheinlich.


annalena hat gesagt.:


> wie funktioniert das komma? habs auch schon mit nem punkt ausprobiert..nur der wollte nicht so...


Das kommt darauf an welche Sprache eingestellt ist. Das Komma ist das Deutsche Trennzeichen von Dezimalwerten.


annalena hat gesagt.:


> die istgleich taste und die null-taste sollen doppelte größe haben..doch ich baue die Buttons ja der reihe auf...und wie kann ich da nun ne ausnahme regelung bauen? wollte mir ne menge code sparen die tasten alle einzeln zu platzieren...


Du musst dir die Referenz merken und das dann extra behandeln.
Also in deiner Schleifen, möglicherweise prüfen ob es die "0" bzw. die "=" Taste ist.

Dein Code sollte allgemein aber noch etwas überarbeitet werden.
Statt ein SwitchCase Konstruk zu benutzen, welches alle möglichen Eingaben testet, könntest du auch mit einem Regulären Ausdruck arbeiten.


```
String eingabe = // vllt Label des Button der gedrückt wurde.
if(eingabe.match("[0-9]+") {
...
}
```
Bin mit Swing nicht so vertraut. Aber kannst du nicht einfach einen von JButton erben und die Buttons so individuell gestalten.

```
public void test() {
    new MeinButton("=");
    new MeinButton("7");
}

public class MeinButton extends JButton {
    public MeinButton(String text) {
         int width = 0;
         int height = 0;
       
         if(text.equals("=")) {
              width = ButtonProperties.BIG.getWidth();
              //...
         } else {
              width = ButtonProperties.NORMAL.getWidth();
         }
         this.setWidth(width);
    }
}

public enum ButtonProperties {
    BIG(100,200),
    NORMAL(100,100);

    private int height;
    private int width;

    private ButtonProperties(int width, int height) {
        this.width = width;
        this.height = heigth;
    }

    public int getWidth() {
        return width;
    }
    // usw.
}
```

Man kann sich wahrscheinlich noch bessere Möglichkeiten ausdenken, aber man muss auf jeden Fall irgendwo eine Fallunterscheidung machen. Ob das nun im Konstruktor gerade so gut ist sollte man nochmal überdenken.


----------



## Kababär (9. Mrz 2016)

Hi,

muss es Swing sein oder darf es auch das neuere JavaFx sein? 
Wenn du dir Code sparen willst, ist JavaFx perfekt, da du dir die GUI wie im Baukasten zusammenstellen kannst und der Code in quasi-XML Format gespeichert wird. Zudem kannst den Elementen eine ID zuweisen, auf die du dann im Java-code zugreifen kannst. so kannst du auch listener erstellen, die darauf warten bis ein Knopf gedrückt wird und dann eine Aktion ausführen. 

Die GUI kann man aber auch dynamisch per Code erstellen und das hinzufügen mehrerer Buttons in ein Container ist da kein Problem. Man hat dann zwar keine ID mehr (da diese nur über die FXML verfügbar sind), aber du kannst dir den Text des Buttons ausgeben lassen, wenn ein Event getriggered wurde und dementsprechend reagieren. 

Wegen der hintersten Zahl. Entweder du konvertierst die Zahl in einen String und spiegelst diesen, schneidest die erste Stelle ab mit deinString.substring(1); oder du machst einfach 

```
stringNeu = stringAlt.substring(0, stringAlt.length()-1);
int zahlNeu = Integer.parseInt(stringNeu);
```

Bezüglich der Buttons. 
Irgendwo setzt du ja den Text für die Buttons. Zu den Zeitpunkten, an denen du diese Buttons erstellst, würde ich auch einfach die Größe der Buttons verdoppeln. Ich würde das auch so wie mein Vorredner tun und das mittels einer Schleife lösen. Eine Liste mit den Texten erstellen und mit Buttons und dann durchlaufen. Während der schleife dann die Eigenschaften für die Buttons erstellen.


----------



## annalena (10. Mrz 2016)

```
case '←':
        numStr1neu = numStr1.substring( 0, numStr1.length() - 1 );
        numStr1 = numStr1neu;
        displayText.setText( numStr1 );
        butinput = true;
        break;
```

also das funktioniert ja soweit..jedoch hab ich ja das Problem..das ich nicht den aktiven displaystring einen abschneide..sondern IMMER nur numStr1..statt zwei...wie also kann ich genau diese numStr1 abfragen...ob er aktiv ist..und im displaysteht? mit if(displayText.setText(numStr1 == true) wird's ja wohl nix :/


----------



## annalena (10. Mrz 2016)

desweiteren habe ich ein Problem mit meinem Label..ich wollte es ÜBER das textfiel platzieren..und weiß werden lassen..und erst schwarz machen sofern eine zahl im string steht..(MS button) jedoch ist das textfield vordergründig


----------



## annalena (10. Mrz 2016)

soooo einige porbleme behoben...nun komm ich aber wirklich nicht mehr weiter
den mit meinen Memory-Buttons funktioniert gar nichts...zunächst kann ich nicht mehr als ein zeichen als "Name" bzw Zuweisung angeben..in meinen keys also das ARRAY in dem ich alle knöpfe angebe..sind die ersten 5 ja MC,MR,MS, M+,M- aber in meinen cases schreibt mir eclypse das als fehler..

und ich komm gerade nicht mit der Logik dieser knöpfe klar..mc soll ja clearen...mr soll den wert den ich in mSave speicher wieder aufrufen..MS macht mir die größten Probleme..ich versuche nunmal den wert numStr1 in mSave zu speichern..das funktioniert auch..jedoch der rest bugt dann -.-

sofern ich dann weiter rechnen möchte oder mit dem rechner arbeiten möchte..geht mir der wert verloren
habt ihr ne Idee?


```
public void actionPerformed( ActionEvent e )
  {
    String resultStr;
    String str = String.valueOf( e.getActionCommand() );
    char ch = str.charAt( 0 );
    switch( ch )

    {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':

        if ( butinput )
        {
          numStr1 = numStr1 + ch;
          displayText.setText( numStr1 );
        }
        else
        {
          numStr2 = numStr2 + ch;
          displayText.setText( numStr2 );
        }
        break;

      case '+':
      case '-':
      case '*':
      case '/':
        op = ch;
        butinput = false;
        break;
      case '=':
        resultStr = auswerten();
        numStr1 = resultStr;
        numStr2 = "";
        butinput = false;
        displayText.setText( numStr1 );
        break;
      case 'C':
        displayText.setText( "" );
        numStr1 = "";
        numStr2 = "";
        butinput = true;
        break;
      case '←':
        numStr1neu = numStr1.substring( 0, numStr1.length() - 1 );
        numStr1 = numStr1neu;

        butinput = true;
        break;
      case ',':
        butinput = true;
        break;

      case 'q':
        mSave = "";
        labelM.setForeground( Color.white );
        labelM.setOpaque( false );
        numStr1 = "";
        butinput = false;

      case 'w':
        mSave = numStr1;
        butinput = false;
        break;

      case 'e':
        numStr1 = mSave;
        labelM.setForeground( Color.black );
        labelM.setOpaque( false );
        //displayText.setText( "0" );
        butinput = false;
        break;
        //      case 'M+':
        //
        //        butinput = false;
        //        break;
        //
        //      case 'M-':
        //
        //        butinput = false;
        //        break;
    }
  }
```


----------



## annalena (10. Mrz 2016)

gut mein switchcase hab ich von char auf string umgebaut..das ist nun auch kein Problem mehr..aber die Funktion der knöpfe -.- lässt mir noch meine haare grau werden..bitte um hilfe


----------



## Kababär (10. Mrz 2016)

Verwende doch statt dem Case eine if-else if-else Verzweigung.


----------



## VfL_Freak (10. Mrz 2016)

Moin,


Kababär hat gesagt.:


> Verwende doch statt dem Case eine if-else if-else Verzweigung.


DAS wird hier wohl NICHT die Lösung sein 
IMHO  passt hier ein Switch besser, weil es übersichtlicher ist!

Die Frage, die sichmir nun stellt ist jedoch:
was genau läßt denn die Haare grau werden??
wird das verraten ?? 

Was mir so spontan auffällt:
ist "butinput" bekannt? Wo ist das deklariert? Wo wird es womit gefüllt?? 
Gruß Klaus


----------



## Kababär (10. Mrz 2016)

Das Problem ist doch, dass M+, MC oder sonst was, nicht ein Char ist.
Du rufst e.getActionCommand() auf. Wenn du bei der Erstellung deiner Buttons auch noch setActionCommand() vergibst, dann kannst du doch mit String-Cases rausfiltern, ob es sich um +, *, -, ..., MC, C, MR, MS handelt, oder nicht?



> DAS wird hier wohl NICHT die Lösung sein
> IMHO passt hier ein Switch besser, weil es übersichtlicher ist



Wohl wahr. Ich zielte darauf ab, dass sie mit chars arbeitet, da es vorher mit Strings wohl nicht funktionierte. Deshalb die Überlegung, ob es mit if-else if-else funktionieren würde.
Punkto Übersichtlichkeit gebe ich dir Recht.


----------



## VfL_Freak (10. Mrz 2016)

Kababär hat gesagt.:


> Ich zielte darauf ab, dass sie mit chars arbeitet, da es vorher mit Strings wohl nicht funktionierte


Ah, ok ... mit Strings klappt das erst ab Java8 !!
Gruß Klaus


----------



## Saheeda (10. Mrz 2016)

Öh, Strings und Switch funktioniert doch schon seit Java 7? https://docs.oracle.com/javase/8/docs/technotes/guides/language/strings-switch.html


----------



## annalena (10. Mrz 2016)

es liegt nun nur noch an der funktion der knöpfe...alles andere funktioniert doch 

und die haare werden dann grau wenn ich zB. meine zahl speicher..in mSave, die jedoch mit einer nächsten aktion verloren geht..und die MC und M+ /M- funktionieren auch irgendwie nicht -.-

und naja komma-taste weiß ich auch noch keine lösung wie man sowas ausprogrammiert.

so sieht der gesammte code nun aus:

TODO
MC, MR, MS, M+, M-  ","


```
package calc.swing;

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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

public class abacus extends JFrame implements ActionListener
{
  private JTextField displayText = new JTextField( 30 ); // textfield 30 charakter
  private JLabel     labelM      = new JLabel();
  private JButton[]  button      = new JButton[23];     //number of buttons
  private String[]   keys        = { //and order of buttons
                                 "MC", "MR", "MS", "M+", "M-", //clear / recall / save / m+-?
                                 "7", "8", "9", "/", "←",
                                 "4", "5", "6", "*", "C",
                                 "1", "2", "3", "-", "=",
                                 "0", ",", "+", };
  private String     numStr1     = "";
  private String     numStr2     = "";
  private String     numStr1neu  = "";
  private String     mSave       = "";
  private String     op;
  private boolean    butinput    = true;

  public abacus()
  {
    setTitle( "Abakus Omega" ); //frame settings
    this.setBounds( 650, 400, 315, 250 );
    Container pane = getContentPane();
    labelM.setLocation( 20, 18 );
    labelM.setText( "M" );
    labelM.setForeground( Color.white );
    labelM.setSize( 15, 15 );
    pane.add( labelM );
    displayText.setBounds( 12, 10, 276, 30 );
    displayText.setHorizontalAlignment( JTextField.RIGHT );
    pane.add( displayText );
    int x, y;
    x = 12;
    y = 40;
    pane.setLayout( null );
    //initializing buttons
    for( int indicator = 0; indicator < 23; indicator++ ) 
    {
      button[indicator] = new JButton( keys[indicator] );
      button[indicator].addActionListener( this );
      button[indicator].setSize( 55, 31 );
      button[indicator].setLocation( x, y );
      pane.add( button[indicator] );
      x = x + 55;
      if ( ( indicator + 1 ) % 5 == 0 )
      {
        x = 12;
        y = y + 31;
      }
      if ( button[indicator] == button[19] )
        button[indicator].setSize( 55, 62 );

      if ( button[indicator] == button[20] )
      {
        button[indicator].setSize( 110, 31 );
        x += 55;
      }
    }
    this.addWindowListener( new WindowAdapter()
    {
      @Override
      public void windowClosing( WindowEvent e )
      {
        System.exit( 0 );
      }
    }
        );
    setVisible( true );
  }

  @Override
  public void actionPerformed( ActionEvent e )
  {
    String resultStr;
    String str = String.valueOf( e.getActionCommand() );
    switch( str )

    {
      case "0":
      case "1":
      case "2":
      case "3":
      case "4":
      case "5":
      case "6":
      case "7":
      case "8":
      case "9":

        if ( butinput )
        {
          numStr1 = numStr1 + str;
          displayText.setText( numStr1 );
        }
        else
        {
          numStr2 = numStr2 + str;
          displayText.setText( numStr2 );
        }
        break;

      case "+":
      case "-":
      case "*":
      case "/":
        op = str;
        butinput = false;
        break;
      case "=":
        resultStr = auswerten();
        numStr1 = resultStr;
        numStr2 = "";
        butinput = false;
        displayText.setText( numStr1 );
        break;
      case "C":
        displayText.setText( "" );
        numStr1 = "";
        numStr2 = "";
        butinput = true;
        break;
      case "←":
        numStr1neu = numStr1.substring( 0, numStr1.length() - 1 );
        numStr1 = numStr1neu;
        displayText.setText( numStr1 );
        butinput = true;
        break;
      case ",":
        butinput = true;
        break;
      case "MC":
        mSave = "";
        labelM.setForeground( Color.white );
        labelM.setOpaque( false );
        numStr1 = "";
        butinput = false;
        break;
      case "MR":
        mSave = numStr1;
        butinput = false;
        break;

      case "MS":
        numStr1 = mSave;
        labelM.setForeground( Color.black );
        labelM.setOpaque( false );
        //displayText.setText( "0" );
        butinput = true;
        break;
      case "M+":
        mSave = numStr1 + mSave;
        displayText.setText( numStr1 );
        butinput = false;
        break;
      case "M-":
        mSave = numStr1 - mSave;
        displayText.setText( numStr1 );
        butinput = false;
        break;
    }
  }

  private String auswerten()
  {
    try
    {
      double nummer1 = Double.parseDouble( numStr1 );
      double nummer2 = Double.parseDouble( numStr2 );
      double resultat = 0;
      switch( op )
      {
        case "+":
          resultat = nummer1 + nummer2;
          break;
        case "-":
          resultat = nummer1 - nummer2;
          break;
        case "*":
          resultat = nummer1 * nummer2;
          break;
        case "/":
          resultat = nummer1 / nummer2;
      }
      return String.valueOf( resultat );
    }
    catch ( ArithmeticException e )
    {
      return "FEHLER: " + e.getMessage();
    }
    catch ( NumberFormatException e )
    {
      if ( numStr1.isEmpty() || numStr1 == null ) return "FEHLER: Erste Eingabe Falsch";
      else return "FEHLER: Zweite Eingabe Falsch";
    }
    catch ( Exception e )
    {
      return "FEHLER";
    }
  }

  public static void main( String[] args )
  {
    abacus C = new abacus();
  }
}
```


----------



## Kababär (10. Mrz 2016)

Revidierung: Bei mir stellt sich mSave nicht auf null zurück, sondern ich kann mit dem Ergebnis weiterrechnen.


----------



## Kababär (10. Mrz 2016)

```
case "MC":
                mSave = "";
                labelM.setForeground(Color.white);
                labelM.setOpaque(false);
                numStr1 = "";
                butinput = false;
                break;
            case "MR":
                displayText.setText(mSave);
                butinput = false;
                break;

            case "MS":
                mSave = numStr1;
                labelM.setForeground(Color.black);
                labelM.setOpaque(false);
                //displayText.setText( "0" );
                butinput = true;
                break;
            case "M+":
                numStr1 = String.valueOf(Double.parseDouble(numStr1) + Double.parseDouble(mSave));
                displayText.setText(numStr1);
                butinput = false;
                break;
            case "M-":
                numStr1 = String.valueOf(Double.parseDouble(numStr1) - Double.parseDouble(mSave));
                //mSave = numStr1 - mSave;
                displayText.setText(numStr1);
                butinput = false;
                break;
```

Ist das wonach du suchst?


----------



## Kababär (11. Mrz 2016)

Also das habe ich bis jetzt mal zusammengebastelt.
Um das M im TextField immer im Vordergrund zu haben, braucht man ein LayeredPane, bei dem man die Ebene bzw die Schicht der Komponente angeben kann.

```
Container pane = getLayeredPane();
pane.add(labelM, 2, 0);
```

Bei M+ und M-, war das Problem, dass wenn beispielsweise 100 im MS (mSave) landete und du nun eigentlich 100+50 rechnen wolltest, plötzlich 10050 daraus wurden, weil nicht die Zahlenwerte miteinander addiert wurden, sondern lediglich die zwei Strings 100 und 50 konkateniert wurden.
Deshalb ging M- nicht, weil der Operator "-" nicht für Strings definiert ist.

Dann gab es noch ein paar runtime exceptions, weil nicht abgefragt wurde, ob überhaupt was in den jeweiligen Strings steht, diese aber verwendet werden (substring, etc).

Derzeit sieht das ganze so aus:


Spoiler: Überarbeitet





```
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package abacus;

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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

public class abacus extends JFrame implements ActionListener {

    private JTextField displayText = new JTextField(30); // textfield 30 charakter
    private JLabel labelM = new JLabel();
    private JButton[] button = new JButton[23];     //number of buttons
    private String[] keys = { //and order of buttons
        "MC", "MR", "MS", "M+", "M-", //clear / recall / save / m+-?
        "7", "8", "9", "/", "←",
        "4", "5", "6", "*", "C",
        "1", "2", "3", "-", "=",
        "0", ",", "+",};
    private String numStr1 = "";
    private String numStr2 = "";
    private String numStr1neu = "";
    private String mSave = "";
    private String op;
    private boolean butinput = true;

    public abacus() {
        setTitle("Abakus Omega"); //frame settings
        this.setBounds(650, 400, 315, 250);
        Container pane = getLayeredPane();
        labelM.setLocation(20, 18);
        labelM.setText("M");
        labelM.setForeground(Color.white);
        labelM.setSize(15, 15);
        pane.add(labelM, 2, 0);
        displayText.setBounds(12, 10, 276, 30);
        displayText.setHorizontalAlignment(JTextField.RIGHT);
        pane.add(displayText);
        int x, y;
        x = 12;
        y = 40;
        pane.setLayout(null);
        //initializing buttons
        for (int indicator = 0; indicator < 23; indicator++) {
            button[indicator] = new JButton(keys[indicator]);
            button[indicator].addActionListener(this);
            button[indicator].setSize(55, 31);
            button[indicator].setLocation(x, y);
            pane.add(button[indicator]);
            x = x + 55;
            if ((indicator + 1) % 5 == 0) {
                x = 12;
                y = y + 31;
            }
            if (button[indicator] == button[19]) {
                button[indicator].setSize(55, 62);
            }

            if (button[indicator] == button[20]) {
                button[indicator].setSize(110, 31);
                x += 55;
            }
        }
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        }
        );
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String resultStr;
        String str = String.valueOf(e.getActionCommand());
        switch (str) {
            case "0":
            case "1":
            case "2":
            case "3":
            case "4":
            case "5":
            case "6":
            case "7":
            case "8":
            case "9":

                if (butinput) {
                    numStr1 = numStr1 + str;
                    displayText.setText(numStr1);
                } else {
                    numStr2 = numStr2 + str;
                    displayText.setText(numStr2);
                }
                break;

            case "+":
            case "-":
            case "*":
            case "/":
                op = str;
                butinput = false;
                break;
            case "=":
                resultStr = auswerten();
                numStr1 = resultStr;
                numStr2 = "";
                butinput = false;
                displayText.setText(numStr1);
                break;
            case "C":
                displayText.setText("");
                numStr1 = "";
                numStr2 = "";
                butinput = true;
                break;
            case "←":
                if (numStr1 != null && !numStr1.isEmpty()) {

                    numStr1neu = numStr1.substring(0, numStr1.length() - 1);
                    if (numStr1neu.substring(numStr1neu.length() - 1).equals(".")) {
                        numStr1neu = numStr1neu.substring(0, numStr1neu.length() - 1);
                    }
                    numStr1 = numStr1neu;
                    displayText.setText(numStr1);
                    butinput = true;
                }
                break;
            case ",":
                butinput = true;
                break;
            case "MC":
                mSave = "";
                labelM.setForeground(Color.white);
                labelM.setOpaque(false);
                numStr1 = "";
                butinput = false;
                break;
            case "MR":
                if (mSave != null && !mSave.isEmpty()) {
                    displayText.setText(mSave);
                } else {
                    displayText.setText("Nichts im Speicher");
                }
                butinput = false;
                break;

            case "MS":
                mSave = numStr1;
                numStr1 = "";
//                displayText.setText("");
                labelM.setForeground(Color.black);
                labelM.setOpaque(false);

                butinput = true;
                break;
            case "M+":
                if (mSave != null && !mSave.isEmpty()) {
                    numStr1 = String.valueOf(Double.parseDouble(numStr1) + Double.parseDouble(mSave));
                    displayText.setText(numStr1);
                }
                butinput = false;
                break;
            case "M-":
                if (mSave != null && !mSave.isEmpty()) {
                    numStr1 = String.valueOf(Double.parseDouble(numStr1) - Double.parseDouble(mSave));
                    //mSave = numStr1 - mSave;
                    displayText.setText(numStr1);
                }
                butinput = false;
                break;

        }
    }

    private String auswerten() {
        try {
            double nummer1 = Double.parseDouble(numStr1);
            double nummer2 = Double.parseDouble(numStr2);
            double resultat = 0;
            switch (op) {
                case "+":
                    resultat = nummer1 + nummer2;
                    break;
                case "-":
                    resultat = nummer1 - nummer2;
                    break;
                case "*":
                    resultat = nummer1 * nummer2;
                    break;
                case "/":
                    resultat = nummer1 / nummer2;
            }
            return String.valueOf(resultat);
        } catch (ArithmeticException e) {
            return "FEHLER: " + e.getMessage();
        } catch (NumberFormatException e) {
            if (numStr1.isEmpty() || numStr1 == null) {
                return "FEHLER: Erste Eingabe Falsch";
            } else {
                return "FEHLER: Zweite Eingabe Falsch";
            }
        } catch (Exception e) {
            return "FEHLER";
        }
    }

    public static void main(String[] args) {
        abacus C = new abacus();
    }
}
```


----------



## annalena (11. Mrz 2016)

wow danke das ist...sehr hilfreich
nur mein komma bugt noch etwas...


```
private String noComma = "" ;
private boolean hasComma = false;


case ",":
        if ( hasComma ) break;
        else hasComma = true;
        if ( numStr1.length() < 30 )
        {
          noStr1 = numStr1.concat( "." );
          displayText.setText( numStr1 );
        }
        break;
```


----------



## Kababär (11. Mrz 2016)

Was genau meinst du mit buggt noch etwas?
Was passiert wann, was du nicht haben willst?

Mir fällt auf, dass du noStr1 definierst, aber es nicht benutzt. Du hast nicht zufällig die Variablen vertauscht beim setzen des Displaytextes?


----------



## annalena (11. Mrz 2016)

ich kann auf meinem zweiten string kein komma setzen...das heisst..ich muss numstr2 auch ein komma vergeben...mhh wieso kam ich nicht selbst drauf..jedoch funktioniert es nicht so einfach wie ich glaubte....

```
case ",":
        if ( hasComma ) break;
        else hasComma = true;
        if ( noStr1.length() < 30 )
        {
          noStr1 = noStr1.concat( "." ); //transform comma into point..looks like better
          displayText.setText( noStr1 );
        }
        if ( noStr2.length() < 30 )
        {
          noStr2 = noStr2.concat( "." ); //transform comma into point..looks like better
          displayText.setText( noStr2 );
        }
        break;
```


----------



## Kababär (11. Mrz 2016)

Wozu brauchst du denn eigentlich zwei Strings?
Was soll jeder dieser beinhalten?

Derzeit wird das Ergebnis oder die Zahl als "199,0" dargestellt und du willst es als "199.0" haben?
Bedenke, dass concat nicht das macht, was du gerne hättest. concat, zu deutsch, konkatenieren, verbindet zwei Strings.

```
String str1 = "Baum";
String str2 = "Haus";
String strR = str1.concat(str2);
System.out.print(strR);

Output:
Baumhaus
```

Alternativ dazu kann man auch

```
strR = str1 + str2;
```
schreiben.

Dein Problem ist, dass du einfach die falsche Methode benutzt. Wenn du etwas ersetzen willst, brauchst du die String.replace Methode.

```
String str1 = "Baumhaus";
//string.replace(alter String, neuer String);
String strR = str1.replace("Baum", "Stein");
System.out.println(strR);

Output:
Steinhaus
```

Edit: Nur Vermutungen und Raterei, da nicht bekannt ist, was genau eigentlich nicht so funktioniert wie gewünscht.


----------



## Jardcore (11. Mrz 2016)

Ich würde dir empfehlen die Logik von der GUI zu trennen, und den Taschenrechner mit allen Funktionen erst einmal Consolen basiert zu entwickeln und dann z.B. mittels MVC ein sauberes Design aufsetzen.

```
public class Calculator {

    private String operator;
    private double operant1;
    private double operant2;
   
    public double calculate() {
        switch(operator) {
        case "+":
            return add();
        case "-":
            return sub();
        case "*":
            return mul();
        case "/":
            return div();
        default:
            throw new UnsupportedOperationException("Operation nicht gefunden");
        }
    }
   
    private double add() {
        return operant1 + operant2;
    }
   
    private double sub() {
        return operant1 - operant2;
    }
   
    private double mul() {
        return operant1 * operant2;
    }
   
    private double div() {
        if(operant2 == 0) {
            throw new IllegalArgumentException("Teilen durch 0 ist nicht definiert");
        }
        return operant1 / operant2;
    }
   
    public void setOperant1(double operant1) {
        this.operant1 = operant1;
    }
   
    public void setOperant2(double operant2) {
        this.operant2 = operant2;
    }
   
    public void setOperator(String operator) {
        this.operator = operator;
    }
}
```

Hier zum Beispiel ein Rechner mit den Basisfunktionen, ein Controller könnte dann auf die GUI reagieren und die set...() Methoden und die calculate() Methode des Calculators aufrufen.


----------



## Kababär (11. Mrz 2016)

> Ich würde dir empfehlen die Logik von der GUI zu trennen, und den Taschenrechner mit allen Funktionen erst einmal Consolen basiert zu entwickeln und dann z.B. mittels MVC ein sauberes Design aufsetzen.



Bin da ganz deiner Meinung und vertrete auch deine Meinung aus dem vorherigen Post.
Allerdings steht bei ihr immer noch das meiste im Konstruktor und eine Trennung sieht man nur einmal: die Methode auswerten().
Ich weiß auch nicht, wie weit ihr Wissensstand in Java und Designing bzw. Modellierung ist, weswegen ich erster Hand probiere, ihre Probleme zu lösen. 
Den Code kann man später auch noch cleanen bzw ist ein Muss, wenn das Programm dann doch etwas größer werden soll.

Nicht falsch verstehen, Design und co ist bezüglich Wiederverwendbarkeit, Stabilität und Flexibilität unverzichtbar für Projekte.


----------

