2013-12-19 36 views
0

我正在設計一個使用Java7的虛擬鋼琴。然而,在點擊鼠標時,我遇到了事件調用的問題。 JFrame(鋼琴)包含JPanel(鋼琴鍵盤),而Janel(鋼琴鍵盤)又包含幾個鋼琴鍵作爲JComponent(鋼琴鍵)。我想讓鋼琴課(jframe)知道按下相應的圖標時哪個鍵被按下。java中的mouseevent沒有被觸發

因此,我做了以下 PianoKey有一個MouseListener,誰的方法在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 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(); 
} 
+0

向我們展示您的鼠標事件。 – Radiodef

回答

1

我認爲發生的事情是你並沒有真正將鍵添加到任何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只是將它們添加到自己。另外,作爲一個便箋,請確保你是overriding paintComponent in Swing,而不是繪畫。

+0

似乎已經解決了我的問題。非常感謝。現在只剩下定位了。 :) – mangusbrother

+0

任何想法,爲什麼這種佈局正在發生:http://tinypic.com/r/2wrnnh1/5當我設置y位置爲0,並將高度設置爲150或89(白色和黑色鍵)?現在使用分層而不是jpanel來分層鍵。 – mangusbrother

+0

不確定。 JLayeredPane不是我非常熟悉的組件。如果您使用佈局,我的印象是佈局不夠好。基本上你必須把它看作一個空的佈局,併爲其中的組件設置手動邊界。如果你手動設置界限,那麼它看起來像你的數學是關閉的,或者有一個它與之相沖突的佈局管理器。如果你仍然使用OverlayLayout,我讀過它很棘手。 – Radiodef

1

你的鋼琴類實現這一點:

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

現在會發生什麼?

+0

我在所有鼠標事件的pianokeyboard類中都有system.out.println(這是調用keylistener(我的)的唯一實例)。它們不會出現,所以沒有引發keyListener事件 – mangusbrother

+0

如果在k.addMouseListener(this)處添加匿名偵聽器,那麼該怎麼辦?將這個替換爲一個動物模型聽衆。匿名聽衆是否會聽到這些事件? –