# zahl hoch und runter zählen per button



## silson (9. Apr 2016)

hallo ich möchte gerne mit dem button die zahlen hoch und runter zählen...
hoch funktioniert, aber runter nicht...weiss nicht wie ich das programmieren muss, das das lezte ergebnis mit  -1 berechnet werden kann.
Bei mir springt es sofort auf 0


```
package de.test3.java;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Main extends JFrame {
  
    JLabel picture1;
    Icon levelNumberRight;
  
    JLabel picture2;
    Icon levelNumberLeft;
  
    JButton up;
  
    JButton down;
  
  
  
    public Main(){
      
        levelNumberRight = new ImageIcon(getClass().getResource("level0.jpg"));
        picture1 = new JLabel(levelNumberRight);
        picture1.setBounds(250, 60, 124, 220);
        add(picture1);
      
        levelNumberLeft = new ImageIcon(getClass().getResource("level0.jpg"));
        picture2 = new JLabel(levelNumberLeft);
        picture2.setBounds(100, 60, 124, 220);
        add(picture2);
      
        Icon a = new ImageIcon(getClass().getResource("button level vor.jpg"));
        Icon b = new ImageIcon(getClass().getResource("button level vor.jpg"));
        up = new JButton("", a);
        up.setRolloverIcon(b);
        up.setBounds(260, 300, 89, 87);
        up.setBorder(null);
        up.addActionListener(new ButtonHaendler());
        add(up);
      
        Icon c = new ImageIcon(getClass().getResource("button level zurueck.jpg"));
        Icon d = new ImageIcon(getClass().getResource("button level zurueck.jpg"));
        down = new JButton("", c);
        down.setRolloverIcon(d);
        down.setBounds(120, 300, 89, 87);
        down.setBorder(null);
        down.addActionListener(new ButtonHaendler());
        add(down);
        }
  
  
  
    class ButtonHaendler implements ActionListener{
      
        int left = 0;
        int right = 0;

      
        @Override
        public void actionPerformed(ActionEvent e) {
          
            levelNumberRight = new ImageIcon(getClass().getResource("level" + right + ".jpg"));
            picture1.setIcon(levelNumberRight);
          
            levelNumberLeft = new ImageIcon(getClass().getResource("level" + left + ".jpg"));
            picture2.setIcon(levelNumberLeft);
          
            if(e.getSource()== up){
                right = right +1;
              
                if(right == 10){
                    right = 0;
                    left = left +1;
              
                    if(e.getSource()== down){
                        right = right -1; //Hier muss das letzte Ergebniss -1
                    }
                }
            }
        }
    }
  
          

    public static void main(String[] args) {
        Main jf = new Main();
        jf.setTitle("TEST");
        jf.setSize(500, 500);
        jf.setLayout(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
        jf.setLocationRelativeTo(null);
        jf.getContentPane().setBackground(new Color(0, 0, 0));
    }
}
```


----------



## Kababär (9. Apr 2016)

Wieso hast du deine Ifs verschachtel?
Das Problem müsste bei einer Variablenzuweisung liegen, nur weiß ich nicht genau wo.

PS: mach mal deine Variablen int left und int right global.
Denke, wenn du nämlich links drückst, also ein runter, wird ein neues Event ausgeführt und in dem Listener definierst und initialisierst du deine Variablen mit 0.
Wenn du zweimal rechts drückst, dann links steht 0? Wenn du dann wieder zwei mal links drückst und ein mal rechts, steht wieder 0?


----------



## VirtualIndex (9. Apr 2016)

Nimm bitte in Zukunft zum Erhöhen und Verringern von Zahlen ++ und --. Also z. B. --left statt left = left - 1.


----------



## Kababär (9. Apr 2016)

Ist doch egal, ob De/Inkrementoren verwendet. 
Ist doch eine äquivalente Anweisung.


----------



## VirtualIndex (9. Apr 2016)

Es geht darum, dass man versteht, dass solche Konstrukte nicht zum Spaß existieren bzw. enorm wichtig sind. ++zahl und zahl++ sind auch gänzlich unterschiedlich. Ebenso wie das Ändern des Vorzeichen durch das unäre Minus.

Je nach Programmiersprache und Intelligenz des Compilers, was Optimierungen angeht, sind das gänzlich unterschiedliche Operationen, die lediglich zum gleichen Ergebnis kommen. Je nachdem was man gerade vorhat oder verwendet: Der eine Weg zieht 1 von der Zahl ab, der andere Weg muss vorher noch kopieren, multiplizieren, usw. Das eine ist eben einfaches plus minus, das andere Multiplikation.

