// Keyboard.java
//Download:http://www.codefans.net
/*
* Portions of Keyboard's source code were excerpted from Sun's MidiSynth.java
* source file. I've included Sun's original copyright and license, to be fair
* to Sun.
*
* Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT
* BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
* MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
* DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
* HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or
* in the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.sound.midi.*;
import javax.swing.*;
/*
This class creates a keyboard component that knows how to play a specific
instrument.
*/
public class Keyboard extends JPanel
{
public final static Color KEY_BLUE = new Color (204, 204, 255);
public final static int KEY_HEIGHT = 80, KEY_WIDTH = 16;
private Key theKey;
private MidiChannel channel;
private Synthesizer synthesizer;
private Vector blackKeys = new Vector ();
private Vector keys = new Vector ();
private Vector whiteKeys = new Vector ();
public Keyboard ()
{
setLayout (new BorderLayout ());
setPreferredSize (new Dimension (42*KEY_WIDTH+1, KEY_HEIGHT+1));
int transpose = 24;
int [] whiteIDs = { 0, 2, 4, 5, 7, 9, 11 };
for (int i = 0, x = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++, x += KEY_WIDTH)
{
int keyNum = i * 12 + whiteIDs [j] + transpose;
whiteKeys.add (new Key (x, 0, KEY_WIDTH, KEY_HEIGHT, keyNum));
}
}
for (int i = 0, x = 0; i < 6; i++, x += KEY_WIDTH)
{
int keyNum = i * 12 + transpose;
blackKeys.add (new Key ((x += KEY_WIDTH)-4, 0, KEY_WIDTH/2,
KEY_HEIGHT/2, keyNum+1));
blackKeys.add (new Key ((x += KEY_WIDTH)-4, 0, KEY_WIDTH/2,
KEY_HEIGHT/2, keyNum+3));
x += KEY_WIDTH;
blackKeys.add (new Key ((x += KEY_WIDTH)-4, 0, KEY_WIDTH/2,
KEY_HEIGHT/2, keyNum+6));
blackKeys.add (new Key ((x += KEY_WIDTH)-4, 0, KEY_WIDTH/2,
KEY_HEIGHT/2, keyNum+8));
blackKeys.add (new Key ((x += KEY_WIDTH)-4, 0, KEY_WIDTH/2,
KEY_HEIGHT/2, keyNum+10));
}
keys.addAll (blackKeys);
keys.addAll (whiteKeys);
addMouseListener (new MouseAdapter ()
{
public void mousePressed (MouseEvent e)
{
// Identify the key that was pressed. A null
// value indicates something other than a key
// was pressed.
theKey = getKey (e.getPoint ());
// If a key was pressed ...
if (theKey != null)
{
// Tell key to start playing note.
theKey.on ();
// Update key's visual appearance.
repaint ();
}
}
public void mouseReleased (MouseEvent e)
{
if (theKey != null)
{
// Tell key to stop playing note.
theKey.off ();
// Update key's visual appearance.
repaint ();
}
}
public void mouseExited (MouseEvent e)
{
// This method is called if the mouse is moved
// off the keyboard component. If a key was
// pressed, we release that key.
if (theKey != null)
{
// Tell key to stop playing note.
theKey.off ();
// Update key's visual appearance.
repaint ();
// The following assignment is needed so
// that we don't execute the code within
// mouseReleased()'s if statement should we
// release a key after exiting the keyboard
// component. There is no need to tell the
// key to stop playing a note after we have
// already told it to do so. Furthermore,
// we prevent an unnecessary repaint.
theKey = null;
}
}
public Key getKey (Point point)
{
// Identify the key that was clicked.
for (int i = 0; i < keys.size (); i++)
{
if (((Key) keys.get (i)).contains (point))
return (Key) keys.get (i);
}
return null;
}
});
}
public boolean chooseInstrument (int instrumentID)
{
if (channel == null)
return false;
// Select new instrument based on ID.
channel.programChange (instrumentID);
return true;
}
public String [] getInstruments ()
{
if (synthesizer == null)
return null;
Instrument [] instruments = synthesizer.getLoadedInstruments ();
String [] ins = new String [instruments.length];
for (int i = 0; i < instruments.length; i++)
ins [i] = instruments [i].toString ();
return ins;
}
public void paint (Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Dimension d = getSize ();
g2.setBackground (getBackground ());
g2.clearRe