提问者:小点点

java中的MouseEvent未被触发


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

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

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

钢琴班:

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 class PianoKey extends JComponent {
    public PianoKey(int pitch,int tempo) {
        super();
    ....code....
    this.setImage(ImageIO.read(cl.getResource(IMAGE_DIRECTORY + "/key/white.png")));
}

关键监听器:

public interface KeyListener {
    public void keyPressed();
}

共2个答案

匿名用户

我认为发生的事情是,你实际上没有将键添加到任何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);
            }
        });
    }
}

类似的东西会起作用。在这里,PianoKey绘制图像,PianoKeyboard只是将它们添加到自己中。另外,作为附带说明,确保您在Swing中覆盖的是画布组件,而不是画布。

匿名用户

在你的钢琴课上实现这一点:

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

现在怎么办?