Vorab: Der letzte Absatz ist stark komprimiert und soll die Logik dahinter verdeutlichen. Konkrete Details oder Erklärungen, siehe Drittquellen.


----------



## silson (10. Apr 2016)

Kababär hat gesagt.:


> Wieso hast du deine Ifs verschachtel?
> Das Problem müsste bei einer Variablenzuweisung liegen, nur weiß ich nicht genau wo.
> 
> PS: mach mal deine Variablen int left und int right global.
> ...


ist doch egal, kann die ifs auch untereinander setzten, ist dasselbe.
weiss nicht wie du das meinst global muss doch in den actionlistener rein alles so wie es ist, oder nicht?



VirtualIndex hat gesagt.:


> Nimm bitte in Zukunft zum Erhöhen und Verringern von Zahlen ++ und --. Also z. B. --left statt left = left - 1.


dann funktioniert das aber nur bis max. 10 und danach geht nix mehr wenn ich den button weiterdrücke mit ++


----------



## Joose (11. Apr 2016)

silson hat gesagt.:


> ist doch egal, kann die ifs auch untereinander setzten, ist dasselbe.


Eben nicht!

Laut deinem Code:

```
if(e.getSource()== up){
                if(right == 10){
                    if(e.getSource()== down){
                        right = right -1; //Hier muss das letzte Ergebniss -1
                    }
                }
            }
```

Soll `right` um 1 reduziert werden wenn der `down` Button gedrückt wurde. Das Problem bei deinem Code ist: Damit diese if-Bedingung greift muss davor die if-Bedingung true ergeben das der `up` Button gedrückt wurde. Das kann aber nie zutreffen -> e.getSource() wird dir entweder up oder down liefern
Sprich bis zu `right = right - 1` wird er nie kommen.



silson hat gesagt.:


> weiss nicht wie du das meinst global muss doch in den actionlistener rein alles so wie es ist, oder nicht?


Vergiss das mit dem global. Du erstellst eine Instanz deines ActionListeners. Jedes ausgelöste Event ruft die entsprechende actionPerformed Methode dieser Instanz auf.
Die beiden Variablen left bzw. right behalten ihre Werte natürlich (egal welchen Button du drückst oder wie oft).

Was dein Problem verursacht: Du erstellst 2 Instanzen deines Buttonhandlers. Eine wird dem up Button, die anderen dem down Button als Listener zugewiesen.
Während du den up Button drückst zählt dessen ButtonHandler Instanz die Variablen brav hoch (und setzt entsprechende Bilder).
Sobald du nun aber down drückst wird die andere ButtonHandler Instanz verwendet. Dort haben die Variablen aber noch den Wert 0.
Lösung: Beide Buttons sollten die gleiche ButtonHandler Instanz verwenden.

Das alleine reicht aber noch nicht: Wie oben schon geschrieben musst du deine if-Bedingungen auch noch richtig stellen.
Außerdem ist glaub ich logischer wenn du die Bilder erst dann setzt wenn du deine Werte erhöht hast, sonst zeigen deine Bilder einen Wert an, die Variablen haben aber einen anderen


----------



## mrBrown (11. Apr 2016)

VirtualIndex hat gesagt.:


> Es geht darum, dass man versteht, dass solche Konstrukte nicht zum Spaß existieren bzw. enorm wichtig sind. ++zahl und zahl++ sind auch gänzlich unterschiedlich. Ebenso wie das Ändern des Vorzeichen durch das unäre Minus.
> 
> Je nach Programmiersprache und Intelligenz des Compilers, was Optimierungen angeht, sind das gänzlich unterschiedliche Operationen, die lediglich zum gleichen Ergebnis kommen. Je nachdem was man gerade vorhat oder verwendet: Der eine Weg zieht 1 von der Zahl ab, der andere Weg muss vorher noch kopieren, multiplizieren, usw. Das eine ist eben einfaches plus minus, das andere Multiplikation.
> 
> Vorab: Der letzte Absatz ist stark komprimiert und soll die Logik dahinter verdeutlichen. Konkrete Details oder Erklärungen, siehe Drittquellen.



Die sind so enorm wichtig, dass z.B. swift sie ganz rausschmeißen wird


----------



## silson (11. Apr 2016)

