problem z mocno zagnieżdżoną pętlą

problem z mocno zagnieżdżoną pętlą
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Witam. Mam taki kod:

Kopiuj
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class KalkulatorBackend extends JFrame {

    public KalkulatorBackend() {
        setSize(400, 300);
        setTitle("Calculator");
        setResizable(false);
    }

    public static void main(String[] args) {

        KalkulatorBackend window = new KalkulatorBackend();
        window.setDefaultCloseOperation(EXIT_ON_CLOSE);
        window.setVisible(true);



        JTextField textField = new JTextField();
        textField.setBounds(100, 100, 150, 20);
        textField.setLayout(null);
        window.add(textField);


        textField.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                displayInfo(e);
            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {

            }

            protected void displayInfo(KeyEvent e) {

                String keyFinalString = "";
                String lancuchZnakow = null;

                int id = e.getID();

                if (id == KeyEvent.KEY_TYPED) {
                    char key = e.getKeyChar();
                    keyFinalString = keyFinalString + key;
                }

                if (keyFinalString != ""){
                    System.out.println(keyFinalString);
                }

                lancuchZnakow = lancuchZnakow + keyFinalString;


                while (!(keyFinalString == "+")){
                    while (!(keyFinalString == "-")){
                        while (!(keyFinalString == "*")){
                            while (!(keyFinalString == "/")){
                                keyFinalString = "";
                                lancuchZnakow = null;

                                id = e.getID();

                                if (id == KeyEvent.KEY_TYPED) {
                                    char key = e.getKeyChar();
                                    keyFinalString = keyFinalString + key;
                                }

                                if (keyFinalString != ""){
                                    System.out.println(keyFinalString);
                                }

                                //lancuchZnakow = lancuchZnakow + keyFinalString;
                            }
                        }
                    }
                }
            }
        });
    }
}

Problem polega na tym, że gdy wpiszę liczbę to jest ona bez końca wyświetlana. Gdzieś czytałem, że w głęboko zagnieżdżonych pętlach dzieją się różne rzeczy...
I jeszcze jedno. Jak zrobić aby keyListener sczytywał tylko liczby i +, -, /, *?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Problem polega na tym, że gdy wpiszę liczbę to jest ona bez końca wyświetlana.

Tak to zaprogramowałeś.

Gdzieś czytałem, że w głęboko zagnieżdżonych pętlach dzieją się różne rzeczy...

Hmm ciekawe. patrze w specyfikację języka Java i nie widzę https://docs.oracle.com/javase/specs/jls/se10/jls10.pdf - nested loops są, ale
strange things in nested loops - nie widzę. Który to rozdział?

I jeszcze jedno. Jak zrobić aby keyListener sczytywał tylko liczby i +, -, /, *?

Tylko te liczby czytaj. Proste.

Tak właściwie : to co właściwie chiałeś w tym kodzie zrobić ? Raczej te pętle są tam niepotrzebne.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Tak właściwie : to co właściwie chiałeś w tym kodzie zrobić ?

Chcę zrobić aby po wciśnięciu klawisza otrzymać znak (np. 1). Ogólnie ma być to kalkulator w konsoli ale ma być obsługiwany nie przez klasę Scanner ale przez KeyListener (czyli przez klawiaturę). I tu miałem problem bo nie wiedziałem (i dalej nie bardzo wiem) jak zmienną key użyć do obliczeń. Obliczenia wiem jak zrobić i mam też zmienną w której jest przechowywana wartość wciśniętego klawisza. Pomyślałem sobie że można te znaki (zmienna key) dodawać do siebie jako łańcuch Stringów i po wciśnięciu ,,=" z string1 + string2 = string3 przekonwertowało by się na int1 + int2 = int3. Chciałem tak zrobić dlatego, że nie wiem co zrobić w sytuacji gdy użytkownik chcę dodać do siebie dwie liczby wielocyfrowe np. 21 + 37. Jak zrobić aby postawić obok siebie w jednym int 2 i 1, przez to całe zamieszanie w kodzie.

Więc mam taki kod wyjściowy:

Kopiuj
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class KalkulatorBackend extends JFrame {

    public KalkulatorBackend() {
        setSize(400, 300);
        setTitle("Calculator");
        setResizable(false);
    }

    public static void main(String[] args) {

        KalkulatorBackend window = new KalkulatorBackend();
        window.setDefaultCloseOperation(EXIT_ON_CLOSE);
        window.setVisible(true);



        JTextField textField = new JTextField();
        textField.setBounds(100, 100, 150, 20);
        textField.setLayout(null);
        window.add(textField);


        textField.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                displayInfo(e);
            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {

            }

            protected void displayInfo(KeyEvent e) {

                int id = e.getID();

                if (id == KeyEvent.KEY_TYPED) {
                    char key = e.getKeyChar();

                System.out.println(key);
                }
            }
        });
    }
}

Po wpisaniu liczby w JTextField pojawia się ona w konsoli. I co dalej?

edytowany 1x, ostatnio: IlikeJava
S9
21 +37 ( ͡° ͜ʖ ͡°)
M9
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 5 lat
  • Postów:18
0

Ogolnie pierwszy blad jaki widac to to ze uzywasz == do porownania Stringów powinieneś użyć metody equals
Tak poza tym to zamiast pisać milion pętel które i tak nic nie robią możesz napisać 1 pętlę a w niej ify stawiać
A masz zapętlenie bo każdy twój While zawsze jest true tzn z przyrownania zawsze masz false a Ty negujesz to i masz true i tak w kółko ;p

jarekr000000
Akurat to nawet nie jest jego problem.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Najprościej. Stwórz sobie zaraz w main zmienną typu StringBuilder i dodawaj do niej kolejne znaki (append). Actionlister jest wywoływany od nowa, niezależnie po każdym nacisnieciu klawisza.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
kiyo
  • Rejestracja:około 8 lat
  • Ostatnio:dzień
  • Postów:155
1

Problem polega na tym, że gdy wpiszę liczbę to jest ona bez końca wyświetlana.

Możesz też użyć instrukcji break, żeby wyjść z pętli.

EDIT. Ale wiesz, że te warunki w pętli można łączyć ze sobą operatorem && i zamiast 4 czy 5 while'ów miałbyś tylko jeden z bardziej rozbudowanym warunkiem. Z kolei ten warunek można by przenieść do jakiejś metody prywatnej wtedy wyglądałoby to trochę bardziej elegancko:

Kopiuj
while (metoda(keyFinalString)){
    // Tutaj reszta z tych pętli z uwzględnieniem break'a po spełnieniu ifa z wyświetlaniem
}
edytowany 3x, ostatnio: kiyo
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Actionlister jest wywoływany od nowa, niezależnie po każdym nacisnieciu klawisza.

Ale jak zrobić aby dalej nie puszczało do tego StringBuildera innych znaków niż cyfry?
Switchem czy jest jakiś prostszy sposób?

edytowany 1x, ostatnio: IlikeJava
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Możesz switchem, możesz jeszcze wszystkie cyfry obalić tym: java.lang.Character.isDigit(char ch)


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

A co do ostatniego wklejonego przeze mnie kodu, obliczenia i wszystko pisać w protected void displayInfo(KeyEvent e)?

IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Teraz mam taki kod:

