setValueAT geht nicht... wieso?

LexeB4F

Mitglied
Hallo zusammen,

Ich bin gerade echt verwirrt.... bitte schaut Euch dies mal an:

Java:
table.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                int x = e.getKeyChar();
                System.out.println(x);
               
               
                if (x == 127) {
                    System.out.println("DEL");
                    System.out.println(table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
                    table.setValueAt("20", 1, 1);                            //dieser Value wird gesetzt
                    int row = table.getSelectedRow();
                    int col = table.getSelectedColumn();
                    table.setValueAt("20", row, col);                    // dieser nicht
                    System.out.println(table.getSelectedRow() + " " + table.getSelectedColumn());
                   
                }

                // TODO Auto-generated method stub

            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub

            }
        });

Ich versteh nicht wieso der zweite Value nicht gesetzt wird...

System.out.println(table.getSelectedRow() + " " + table.getSelectedColumn());
wird schön ausgegeben....

Bitte helft mir auf die Sprünge an was es liegt!
Danke
 
Kann es sein das "row" und "col" jeweils den Wert 1 haben?
Du kannst dir per getValue auch den Wert der Zelle ausgeben. Möglicherweise wird der Wert gesetzt aber die UI nicht neu gezeichnet.
 
Nein raw und col werden dann ja mit Sys.out.pl angezeigt ...sie sind nicht 1,1. Kann es ev. sein, dass es nicht geht weil die Zelle selected ist?
Ausgabe der selected Zelle habe ich gerade geprüft ist der alte Wert.
 
Ich vermute, es liegt daran, dass die Tabelle eine eigene Ereignisbehandlung enthält, die auf die DEL-Taste reagiert und die selektierte Zelle dadurch blockiert. Vielleicht hilft es, mit e.consume() in der keyPressed-Methode das Ereignis abzufangen.
 
