# KeyListener + ActionListener + AdjustmentListener -> Prob



## Gentle (22. Jan 2007)

Holla.

Ich will ne Klasse schreiben --- Zeichenmethode AWT ---, in der man zwei Ufos bewegen kann. Sie sollen per Pfeiltasten gesteuert werden, mit einem Button soll man die Bedienung des Ufos wechseln. Mit drei Reglern werden die Farbwerte der Ufos gesteuert, das eine RGB, das andere mit vertauschten Farbwerten, GBR. Bloß irgendwie ist der einzige Listener, der funktioniert, der AdjustmentListener der Scrollbars.

Mit dem ActionListener will ich abfragen, ob der wechsel-Button betätigt wurde, mit dem KeyListener will ich die Eingabe von den Pfeiltasten abhorchen.
Finde den Fehler bloß leider nicht ... :-/


Hoffe, ihr könnt mir weiterhelfen 
(und: wg. groß- und Kleinschreibung von Klassennamen: ich gelobe Besserung  )



```
/*
 * ufozeichnen.java
 *
 * Created on 16. Jänner 2007, 17:20
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


package schule;


/**
 *
 * @author Gentle
 */

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ufozeichnen extends Applet implements AdjustmentListener, KeyListener, ActionListener{

    /** Initialization method that will be called after the applet is loaded
     *  into the browser.
     */
    int r=127, b=64, g=80, ieh=0;
    int[] x={40,300},y={50,200};
    

    Scrollbar rot = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,r,1,0,255);
    Scrollbar gruen = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,g,1,0,255);
    Scrollbar blau = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,b,1,0,255);
    Button change = new Button("wechsel");
    
    




    public void init() 
    {
        setBackground(Color.BLACK);

        add(rot);
        add(gruen);
        add(blau);
        add(change);
        rot.addAdjustmentListener(this);
        gruen.addAdjustmentListener(this);
        blau.addAdjustmentListener(this);
        
        addKeyListener(this);
        
        
    }

     
     
    public void actionPerformed(ActionEvent e){
        
     //Wenn der gedrückte Button change ist, wechsle den wert von ieh -> 1 wird zu 0 und umgekehrt.
         if(e.getSource() == change)
         {
             if(ieh == 1)
             {
                 ieh = 0;
             }
             else
             {
                 ieh+=1;
             }
         }
        repaint();
         

    }


   public void keyPressed( KeyEvent e ) { }
   public void keyReleased( KeyEvent e ) { }
   public void keyTyped( KeyEvent e ) {
      
      if ( e.getKeyCode() == e.VK_UP ) 
      {
         y[ieh]--;
      }
      else if( e.getKeyCode() == e.VK_DOWN ) 
      {
         y[ieh]++;
      }
      else if( e.getKeyCode() == e.VK_RIGHT ) 
      {
         x[ieh]++;
      }
      else if( e.getKeyCode() == e.VK_LEFT ) 
      {
         x[ieh]--;
      }
      repaint();
   }
     
     

     public void adjustmentValueChanged(AdjustmentEvent e){
     if((e.getSource() == rot)||(e.getSource() == gruen)||(e.getSource() == blau))
         {
         r = rot.getValue();
         g = gruen.getValue();
         b = blau.getValue();
         repaint();   
        }

    }


     

     

    Image buffer;
    Graphics2D gbuffer;
    public void paint(Graphics graph)
    {

        if (buffer==null)
            {
                buffer = createImage(500,500);
                gbuffer = (Graphics2D)buffer.getGraphics();
            }
            gbuffer.clearRect(0,0,this.getSize().width,this.getSize().height);
            gbuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
            
            //Style von Scrollbar und Buttons
            change.setBounds(120,470,60,20);
            rot.setBounds(30,450,80,10);
            rot.setBackground(Color.red);
            gruen.setBounds(30,465,80,10);
            gruen.setBackground(Color.green);
            blau.setBounds(30,480,80,10);
            blau.setBackground(Color.blue);
            
            //Verlauf für den Hintergrund
            GradientPaint verlauf = new GradientPaint(0,0,new Color(164,204,255),0,500,new Color(244,244,255));
            gbuffer.setPaint(verlauf);
            gbuffer.fillRect(0,0,500,500);
            
            // Bedienkonsole
            gbuffer.setColor(new Color(0,0,0,120));
            gbuffer.fillOval(-370,420,800,400);
            gbuffer.setColor(Color.BLACK);
            gbuffer.drawOval(-370,420,800,399);
            gbuffer.setColor(Color.white);
            gbuffer.drawString("Setze die Farbe.",30,445);
            
            //Ufofarben
            Color[] ufocolor = {new Color(r,g,b),new Color(g,b,r)};
            
            //Ufo 1 mit position-x, position-y und farbe
            ufo ufo1 = new ufo(x[0],y[0],ufocolor[0]);
            ufo1.zeichnedasufo(gbuffer);
            
            //Ufo 2 mit position-x, position-y und farbe
            ufo ufo2 = new ufo(x[1],y[1],ufocolor[1]);
            ufo2.zeichnedasufo(gbuffer);
            
        graph.drawImage(buffer,0,0,this);

    }

    //Überschreiben von update
    public void update(Graphics graph)
    { 
        paint(graph); 
    }


}
```





