Processing 2.1.1 Keylisteners

edited March 2014 in Programming Questions

Hi, I'm trying to write a KeyListener for a JTextField in Processing 2.1.1. Here's the code:

mp_t_fg.addKeyListener(new KeyListener () {
  public void keyReleased(KeyEvent e) {}
  public void keyPressed(KeyEvent e) {}
  public void keyTyped(KeyEvent e) {
    //do something
  }
});

'mp_t_fg' is the JTextField.

When I'm trying to compile the project I get the following error: 'The type new KeyListener(){} must implement the inherited abstract method KeyListener.keyReleased(KeyEvent))'

What am I doing wrong?

Answers

  • Well, the error says it all: KeyListeners need to define every method in the KeyListener interface: http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyListener.html

    You could also use a KeyAdapter instead.

    Although, it seems strange that you're dealing with a Swing component in a Processing sketch. I assume you're just passing it into the sketch to add the KeyListener so that the KeyListener can access the sketch variables?

  • edited March 2014

    Thanks for your respond! I think that I actually defined every method in the KeyListener interface.

    I'm using Swing inside of Processing because I need the serial library in a project which uses a Swing interface and Processing was the most comfortable solution.

  • You can use Processing code from inside a Java application. It's weird to be using Swing stuff inside a Processing sketch though.

    Can you provide a small example that demonstrates the error?

  • edited March 2014

    Here's a example:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    boolean frm_active=false;
    
    JFrame frame;
    JTextField field = new JTextField(15);
    
    void setup() {
      frame=new JFrame("Test");
      Container con=frame.getContentPane();
      con.setLayout(new GridLayout(8,1)); 
    
      con.add(field);
    
      field.addKeyListener(new KeyListener () { //error occurs here
        public void keyReleased(KeyEvent e) {}
        public void keyPressed(KeyEvent e) {}
        public void keyTyped(KeyEvent e) {
          println("keyTyped");
        }
      });
    }
    
    void draw() {
      if (!frm_active) {
        frame.setVisible(true);
        frame.setSize(new Dimension(280,360));
        frm_active=true;
      }
      background(50);
    }
    
  • Like I said, it's pretty strange to see Swing code mixed into a Processing sketch. You usually go the other way and have Processing code inside a Java application.

    And you're starting to see some of the weirdness of putting Swing code inside Processing. It turns out that Processing has its own KeyEvent class, so when you declare a function that takes a KeyEvent parameter, Processing thinks you're talking about the Processing KeyEvent! This makes Swing unhappy because a Swing KeyListener has to take a Swing (well, AWT) KeyEvent, not a Processing KeyEvent!

    You can get around this by using the fully qualified name. In other words, add the package information to the KeyEvent so the code knows exactly which KeyEvent you want:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    boolean frm_active=false;
    
    JFrame frame;
    JTextField field = new JTextField(15);
    
    void setup() {
      frame=new JFrame("Test");
      Container con=frame.getContentPane();
      con.setLayout(new GridLayout(8,1)); 
    
      con.add(field);
    
      field.addKeyListener(new KeyListener () {
        public void keyReleased(java.awt.event.KeyEvent e) {}
        public void keyPressed(java.awt.event.KeyEvent e) {}
        public void keyTyped(java.awt.event.KeyEvent e) {
          println("keyTyped");
        }
      });
    }
    
    void draw() {
      if (!frm_active) {
        frame.setVisible(true);
        frame.setSize(new Dimension(280,360));
        frm_active=true;
      }
      background(50);
    }
    

    But again, it's much better to add Processing code to your Swing application than it is to add Swing code to your Processing sketch.

  • This problem can also be avoided if you just use the fully qualified name in your import statement instead of the sloppier wildcard import:

    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import java.awt.Container;
    import java.awt.GridLayout;
    import java.awt.Dimension;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
  • Ok, thanks! It works! And yes, I will think about moving from the Processing IDE to something like Eclipse...

  • That is definitely what you should be doing. All you need to do is add Processing to your classpath, then you can embedd PApplets (sketches) inside Swing interfaces as well as access the Processing library classes outside of a Processing sketch.

  • If you want to embed Processing in Java Swing I suggest NetBeans rather than Eclipse. Also you might find this discussion useful.

  • Why do you suggest NetBeans over eclipse for this? I would prefer eclipse, personally...

  • I prefer Eclipse but I think that's because I use Eclipse much more often than NetBeans. I think it's up to you which to choose but I really like the way you can work with Eclipse so I'll stick with it.

  • In this instance NetBeans has the advantage because it has an easy to use graphical form designer for creating the Java Swing applications (especially if the GUI is to have many Swing components that have to move if the window is resized).

    Personally I prefer Eclipse but I am prepared to use the best tool for the job. For instance the GUI Builder tool was an Eclipse project where I created the program logic but was imported into NetBeans to create it's GUI .

  • Ack, I personally hate GUI builders. I think they hide implementation details (which is bad for novices) and generate horrible code (which is bad for everybody). I personally would recommend just writing the Swing by hand.

    But this is pretty subjective, so to each their own!

Sign In or Register to comment.