so habe jetzt die ifs geändert, aber ist dasselbe
geht immer noch nicht runter, bzw. springt sofort auf null

```
class ButtonHaendler implements ActionListener{
       
        int left = 0;
        int right = 0;

       
        @Override
        public void actionPerformed(ActionEvent e) {
           
            levelNumberRight = new ImageIcon(getClass().getResource("level" + right + ".jpg"));
            picture1.setIcon(levelNumberRight);
           
            levelNumberLeft = new ImageIcon(getClass().getResource("level" + left + ".jpg"));
            picture2.setIcon(levelNumberLeft);
           
            if(e.getSource()== up){
                right = right +1;
            }
               
            if(right == 10){
                right = 0;
                left = left +1;
            }
               
            if(e.getSource()== down){
                right = right -1; //Hier muss das letzte Ergebniss -1
            }
        }
    }
```


----------



## VirtualIndex (11. Apr 2016)

mrBrown hat gesagt.:


> Die sind so enorm wichtig, dass z.B. swift sie ganz rausschmeißen wird



Was Swift tut oder nicht ist doch völlig egal dabei. Die Grundprinzipien bleiben gleich. Wer die über Bord werfen will, der wird da was fatal falsch machen. Swift wird vielleicht das Ganze durch etwas substituieren. Am Ende bleibt es jedoch das Gleiche . Wirklich wichtig ist das nur bei sehr maschinennaher Programmierung, wo Speicher teuer ist. Das ändert jedoch nichts an dem Prinzip. Denn wer das nicht versteht, wird es auch in wichtigen Situationen nicht beachten (können).

Das ist wie folgendes: https://dzone.com/articles/java-performance-notes-autoboxing-unboxing


----------



## mrBrown (11. Apr 2016)

Wenn eine der neusten und am schnellsten wachsenden Sprachen etwas Jahrzehnte altes über Bord werfen, ist das also trotzdem noch ein enorm wichtiges Feature? Interessante Sichtweise...
Und nein, es wird kein Ersatz eingeführt, der ist mit i+=1/i-=1 schon vorhanden (was für jeden Compiler das gleiche wie i=i+1 ist).
Der Speicherverbrauch wird nach Compileroptimierung bei allen Varianten gleich sein. Und in den Fällen, wo der Unterschied von ++ zu += relevant sein könnte, wird vermutlich so Maschinennah geschrieben, dass es kein ++ oder += gibt.

Die meisten Fälle, in denen der Unterschied zwischen ++i, i++, i+=1 eine Rolle spielt, dürften unter "Mein Code ist cooler" fallen.


Autoboxing hat so ziemlich gar nichts mit ++ und -- zu tun.


----------



## Meniskusschaden (11. Apr 2016)

silson hat gesagt.:


> so habe jetzt die ifs geändert, aber ist dasselbe
> geht immer noch nicht runter, bzw. springt sofort auf null


Hast du den anderen Hinweis von Joose denn schon berücksichtigt? Das sollte dein Problem doch lösen:





Joose hat gesagt.:


> Was dein Problem verursacht: Du erstellst 2 Instanzen deines Buttonhandlers. Eine wird dem up Button, die anderen dem down Button als Listener zugewiesen.
> Während du den up Button drückst zählt dessen ButtonHandler Instanz die Variablen brav hoch (und setzt entsprechende Bilder).
> Sobald du nun aber down drückst wird die andere ButtonHandler Instanz verwendet. Dort haben die Variablen aber noch den Wert 0.
> Lösung: Beide Buttons sollten die gleiche ButtonHandler Instanz verwenden.


----------



## Joose (11. Apr 2016)

Genau @silson dein eigentliches Problem + Lösung habe ich schon beschrieben. Dürftes es wohl überlesen haben


----------



## silson (13. Apr 2016)

Also ich weiss nicht wie ich es mit der gleichen Instanz mache


----------



## Joose (13. Apr 2016)

Wo liegt denn das Problem eine Instanz von dieser Klasse zu erstellen und diese Instanz zu übergeben? (und zwar bei jedem Aufruf die gleiche Instanz)

```
ButtonHandler handler = new ButtonHandler();
button.addActionListener(handler);
```


----------



## VfL_Freak (13. Apr 2016)

Moin,


mrBrown hat gesagt.:


> Die meisten Fälle, in denen der Unterschied zwischen ++i, i++, i+=1 eine Rolle spielt, dürften unter "Mein Code ist cooler" fallen


