Swing Wert in JTextField wird falsch ausgegeben

ralfb1105

Bekanntes Mitglied
Hallo zusammen,

ich verzweifle gerade an einem Problem mit einem JTextField in das ich einen Wert eingebe der zum erstellen einen TableSpace herangezogen wird.

Hier das Code zum JTextField:
Java:
private JTextField getJTFTSsize() {
        if(jTFTSsize == null) {
            jTFTSsize = new JTextField();
            jTFTSsize.setHorizontalAlignment(JTextField.RIGHT);
            jTFTSsize.setText("100");
            jTFTSsize.setBounds(289, 155, 39, 23);
            jTFTSsize.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
            jTFTSsize.setFont(new java.awt.Font("Segoe UI",0,12));
            System.out.println(Integer.valueOf(jTFTSsize.getText()));
            jTFTSsize.addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e1) {
                    System.out.println(Integer.valueOf(jTFTSsize.getText()));
                    setDataJComboBox1();
                }
            });
        }
        return jTFTSsize;
    }

Im initGUI() wird das TextField folgendermassen initialisiert:
Java:
getContentPane().add(getJTFTSsize());

Wenn ich das GUI starte wird der Wert 100 gesetzt und zur Kontrolle auch so auf der Konsole ausgegeben.

Ändere ich nun den Wert im TextField, wird auf Grund des KeyEvent der neue Wert auf der Konsole ausgegeben, aber leider immer /10 !? Klingt komisch, ist aber so.
Wenn ich aus der 100 eine 10 mache ist es noch OK - Ausgabe 10. Weiter auf 1 - auch OK -> 1. Gehe ich dann wieder hoch auf 10 wird eine 1 ausgegeben, hoch auf 100 eine 10, usw. Ist auch bei anderen Werten wie 109 -> 10 so.

Ich muss sagen ich habe keine Idee warum das so ist?
Was mache ich hier falsch, wo liegt mein blöder Fehler - ich vermute mal es hat mit dem KeyEvent zu tun, denn das hab eich neu hinzugefügt.

Bin dankbar für jede Hilfe und jeden Tipp!!

Gruß

Ralf
 
Erst mal ein wenig Erklärung: das JTextField wird selbst von einem KeyListener aufgrund von "key-typed"-Events aktualisiert (tatsächlich ist es komplizierter aber fürs Verständnis soll das reichen). Wenn Du einen weiteren KeyListener registrierst, wird auch dieser über KeyEvents informiert. Allerdings ist die Reihenfolge der Benachrichtigungen nicht spezifiziert, d. h. es gibt keine Garantie, welcher Listener zuerst benachrichtigt wird.

Es kann also sein, dass dein Listener im Fall des "Einfügens" benachrichtigt wird, bevor das JTextField den Text geändert hat. Dann fehlt bei getText() die letzte Änderung (wenn man einer Zahl eine Stelle hinzufügt, fehlt diese bei getText(), das sieht dann so aus, als würde getText() nur ein Zehntel zurückgeben).

Das ist ein Grund, warum der KeyListener für Dein Vorhaben nicht geeignet ist. Der andere ist, dass KeyEvents auch auftreten, wenn sich am Text nichts ändert, beispielsweise bei Steuertasten.

Du willst auf Änderungen des Texts reagieren, nicht auf das Tippen irgendwelcher Tasten. Das JTextField verwaltet den Text nicht selbst, sondern verwendet hierfür ein Document. Das Document kann DocumentListener über DocumentEvents informieren.

Letzteres ist so auch dokumentiert (https://docs.oracle.com/javase/8/docs/api/javax/swing/JTextField.html):

In the JTextComponent based components, changes are broadcasted from the model via a DocumentEvent to DocumentListeners. The DocumentEvent gives the location of the change and the kind of change if desired. The code fragment might look something like:

Java:
     DocumentListener myListener = ??;
     JTextField myArea = ??;
     myArea.getDocument().addDocumentListener(myListener);
 
Hallo mihe7,

Vielen Dank für die ausführliche Erklärung des Verhaltens - wieder mal sehr viel gelernt 🙂
Ich habe dem JTextField nun einen DocumentListener hinzugefügt und damit wird die JComboBox über die Methode
setDataJComboBox1() neu aufgebaut wenn sich die Werte in dem JTextField ändern - so wie gewollt!

Hier der neue Code:

Java:
private JTextField getJTFTSmaxSize() {
        if(jTFTSmaxSize == null) {
            jTFTSmaxSize = new JTextField();
            jTFTSmaxSize.setHorizontalAlignment(JTextField.RIGHT);
            jTFTSmaxSize.setText("200");
            jTFTSmaxSize.setBounds(417, 155, 39, 23);
            jTFTSmaxSize.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
            jTFTSmaxSize.setFont(new java.awt.Font("Segoe UI",0,12));
           
            //add a DocumentListener to the JTextField and on the events call setDataJComboBox1() to modify ComboBox and
            //  re-calculate the values in the ComboBox
            DocumentListener documentListenerjTFTSmaxSize = new DocumentListener() {
                  public void changedUpdate(DocumentEvent documentEvent) {
                      setDataJComboBox1();
                  }
                  public void insertUpdate(DocumentEvent documentEvent) {
                      setDataJComboBox1();
                  }
                  public void removeUpdate(DocumentEvent documentEvent) {
                      setDataJComboBox1();
                  }
                };
            jTFTSmaxSize.getDocument().addDocumentListener(documentListenerjTFTSmaxSize);
               
        }
        return jTFTSmaxSize;
    }

Danke nochmal für Deine Hilfe!

Gruß

Ralf
 

Neue Themen


Zurück
Oben