未触发java中的MouseeEvent

未触发java中的MouseeEvent,java,mouseevent,event-listener,Java,Mouseevent,Event Listener,我正在用Java7设计一个虚拟钢琴。我有一个问题的事件调用,但在鼠标点击。JFrame(Piano)包含JPanel(PianoKeyboard),而JPanel(PianoKeyboard)又包含几个作为JComponent(PianoKey)的钢琴键。我想让钢琴课(jframe)知道当按下相应图标时按下了哪个键 因此,我做了以下工作 PianoKey有一个MouseStener,其方法在PianoKeyboard中实现。PianoKeyboard有一个KeyListener,其方法在Pian

我正在用Java7设计一个虚拟钢琴。我有一个问题的事件调用,但在鼠标点击。JFrame(Piano)包含JPanel(PianoKeyboard),而JPanel(PianoKeyboard)又包含几个作为JComponent(PianoKey)的钢琴键。我想让钢琴课(jframe)知道当按下相应图标时按下了哪个键

因此,我做了以下工作 PianoKey有一个MouseStener,其方法在PianoKeyboard中实现。PianoKeyboard有一个KeyListener,其方法在Piano中实现。当从钢琴键接收到事件时,将触发键侦听器事件

然而,问题是当点击图标时,钢琴键盘中的鼠标事件侦听器方法都不会被触发

钢琴课:

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);
    }
}
钢琴键盘课:

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);
        }
    }
}
关键侦听器:

public interface KeyListener {
    public void keyPressed();
}

在钢琴课上实施这一点:

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

现在发生了什么?

我认为发生的事情是,您实际上没有向任何GUI添加按键来注册鼠标单击。我看到你将它们添加到某种列表中,但仅此而已。它们“出现”是因为面板正在绘制来自它们的图像,但这与实际作为界面的可见部分并不相同

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);
            }
        });
    }
}
classpianokey
扩展JComponent{
PianoKey(/*args*/){
BuffereImage键=ImageIO.read(
cl.getResource(IMAGE_DIRECTORY+“/key/white.png”)
);
最终尺寸sz=新尺寸(key.getWidth(),key.getHeight());
setPreferredSize(sz);
设置最小尺寸(sz);
设定最大尺寸(sz);
设置图像(键);
}
@凌驾
公共组件(图形g){
超级组件(g);
BuffereImage键=getImage();
g、 drawImage(key,0,0,key.getWidth(),key.getHeight(),null);
}
}
类钢琴板
扩展JPanel
鼠标听器{
PianoKeyBoard(/*args*/){
setLayout(新网格布局(25,0));

for(int i=1;我在所有鼠标事件(这是调用keylistener(我的)的唯一实例)中的pianokeyboard类中有system.out.println)。它们不会出现,因此不会出现keylistener事件。如果在k.addMouseListener(此)中添加匿名侦听器,会怎么样;将此替换为AnoyMoons侦听器。匿名侦听器是否听到这些事件?向我们显示您的鼠标事件。似乎解决了我的问题。非常感谢。现在只剩下对定位的干扰了。:)知道为什么会出现这种布局吗:当我将y位置设置为0,高度设置为150或89(黑白键)时?现在使用layeredpane而不是jpanel来进行分层键。不确定。JLayeredPane不是我非常熟悉的组件。如果您使用的是布局,我的印象是它不能很好地处理布局。基本上,您必须将其视为空布局,并手动为其中的组件设置边界。如果您手动设置边界,则它将被禁用好的,比如你的数学是关闭的,或者可能有一个布局管理器与之冲突。如果你仍然使用OverlyLayout,我已经读到这很棘手。
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);
            }
        });
    }
}