Weniger, da das Verhalten bei Post- und Pre-Inkrement unterschiedlich ist.
Beispiel:

```
int i = 5;
int c = i++;  // c = 5 !
int j = 5;
int d = ++j;    // d = 6 !!
```

Gruß Klaus


----------



## mrBrown (13. Apr 2016)

VfL_Freak hat gesagt.:


> Moin,
> 
> Weniger, da das Verhalten bei Post- und Pre-Inkrement unterschiedlich ist.
> Beispiel:
> ...



"Der Unterschied" in meinem Post meint genau diesen Unterscheid.


----------



## silson (13. Apr 2016)

in welcher zeile füge ich denn code


```
ButtonHandler handler = new ButtonHandler();
button.addActionListener(handler);
```

ein...bin anfänger wie du weisst


----------



## Joose (13. Apr 2016)

Das ButtonHandler Objekt musst du natürlich erstellen bevor du das objekt als Parameter an die Methode "addActionListener" übergibst.
Du hast doch oben schon einen Code wo du etwas an "addActionListener" übergibst. Wenn du deinen eigenen Code verstehst, sollte diese beiden Zeilen kein Problem bereiten.


----------



## silson (13. Apr 2016)

ich weiss nicht wie du das meinst...
habe einen button links und einen button rechts erstellt.
dann habe ich einen actionlistener erstellt und in dem actionlistener ist
der code, wenn man auf den button links drückt geht die zahl runter und wenn man auf den button rechts drückt geht die zahl hoch.
und damit das funktioniert habe ich den befehl add.actionlistener in eine zeile bei den button reingeschrieben das er dann auf den listener zugreift.
hoffe das ist jetzt alles richtig, was ich geschrieben habe?
jetzt kommst du und ich verstehe nur bahnhof...lol
habe mir schon gedacht das er auf null springt, wenn ich den einen button drücke, aber das ist mein problem weiss nicht wie ich das umgehen kann und dein tip schein gold wert zu sein, aber nur für leute die es verstehen...ich leider nicht


----------



## Meniskusschaden (13. Apr 2016)

silson hat gesagt.:


> dann habe ich einen actionlistener erstellt


Ja, du hast EINE ActionListener-Klasse programmiert. Aber du hast mittels `new ButtonHaendler()`ZWEI ActionListener-Objekte erzeugt.


----------



## silson (15. Apr 2016)

muss ich nur für hoch ein listener und für runter einen zweiten listener erstellen oder wie soll ich das verstehen


----------



## Joose (15. Apr 2016)

silson hat gesagt.:


> muss ich nur für hoch ein listener und für runter einen zweiten listener erstellen oder wie soll ich das verstehen



Hm ich habe doch schon genau beschrieben was das Problem ist und wie es zu lösen wäre.



Joose hat gesagt.:


> .... Was dein Problem verursacht: Du erstellst 2 Instanzen deines Buttonhandlers. Eine wird dem up Button, die anderen dem down Button als Listener zugewiesen.
> Während du den up Button drückst zählt dessen ButtonHandler Instanz die Variablen brav hoch (und setzt entsprechende Bilder).
> Sobald du nun aber down drückst wird die andere ButtonHandler Instanz verwendet. Dort haben die Variablen aber noch den Wert 0.
> Lösung: Beide Buttons sollten die gleiche ButtonHandler Instanz verwenden.
> ....



Oder ist es unverständlich was "die gleiche ..... Instanz" bedeuten soll?


----------



## Meniskusschaden (15. Apr 2016)

Joose hat gesagt.:


> Oder ist es unverständlich was "die gleiche ..... Instanz" bedeuten soll?


Etwas korrekter wäre meines Erachtens "dieselbe". "Die Gleiche" ist es eigentlich ja schon, aber eben nicht dieselbe.


----------



## Meniskusschaden (15. Apr 2016)

silson hat gesagt.:


> muss ich nur für hoch ein listener und für runter einen zweiten listener erstellen oder wie soll ich das verstehen


Nein, du solltest von der einen Listener-Klasse auch nur ein Objekt erstellen, das du beiden Buttons zuordnest.


----------



## silson (15. Apr 2016)

*Joose*, danke für deine Tips...habe es jetzt geschafft und die bilder habe ich nach den variabeln gesetzt, so wie du es gesagt hast. hatte wirklich falsch angezeigt... noch mal besten dank


----------

