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

0

Witam. Mam taki kod:

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 +, -, /, *?

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.

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:

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?

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

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.

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:

while (metoda(keyFinalString)){
    // Tutaj reszta z tych pętli z uwzględnieniem break'a po spełnieniu ifa z wyświetlaniem
}
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?

0

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

0

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

0

Teraz mam taki kod:

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?

0

Debugger w dłoń i do roboty :)

0

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

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?

0

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

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ć?

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

 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ść.

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ę:

class Klasa {

}

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

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.
Java

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ę:

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ć.

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).

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ę"?

0

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1