import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import org.jfugue.Player;
public class Midi extends Frame implements ActionListener, KeyListener{
private static final long serialVersionUID = 1L;
MidiKey keys[] = new MidiKey[21]; // 21个琴键
public Midi(){
setLayout(null);
setSize(433, 130);
addKeyListener(this);
setBackground(new Color(33,186,181));
for(int i = 14; i < 21; i++){
if(i==14){
keys[i] = new MidiKey('b');
} else {
keys[i] = new MidiKey('b', keys[i-1]);
}
add(keys[i]);
keys[i].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
// modified from keyTyped(KeyEvent e) method
int typed = ((MidiKey) me.getComponent()).getPos();
if(typed != -1){
new KeyThread(keys[typed]);
}
}
public void mouseReleased(MouseEvent me){
// modified from keyReleased(KeyEvent e) method
int released = ((MidiKey) me.getComponent()).getPos();
if (released != -1) {
if (released < 14)
keys[released].setBackground(Color.white);
else
keys[released].setBackground(Color.black);
}
}
});
}
for(int i = 0; i < 14; i++){
if(i==0){
keys[i] = new MidiKey('w');
} else {
keys[i] = new MidiKey('w', keys[i-1]);
}
add(keys[i]);
keys[i].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
// modified from keyTyped(KeyEvent e) method
int typed = ((MidiKey) me.getComponent()).getPos();
if(typed != -1){
new KeyThread(keys[typed]);
}
}
public void mouseReleased(MouseEvent me){
// modified from keyReleased(KeyEvent e) method
int released = ((MidiKey) me.getComponent()).getPos();
if (released != -1) {
if (released < 14)
keys[released].setBackground(Color.white);
else
keys[released].setBackground(Color.black);
}
}
});
}
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
validate();
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
}
public void processWindowEvent(WindowEvent e){
if(e.getID() == WindowEvent.WINDOW_CLOSING){
setVisible(false);
dispose();
System.exit(0);
}else
super.processWindowEvent(e);
}
public static void main(String[] args) {
new Midi();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
int typed = charToPos(e.getKeyChar());
if (typed != -1) {
new KeyThread(keys[typed]);
}
}
@Override
public void keyPressed(KeyEvent e) {
// sound(e);
}
@Override
public void keyReleased(KeyEvent e) {
int released = charToPos(e.getKeyChar());
if (released != -1) {
if (released < 14)
keys[released].setBackground(Color.white);
else
keys[released].setBackground(Color.black);
}
}
public int charToPos(char keyChar){
int keyPos = -1;
switch (keyChar) {
case 'q': keyPos = 0; break;
case 'w': keyPos = 1; break;
case 'e': keyPos = 2; break;
case 'r': keyPos = 3; break;
case 'a': keyPos = 4; break;
case 's': keyPos = 5; break;
case 'd': keyPos = 6; break;
case 'f': keyPos = 7; break;
case 'g': keyPos = 8; break;
case 'h': keyPos = 9; break;
case 'j': keyPos = 10; break;
case 'k': keyPos = 11; break;
case 'l': keyPos = 12; break;
case ';': keyPos = 13; break;
case 't': keyPos = 14; break;
case 'y': keyPos = 15; break;
case 'u': keyPos = 16; break;
case 'i': keyPos = 17; break;
case 'o': keyPos = 18; break;
case 'p': keyPos = 19; break;
case '[': keyPos = 20; break;
default: break;
}
return keyPos;
}
}
class MidiKey extends Label {
private static final long serialVersionUID = 1L;
private int KEY_WIDTH = 30, KEY_HEIGHT = 130;
private int pos = -1;
private String[] tones = {"F4","G4","A4","B4","C5","D5","E5","F5","G5","A5","B5","C6","D6","E6","C#","D#","E#","F#","G#","A#","B#" };
private String tone = "";
MidiKey(char ch){
super();
if(ch == 'w'){
this.pos = 0;
setBounds(0, 0, KEY_WIDTH, KEY_HEIGHT);
setBackground(Color.white);
} else {
this.pos = 14;
setBounds((int) (KEY_WIDTH * 0.75), 0, KEY_WIDTH/2, KEY_HEIGHT/3*2);
setBackground(Color.black);
}
this.tone = tones[this.pos];
}
MidiKey(char ch, MidiKey midiKey){
super();
if(ch == 'w'){
this.pos = midiKey.pos + 1;
setBounds(midiKey.getX() + KEY_WIDTH + 1, 0, KEY_WIDTH, KEY_HEIGHT);
setBackground(Color.white);
} else {
this.pos = midiKey.pos + 1;
setBounds(midiKey.getX() + (KEY_WIDTH + 1) * 2, 0, KEY_WIDTH/2, KEY_HEIGHT/3*2);
setBackground(Color.black);
}
this.tone = tones[this.pos];
}
String getTone(){
return this.tone;
}
int getPos(){
return this.pos;
}
}
class KeyThread implements Runnable {
Thread t;
MidiKey key;
Player player = new Player();
KeyThread(MidiKey key) {
this.key = key;
// this.player = player;
t = new Thread(this, "KeyThread");
t.start();
}
@Override
public void run() {
String opt = "";
key.setBackground(new Color(133, 215, 212));
player.play(key.getTone() + opt);
player.close();
}
}