0

I am designing a virtual piano using Java7. I am having an issue with event calls however on mouse clicks. the JFrame (Piano) contains the JPanel (PianoKeyboard) which in turn contains several piano keys as JComponent(PianoKey). i would like the Piano class (jframe) to know which key was pressed when the respective icon is pressed.

Hence i have done the following the PianoKey has a MouseListener, who's methods are implemented within PianoKeyboard. PianoKeyboard has a KeyListener who's methods are implemented within Piano. The Key listener events are fired when an event is received from piano key.

The issue however is that when the icons are clicked on, none of the mouse event listener methods within piano keyboard are being triggered.

The Piano Class:

public class Piano extends JFrame implements KeyListener {
 public Piano() {
 super();
 this.setTitle("Piano");
 this.setName("Piano"); 
 this.setSize(850,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.setResizable(false); 
 PianoKeyboard s = new PianoKeyboard(0);
 s.addListener(this);
 this.getContentPane().add(s);
 this.setVisible(true);
 }
}

the Piano Keyboard Class:

public class PianoKeyboard extends JPanel implements MouseListener{
 ArrayList<KeyListener> listeners = new ArrayList<KeyListener>();
 public PianoKeyboard(int tempo){
 super();
 this.tempo = tempo; 
 this.setBackground(Color.WHITE);
 this.setEnabled(true);
 this.setSize(Piano.FRAME_SIZE);
 this.setVisible(true);
 this.setLayout(new OverlayLayout(this));
 createKeyboard();
 }
 public void addListener(KeyListener listener){
 listeners.add(listener);
 }
 private void createKeyboard() {
 ........ code ......
 for (int i = 0; i < 25; i++) {
 PianoKey k = new PianoKey(i+1, tempo);
 k.addMouseListener(this); 
 ..... code .....
 keys.add(k);
 }
 }
 /** the followign methods are also available:
 mouseClicked, mouseExited, mousePressed, mouseReleased
 which contain the following code when neeed:
 for(KeyListener k : listeners){
 k.keyPressed();
 }
 */
 public void paint(Graphics g){
 for(int i = 0; i < keys.size(); i++){
 g.drawImage(keys.get(i).getImage(),positions.get(i),0,54,150,null);
 }
 }
}

The Piano Key Class:

public class PianoKey extends JComponent {
 public PianoKey(int pitch,int tempo) {
 super();
 ....code....
 this.setImage(ImageIO.read(cl.getResource(IMAGE_DIRECTORY + "/key/white.png")));
}

The Key Listener:

public interface KeyListener {
 public void keyPressed();
}
nhahtdh
56.9k15 gold badges131 silver badges164 bronze badges
asked Dec 19, 2013 at 16:17
1
  • Show us your mouse events. Commented Dec 19, 2013 at 18:42

2 Answers 2

1

I think what is going on is you haven't actually added the keys to any GUI to register mouse clicks. I see you adding them to what appears to be some kind of List but that's all. They 'appear' because the panel is painting images from them but that's not the same thing as actually being a visible part of the interface.

class PianoKey
extends JComponent {
 PianoKey(/* args */) {
 BufferedImage key = ImageIO.read(
 cl.getResource(IMAGE_DIRECTORY + "/key/white.png")
 );
 final Dimension sz = new Dimension(key.getWidth(), key.getHeight());
 setPreferredSize(sz);
 setMinimumSize(sz);
 setMaximumSize(sz);
 setImage(key);
 }
 @Override
 public void paintComponent(Graphics g) {
 super.paintComponent(g);
 BufferedImage key = getImage();
 g.drawImage(key, 0, 0, key.getWidth(), key.getHeight(), null);
 }
}
class PianoKeyBoard
extends JPanel
implements MouseListener {
 PianoKeyBoard(/* args */) {
 setLayout(new GridLayout(25, 0));
 for( int i = 1; i <= 25; i++ ) {
 PianoKey key = new PianoKey(/* args */);
 key.addMouseListener(this);
 add(key);
 }
 }
 @Override
 public void mousePressed(MouseEvent me) {
 System.out.println("pressed");
 }
 @Override
 public void mouseClicked(MouseEvent me) {
 System.out.println("clicked");
 }
 @Override
 public void mouseReleased(MouseEvent me) {
 System.out.println("released");
 }
 @Override
 public void mouseEntered(MouseEvent me) {
 System.out.println("entered");
 }
 @Override
 public void mouseExited(MouseEvent me) {
 System.out.println("exited");
 }
}
class Piano
extends JFrame {
 Piano() {
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 setContentPane(new PianoKeyBoard(/* args */));
 pack();
 }
 public static void main(String[] args) {
 SwingUtilities.invokeLater(new Runnable() {
 @Override
 public void run() {
 new Piano().setVisible(true);
 }
 });
 }
}

Something like that will work. Here, PianoKey paints the image and PianoKeyBoard just adds them to itself. Also, as a side note, make sure you are overriding paintComponent in Swing, not paint.

answered Dec 19, 2013 at 19:17
Sign up to request clarification or add additional context in comments.

3 Comments

Seems to have solved my problem. thanks a lot. only messing around with the positioning is left now. :)
any idea as to why this layout is happening: tinypic.com/r/2wrnnh1/5 when i'm setting the y position to 0, and height to 150 or 89 (white and black keys)? using a layeredpane instead of jpanel now for layering keys.
Not sure. JLayeredPane isn't a component I'm very familiar with. If you're using a layout, my impression is it doesn't play well with layouts. Basically you have to treat it like a null layout and set bounds manually for the components in it. If you're setting bounds manually then it looks like your math is off or maybe there's a layout manager it is conflicting with. If you're still using OverlayLayout, I've read that it's tricky.
1

implement this on your piano class :

public void keyTyped(KeyEvent e) {
 System.out.println("am i working?");
}

what happens now?

answered Dec 19, 2013 at 16:23

2 Comments

i have system.out.println's within thte pianokeyboard class in all mouse events (whicih are the only instances where the keylistener (mine) are called). they do not appear so no keyListener event is thrown
what about if you add an anonymous listener at k.addMouseListener(this); Replace this with an anoymouns listener. Does the anonymous listener hear the events?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.