Wenn ich den code nun ausführe, klappt alles, nur Meldet mir Netbeans das im Run-Fenster:


```
run-applet:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: component argument pData
        at sun.awt.windows.Win32SurfaceData.initOps(Native Method)
        at sun.awt.windows.Win32SurfaceData.<init>(Win32SurfaceData.java:448)
        at sun.awt.windows.Win32SurfaceData.createData(Win32SurfaceData.java:316)
        at sun.awt.Win32GraphicsConfig.createSurfaceData(Win32GraphicsConfig.java:357)
        at sun.awt.windows.WComponentPeer.replaceSurfaceData(WComponentPeer.java:332)
        at sun.awt.windows.WComponentPeer.replaceSurfaceData(WComponentPeer.java:313)
        at sun.awt.windows.WComponentPeer$2.run(WComponentPeer.java:353)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
BUILD SUCCESSFUL (total time: 20 seconds)
```


Danke schon mal,
Gentle


----------



## Marco13 (22. Jan 2007)

Ein
System.out.println(e);
in jeder event-handle-Methode zeigt, dass zumindest Adjustment- und KeyEvents ankommen. Und dass kein ActionEvent ankommt, liegt daran, dass du dem Button "change" keinen ActionListener zugewiesen hast.

Die Meldung, die deine IDE da Raushaut ist wohl eine IDE-spezifische - hat mit dem Applet soweit ich sehe nichts zu tun. Es funktioniert doch vmlt. im Browser und im Appletviewer!?


----------



## Gentle (22. Jan 2007)

Oh, danke. Das hat geholfen :idea: 
Jetzt funktioniert der Button, und bei Button sowie Scrollbar bekomme ich auch Ausgaben durch System.out-println(e).  


Jetzt fehlt mir noch der KeyListener, bekomme bei ihm auch (egal welche Taste ich drücke) keine Ausgabe durch println.
Finde den Fehler bloß nicht..  :?


----------



## Marco13 (22. Jan 2007)

Hm - bei Applets ist das AFAIK ein bißchen heikel: Das Applet braucht ja den Focus, um die Tastendrücke mitzukreigen. Ich hatte deinen Code 1:1 kopiert, NUR(!) um die System.out's erweitert, und dann im Appletviewer gestartet, und er hat die Pfeil-Tastendrücke mitgekriegt. Ganz dumm: Evtl. mußt du erstmal in den Haupt-Applet-Zeichenbereich klicken, damit danach die Tastendrücke ankommen? Wie startest du das Applet denn? Im Webbrowser, im Appletviewer, oder gibt's da irgendwas Netbeans-spezifisches dafür? Ggf. auch mal die ersten beiden probieren, und nochmal bescheid sagen...


----------



## Gentle (22. Jan 2007)

Er hat die Pfeil-Tastendrücke mitbekommen? Wuha.. strange!
Bei netbeans ist es so, dass man das File "runnen" kann, dann öffnet sich n fenster, in dem man das applet sieht.

Mein aktueller Quelltext sieht so aus:


```
/*
 * ufozeichnen.java
 *
 * Created on 16. Jänner 2007, 17:20
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


package schule;


/**
 *
 * @author Gentle
 */

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ufozeichnen extends Applet implements AdjustmentListener, ActionListener{

    /** Initialization method that will be called after the applet is loaded
     *  into the browser.
     */
    int r=127, b=64, g=80, ieh=0;
    int[] x={40,300},y={50,200};
    

    Scrollbar rot = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,r,1,0,255);
    Scrollbar gruen = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,g,1,0,255);
    Scrollbar blau = new java.awt.Scrollbar(Scrollbar.HORIZONTAL,b,1,0,255);
    Button change = new Button("wechsel");
    ufo[] myufo = {new ufo(),new ufo()};
    




    public void init() 
    {
        setBackground(Color.BLACK);

        add(rot);
        add(gruen);
        add(blau);
        add(change);
        rot.addAdjustmentListener(this);
        gruen.addAdjustmentListener(this);
        blau.addAdjustmentListener(this);
        change.addActionListener(this);
        addKeyListener(new KuhHaendler());
        
        
    }

     
     
    public void actionPerformed(ActionEvent e){
     System.out.println(e);   
     //Wenn der gedrückte Button change ist, wechsle den wert von ieh -> 1 wird zu 0 und umgekehrt.
         if(e.getSource() == change)
         {
             if(ieh == 1)
             {
                 ieh = 0;
             }
             else
             {
                 ieh+=1;
             }
         }
        repaint();
         

    }


    class KuhHaendler extends KeyAdapter 
    { 
    public void keyPressed(KeyEvent e) { }  
 
    public void keyReleased(KeyEvent e) { } 
 
    public void keyTyped(KeyEvent e) { 
        System.out.println(e); 
       if ( e.getKeyCode() == KeyEvent.VK_UP ) 
      { 
         myufo[ieh].rauf(1);
         
      } 
      else if( e.getKeyCode() == KeyEvent.VK_DOWN ) 
      { 
         myufo[ieh].runter(1);
      } 
      else if( e.getKeyCode() == KeyEvent.VK_RIGHT ) 
      { 
         myufo[ieh].rechts(1);
      } 
      else if( e.getKeyCode() == KeyEvent.VK_LEFT ) 
      { 
         myufo[ieh].links(1);
      } 
      repaint(); 
       } 
}
    
    

     public void adjustmentValueChanged(AdjustmentEvent e){
     if((e.getSource() == rot)||(e.getSource() == gruen)||(e.getSource() == blau))
         {
         r = rot.getValue();
         g = gruen.getValue();
         b = blau.getValue();
         repaint();   
        }
System.out.println(e);
    }


     

     

    Image buffer;
    Graphics2D gbuffer;
    public void paint(Graphics graph)
    {

        if (buffer==null)
            {
                buffer = createImage(500,500);
                gbuffer = (Graphics2D)buffer.getGraphics();
            }
            gbuffer.clearRect(0,0,this.getSize().width,this.getSize().height);
            gbuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
            
            //Style von Scrollbar und Buttons
            change.setBounds(120,470,60,20);
            rot.setBounds(30,450,80,10);
            rot.setBackground(Color.red);
            gruen.setBounds(30,465,80,10);
            gruen.setBackground(Color.green);
            blau.setBounds(30,480,80,10);
            blau.setBackground(Color.blue);
            
            //Verlauf für den Hintergrund
            GradientPaint verlauf = new GradientPaint(0,0,new Color(164,204,255),0,500,new Color(244,244,255));
            gbuffer.setPaint(verlauf);
            gbuffer.fillRect(0,0,500,500);
            
            // Bedienkonsole
            gbuffer.setColor(new Color(0,0,0,120));
            gbuffer.fillOval(-370,420,800,400);
            gbuffer.setColor(Color.BLACK);
            gbuffer.drawOval(-370,420,800,399);
            gbuffer.setColor(Color.white);
            gbuffer.drawString("Setze die Farbe.",30,445);
            
            //Ufofarben
            Color[] ufocolor = {new Color(r,g,b),new Color(g,b,r)};
            
            //Ufo 1 mit position-x, position-y und farbe
            //ufo ufo1 = new ufo(x[0],y[0],ufocolor[0]);
            for(int i=0; i<2; i++)
            {
            myufo[i].setX(x[i]);
            myufo[i].setY(y[i]);
            myufo[i].setCol(ufocolor[i]);
            myufo[i].zeichnedasufo(gbuffer);
            }
            

            
        graph.drawImage(buffer,0,0,this);

    }

    //Überschreiben von update
    public void update(Graphics graph)
    { 
        paint(graph); 
    }


}
```




bzw. das Ufo-File:


```
/*
 * ufo.java
 *
 * Created on 16. Jänner 2007, 17:21
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package schule;

import java.applet.*;
import java.awt.*;

/**
 *
 * @author Gentle
 */
public class ufo {
    int xpos, ypos;
    Color col;
    Graphics2D graph;
    /** Creates a new instance of ufo */
        public ufo() 
        {
        }
    public ufo(int x, int y, Color c) 
    {
        xpos = x;
        ypos = y;
        col = c;
    }


    public void zeichnedasufo(Graphics2D gr)
    {
        graph = gr;
        graph.setColor(new Color(0,0,0,50));
        graph.fillOval(xpos+20,ypos-20,40,60);
        graph.setColor(new Color(255,255,255,80));
        graph.fillOval(xpos+30,ypos-16,27,55);
        graph.setColor(new Color(255,255,255,180));
        graph.fillOval(xpos+45,ypos-15,5,5);
        graph.setColor(col);
        graph.fillOval(xpos,ypos,80,40);
        graph.setColor(new Color(255,255,255,100));
        graph.fillOval(xpos+18,ypos+5,60,30);
        graph.setColor(col);
        graph.fillOval(xpos+5,ypos+7,70,33);
        graph.setColor(new Color(0,0,0,180));
        graph.fillOval(xpos+15,ypos+25,50,15);
        graph.setColor(new Color(255,255,255,230));
        graph.fillOval(xpos+25,ypos+32,30,8);
    }

    public void setX(int x)
    {
        xpos = x;
    }

    
    public void setY(int y)
    {
        ypos = y;
    }
    
    public void setCol(Color c)
    {
        col = c;
    }
    
        public void runter(int y)
    {
        ypos = ypos + y;
    }
        
    public void rauf(int y)
    {
        ypos = ypos - y;
    }
                
    public void links(int x)
    {
        xpos = xpos - x;
    }
                        
    public void rechts(int x)
    {
        xpos = xpos + x;
    }
}
```




Funktioniert das jetzt bei dir, oder..? 
Könnte aber echt sein, dass da n Focus-problem besteht, ich lege zumindest keinen Bereich für den Tastendruck fest.


Grüße,
Tobias


----------



## Marco13 (22. Jan 2007)

Hm - habs jetzt nochmal getestet, an einem anderen Rechner, mit anderem Betreibessystem und anderer JVM - und hier funktioniert es auch nicht  
Wenn man ein bißchen ändert

```
public void init()
    {
        ...
        requestFocus();
    }

    public boolean isFocusTraversable()
    {
        return true;
    }
```
Funktionieren zwar "normale" Tasten, aber die Pfeiltasten immernoch nicht - und spätestens wenn man auf den Button klickt, hat DER den Focus, und das Applet kriegt garnichtsmehr mit. Ich werde morgen nochmal die letzte Version, die dur gepostet hast, auf dem anderen Rechner testen - wenn sie da (immernoch/wieder) funktioniert, weiß man zumindest schonmal eine Ursache (und vielleicht findet man dann auch eine Lösung)

(nach einer kurzen Websuche
Zumindest sind die Probleme teilweise bekannt...
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4131761
http://bugs.sun.com/bugdatabase/vie...c57f83554b216c6b5636a281a:WuuT?bug_id=4290675
... soweit ich weiß ist das bei Swing etwas Fehler-ärmer, aber ob nicht vielleicht genau das gleiche Problem noch dort auch noch besteht, weiß ich nicht....


----------



## Gentle (23. Jan 2007)

Danke Marco, das mit dem Hinweis auf den Bug war ein wichtiger Schritt, habs dann gelassen und per Buttons gelöst. 


Alles mit Arrays, alles mit Methoden und ohne KeyListener - anscheinend ein Bug, da der Heavyweight Component (Adjustment Listener) den Lightweight Component (KeyListener) überdeckt. Falls jemand ne Lösung dafür hat, immer her damit 


Hier das Ufo-Applet:
http://gentle.gym.wenzgasse.at/Java/Ufo/ufozeichnen.html

Quelltext Ufo-zeichnen

Quelltext Ufo-Klasse


-gentle


----------



## Marco13 (23. Jan 2007)

Hmja sorry - immer blöd, wenn man den (vermeintlichen) Fehler findet, aber keine Lösung dafür anbieten kann    (Außer der Frage: Warum verwendest du nicht Swing? Oder: Warum steuerst du die Ufos nicht mit der Maus?). 

Aber dann zumindest noch ein bißchen pedantisches Rum-Gemotze:  :wink: 
- Ufo.runter bewegt sich immer nur 1 pixel
- Die Bounds und Farben der Bedienelemente sollten nicht in der paint gesetzt werden (die paint sollte NUR das machen, was unbedingt nötig ist - also painten)
- Die System.out's der Events könnten jetzt raus...  :wink:


----------



## Gentle (23. Jan 2007)

Danke für die Tipps, werde das mit der Maus mal probieren 
Swing deshalb, weil ichs mir noch nicht angeguckt habe...


----------

