我正在设计一个使用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();
}
我认为发生的事情是,你实际上没有将键添加到任何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?");
}
现在怎么办?