Damit der Thread komplett und gelöst ist...
Im erste Post konnte das nix werden, da:
if (x == 127){
x= e.getKeyChar() --> wird nie 127 sein...

Doch an dem alleine lag es leider nicht...

Nach langem versuchen habe ich es rausgefunden wie es funktioniert.

Java:
table.addKeyListener(new KeyListener() {
                ;
                @Override
                public void keyPressed(KeyEvent e) {
                             
                if (e.getKeyCode() == 127){
                    col1 = table.getSelectedColumn();
                    row1 = table.getSelectedRow();
                    table.setValueAt("", row1, col1);
                }
                 
                }
             
                @Override
                public void keyTyped(KeyEvent e) {
                 
                }
             
                @Override
                public void keyReleased(KeyEvent e) {
                 
                }
            });

Als ich diesen KeyListener in den TableCellRenderer gesteckt habe... unter if (hasFocus){...

hats nun endlich geklappt...

Leider verstehe ich immer noch nicht wieso ich den KeyListener in den if (hasFocus) {
teil packen muss... der sollte doch auch wo anders funktionieren...

Also wenn jemand mir da auf die Sprünge helfen kann... wär ich froh.

LG
Lexe
 
Im erste Post konnte das nix werden, da:
if (x == 127){
x= e.getKeyChar() --> wird nie 127 sein...
Die Bemerkung verstehe ich nicht. Dieser Code kommt im ersten Post doch gar nicht vor, oder habe ich da etwas übersehen.

Als ich diesen KeyListener in den TableCellRenderer gesteckt habe... unter if (hasFocus){...

hats nun endlich geklappt...

Leider verstehe ich immer noch nicht wieso ich den KeyListener in den if (hasFocus) {
teil packen muss... der sollte doch auch wo anders funktionieren...
Mir ist nicht klar, was du bzgl. TableCellRenderer und hasFocus gemacht hast. Ich glaube, damit hat es nichts zu tun, sondern der entscheidende Unterschied ist, dass du deine Routine von der Methode keyTyped in die Methode keyPressed verlegt hast, die zeitlich vor keyTyped ausgeführt wird und offenbar dem in meinem vorigen Post vermuteten Konflikt mit der Standardereignisbehandlung zuvorkommt.

Ich habe den Vorschlag aus meinem vorigen Post jetzt interessehalber auch mal getestet (e.consume() in keyPressed-Methode einfügen). Dann funktioniert bereits der Code aus deinem ersten Post.
 
Danke für die Antwort.

Diesen Abschnitt habe ich gemeint:

int x = e.getKeyChar();
System.out.println(x);


if (x == 127) {
System.out.println("DEL");


Danke für den Hinweis mit keytyped und keyPressed habe ich selber gar nicht bemerkt...
Jetzt weiss ich erst recht nicht mehr an was es lag, dass es zuerst nicht geklappt hat 😛

Das mit e.consume() habe ich selber nicht hinbekommen.
Wenn du den codeAbschnit postest würde ich mir deine Lösung gerne ansehen.
 
Das ist noch einmal dein ursprünglicher Code aus dem ersten Post, in dem ich als einzige Änderung ganz hinten e.consume() hinzugefügt habe:
Java:
table.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                int x = e.getKeyChar();
                System.out.println(x);
                              
                if (x == 127) {
                    System.out.println("DEL");
                    System.out.println(table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
                    table.setValueAt("20", 1, 1);                            //dieser Value wird gesetzt
                    int row = table.getSelectedRow();
                    int col = table.getSelectedColumn();
                    table.setValueAt("20", row, col);                    // dieser nicht
                    System.out.println(table.getSelectedRow() + " " + table.getSelectedColumn()); 
                }

            }

            @Override
            public void keyReleased(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                e.consume();
            }
        });
Falls du keinen besonderen Grund hattest, es in keyType zu realisieren kannst du es natürlich auch im keyPressed belassen. Dann ist e.consume() überflüssig.
 
Ich hab dies bereits nachgeschlagen, jedoch verstehe ich es nicht ganz...
keyPressed wird einfach nicht ausgeführt? Richtig?

Aber wieso bringt e.consum(); meinen Code zum laufen!?
 
Es ist vielleicht ganz hilfreich, zunächst mit folgendem Code etwas herum zu spielen:
Java:
    table.addKeyListener(new KeyListener() {
  
       @Override
       public void keyPressed(KeyEvent e) {
         System.out.println("keyPressed");
       }

       @Override
       public void keyReleased(KeyEvent e) {
         System.out.println("keyReleased");  
       }

       @Override
       public void keyTyped(KeyEvent e) {
         System.out.println("keyTyped");    
       }

  });
Wenn man damit ein paar Tasten ausprobiert (Buchstaben, Funktionstasten, NumLock, etc.; mal kurz drücken, mal festhalten) bekommt man ein Gefühl, welche Ereignisse ausgelöst werden und in welcher Reihenfolge das geschieht.

Wenn alle drei Ereignisse ausgelöst werden, passiert es in der folgenden Reihenfolge:
keyPressed
keyTyped
keyReleased

Die Vermutung ist ja, dass es zunächst nicht funktioniert hat, weil deine Routine die selektierte Zelle manipulieren soll (andere Zellen konnte sie ja ändern) und dass das durch das Standardverhalten der Komponente verhindert wird, die ja wahrscheinlich auch etwas tut, sobald man eine Taste in der selektierten Zelle drückt. Mittels der consume()-Methode wird die Eigenschaft consumed des Ereignisses auf true gesetzt. Die Komponente ist offenbar so programmiert, dass sie ihre Standardbehandlung nur für nicht konsumierte Ereignisse durchführt.

Wir müssen also dafür sorgen, dass consume() rechtzeitig aufgerufen wird, um das Standardverhalten zu unterbinden. Deshalb tun wir das in der keyPressed-Methode, denn in der keyTyped-Methode wäre es schon zu spät.

consume() verhindert nicht, dass die Ereignisbehandlung aufgerufen wird, aber der Programmierer der Ereignisbehandlung kann den Aufruf von consume() respektieren. In folgendem Beispiel werden für keyPressed und keyReleased je zwei Lsitener registriert, wobei die ersten consume() aufrufen. Der zweite keyPressed ignoriert consume(), der zweite keyReleased respektiert es:

Java:
    table.addKeyListener(new KeyListener() {
     
       @Override
       public void keyPressed(KeyEvent e) {
         e.consume();
         System.out.println("keyPressed 1");
       }

       @Override
       public void keyReleased(KeyEvent e) {
         e.consume();
         System.out.println("keyReleased 1");     
       }

  });
     
     table.addKeyListener(new KeyListener() {
       
       @Override
       public void keyPressed(KeyEvent e) {
         System.out.println("keyPressed 2");
       }

       @Override
       public void keyReleased(KeyEvent e) {
         if (!e.isConsumed()) {
           System.out.println("keyReleased 2");
         }
       }

  });
 
Danke für die ausführliche Antwort! Begriffen habe ich es noch nicht ganz aber werde mal etwas mit e.consum rumspielen und es versuchen zu verstehen wie genau wann was wie wo geht im keylistener 😉
 
Begriffen habe ich es noch nicht ganz ....

Hier eine andere Darstellung (von consume): Stelle dir 2 Arbeiter (Listener) an einem Fließband vor. Der eine Arbeiter ist von dir eingeschult (programmiert) worden vorbeifahrende Geschenke (Event) einzupacken und mit einer Masche zu versehen (sie zu konsumieren), wenn sie nicht schwerer als 1kg sind. Der andere Arbeiter soll die Geschenke auspacken, aber nur wenn keine Masche auf dem Geschenk ist.

Sprich mit "consume" kannst du sagen das Event wurde bereits von einem Listener verarbeitet. Alle Listener können prüfen ob es verarbeitet wurde und machen dann entweder nichts damit oder sie ignorieren das es schon verarbeitet wurde und machen das was sie tun sollen.
 

Neue Themen


Zurück
Oben