Kopiuj
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KalkulatorBackend2 extends JFrame {

    KalkulatorBackend2() {

        setSize(400, 300);
        setTitle("Calculator");
        setResizable(false);
        setLayout(null);

        JTextField textField = new JTextField();
        textField.setBounds(20, 40, 350, 25);
        add(textField);
        textField.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                displayInfo(e);

            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {

            }
        });
    }

    public static void main(String[] args) {

        KalkulatorBackend2 KalKulatorBackend2 = new KalkulatorBackend2();
        KalKulatorBackend2.setDefaultCloseOperation(EXIT_ON_CLOSE);
        KalKulatorBackend2.setVisible(true);

    }

    String firstChain = "";

    protected void displayInfo(KeyEvent e) {

        try {

            int id = e.getID();
            String keyFinal = null;

            if (id == KeyEvent.KEY_TYPED) {
                char key = e.getKeyChar();

                keyFinal = keyFinal + key;

                System.out.println(key);
            }

            switch (keyFinal){

                case ("0"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("1"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("2"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("3"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("4"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("5"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("6"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("7"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("8"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("9"):

                    firstChain = firstChain + keyFinal;
                    break;

                case ("+"):


                    break;

                case ("-"):


                    break;

                case ("*"):


                    break;

                case ("/"):


                    break;

                default:

                    System.out.println("switch error");

            }

            keyFinal = null;

        } catch (java.lang.NullPointerException s) {

            System.out.println("(java.lang.NullPointerException): chyba prubujesz odwołać się do obiektu którego nie ma");
        }
    }
}

Nie ważne czy próbuje dodać znak do łańcucha znaków przez StringBuilder czy po prostu +, zawsze jest "switch error" (czyli opcja default w switchu). Dlaczego tak jest?

edytowany 1x, ostatnio: IlikeJava
danek
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Poznań
  • Postów:797
0

Debugger w dłoń i do roboty :)


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
edytowany 1x, ostatnio: danek
CountZero
  • Rejestracja:prawie 8 lat
  • Ostatnio:11 miesięcy
  • Postów:262
0

Za ten try catch z NPE to powinny być przymusowe roboty w kopalniach Oracle... No i to

Kopiuj
String keyFinal = null ;

Zamień albo na String keyFinal;, albo String keyFinal = "";

Sprawdzałeś w debugerze albo w konsoli jak jest wartość keyFinal w momencie switcha?

jarekr000000
final String key = null; byłoby piękniejsze. ;-)
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Dobra, już działa. Teraz mam taki kod:

Kopiuj
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KalkulatorBackend2 extends JFrame {

    KalkulatorBackend2() {

        setSize(400, 300);
        setTitle("Calculator");
        setResizable(false);
        setLayout(null);

        JTextField textField = new JTextField();
        textField.setBounds(20, 40, 350, 25);
        add(textField);
        textField.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                displayInfo(e);

            }

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {

            }
        });
    }

    public static void main(String[] args) {

        KalkulatorBackend2 KalKulatorBackend2 = new KalkulatorBackend2();
        KalKulatorBackend2.setDefaultCloseOperation(EXIT_ON_CLOSE);
        KalKulatorBackend2.setVisible(true);

    }

    String firstChain = "";
    StringBuilder firstChainSB = new StringBuilder(firstChain);

    String firstChain2 = "";
    StringBuilder firstChainSB2 = new StringBuilder(firstChain);

    protected void displayInfo(KeyEvent e) {

        int a = 0;

        if (a == 2) {


        }

        try {

            int id = e.getID();
            String keyFinal = "";

            if (id == KeyEvent.KEY_TYPED) {
                char key = e.getKeyChar();

                keyFinal = keyFinal + key;

                System.out.println(key);
            }

            switch (keyFinal){

                case ("0"):

                    if (a == 0){

                        firstChainSB.append("0");

                    } else if (a == 1) {

                        firstChainSB2.append("0");
                    }

                    break;

                case ("1"):

                    if (a == 0){

                        firstChainSB.append("1");

                    } else if (a == 1) {

                        firstChainSB2.append("1");
                    }

                    break;

                case ("2"):

                    if (a == 0){

                        firstChainSB.append("2");

                    } else if (a == 1) {

                        firstChainSB2.append("2");
                    }

                    break;

                case ("3"):

                    if (a == 0){

                        firstChainSB.append("3");

                    } else if (a == 1) {

                        firstChainSB2.append("3");
                    }

                    break;

                case ("4"):

                    if (a == 0){

                        firstChainSB.append("4");

                    } else if (a == 1) {

                        firstChainSB2.append("4");
                    }

                    break;

                case ("5"):

                    if (a == 0){

                        firstChainSB.append("5");

                    } else if (a == 1) {

                        firstChainSB2.append("5");
                    }

                    break;

                case ("6"):

                    if (a == 0){

                        firstChainSB.append("6");

                    } else if (a == 1) {

                        firstChainSB2.append("6");
                    }

                    break;

                case ("7"):

                    if (a == 0){

                        firstChainSB.append("7");

                    } else if (a == 1) {

                        firstChainSB2.append("7");
                    }

                    break;

                case ("8"):

                    if (a == 0){

                        firstChainSB.append("8");

                    } else if (a == 1) {

                        firstChainSB2.append("8");
                    }

                    break;

                case ("9"):

                    if (a == 0){

                        firstChainSB.append("9");

                    } else if (a == 1) {

                        firstChainSB2.append("9");
                    }

                    break;

                case ("+"):
                    a++;


                    break;

                case ("-"):


                    break;

                case ("*"):


                    break;

                case ("/"):


                    break;

                default:

                    System.out.println("switch error");

            }

            keyFinal = null;
            System.out.println(firstChainSB);

        } catch (java.lang.NullPointerException s) {

            System.out.println("(java.lang.NullPointerException): chyba prubujesz odwołać się do obiektu którego nie ma");
        }
    }
}

Zobaczcie na te IFy w Switchu. Założenie jest takie, że wciśnięte liczby dodawane są do pierwszego StringBuildera, po wciśnięciu znaku dodawania drugiego i tak bez końca ale musiałbym tworzyć nieskończonego IFa więc jak zrobić żeby te Stringi i StringBuildery były tworzone automatycznie i po wciśnięciu ,,=" wszystkie by się do siebie dodawały. Trzeba samemu metodę zrobić czy jest już taka klasa którą można do tego użyć?

IJ
@jarekr000000: Mógłbyś coś doradzić?
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Zbliżasz się.
Rozumiem tój koncept z int a;

Tylko, że on teraz nie działa, bo int a= 0 jest zadeklarowane w metodzie

Kopiuj
 protected void displayInfo(KeyEvent e) {
 
        int a = 0;

Przy każdym naciśnięciu klaswisza - jest ustawiane na 0 ((a potem nawet jak coś zmienisz to znika).

Przesuń tego int a = 0; poza metode - tak gdzie masz StringBuildery i będzie krok do przodu.
Dorób obsługe = - załóż, że zawsze jest dodawanie zrobione na początek, nieważne co w środkowym kroku ktoś wcisńął.
Powinno CI dalej już pójść.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Jak to jest z tymi klasami bo nie ogarniam. Jak mogę stworzyć sobie klasę w której będę mógł normalnie pisać kod? Tworząc klasę:

Kopiuj
class Klasa {

}

Nie mogę w niej pisać np IFów. Trzeba taką klasę jakoś zadeklarować w klasie main czy jak?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Generalnie sa klasy, a w nich są metody.
W metodach możęsz pisać ify i inne zdania. W samych klasach nie.

Polecam Ci zdecydowanie zrobienie sobie jakiegoś kursu javy, poczytanie, zawzięty jestęś, ale bez uporządkowania wiedzy będziesz walił głową w mur ciągle.
https://4programmers.net/Java


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
LS
@jarekr000000: A w Javie same klasy to w ogóle istnieją czy to tylko prefix dla nazw funkcji i struktura dla trzymania pól na etapie bajtkodu?
Haskell
  • Rejestracja:prawie 10 lat
  • Ostatnio:12 miesięcy
  • Postów:4700
0
IlikeJava napisał(a):

Jak to jest z tymi klasami bo nie ogarniam. Jak mogę stworzyć sobie klasę w której będę mógł normalnie pisać kod? Tworząc klasę:

Kopiuj
class Klasa {

}

Nie mogę w niej pisać np IFów. Trzeba taką klasę jakoś zadeklarować w klasie main czy jak?

Kod piszesz w metodach klas. Punktem wejściowym głównej klasy programu jest statyczna metoda main. W przypadku pozostałych klas punktem wejściowym będzie zazwyczaj konstruktor czyli specjalna metoda uruchamiana w trakcie tworzenia obiektu danej klasy. Żeby uruchomić metodę jakiejś klasy musisz stworzyć obiekt tej klasy, wyjątkiem są metody statyczne, które można wywoływać bez konieczności tworzenia obiektu.

Napisz może bardziej konkretne po co jest ta klasa i co chcesz w niej zrobić.


Zaglądali do kufrów, zaglądali do waliz, nie zajrzeli do d**y - tam miałem socjalizm. Czesław Miłosz
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Mielibyście podlinkować jakiś porządny artykuł lub kurs o klasach, metodach i obiektach? Tak żeby wszystko było szczegółowo opisane (nawet takie podstawy podstaw).

edytowany 1x, ostatnio: IlikeJava
IJ
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 lat
  • Postów:139
0

Ostatni kod ma w ogóle jakiś sens? Dobrze robię, że wszystko będzie w Stringach, a przed samymi obliczeniami przerobią się na int? Nie robię tego ,,na piechotę"?

edytowany 1x, ostatnio: IlikeJava
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
0

Kod jest straszny, ale się uczysz... i masz jakiś koncept, więc rób do przodu. Stringi mogą być.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.