tonescanvas.java
来自「J2ME MIDP_Example_Applications」· Java 代码 · 共 297 行
JAVA
297 行
// Copyright 2003 Nokia Corporation.
//
// THIS SOURCE CODE IS PROVIDED 'AS IS', WITH NO WARRANTIES WHATSOEVER,
// EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS
// FOR ANY PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE
// OR TRADE PRACTICE, RELATING TO THE SOURCE CODE OR ANY WARRANTY OTHERWISE
// ARISING OUT OF ANY PROPOSAL, SPECIFICATION, OR SAMPLE AND WITH NO
// OBLIGATION OF NOKIA TO PROVIDE THE LICENSEE WITH ANY MAINTENANCE OR
// SUPPORT. FURTHERMORE, NOKIA MAKES NO WARRANTY THAT EXERCISE OF THE
// RIGHTS GRANTED HEREUNDER DOES NOT INFRINGE OR MAY NOT CAUSE INFRINGEMENT
// OF ANY PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OWNED OR CONTROLLED
// BY THIRD PARTIES
//
// Furthermore, information provided in this source code is preliminary,
// and may be changed substantially prior to final release. Nokia Corporation
// retains the right to make changes to this source code at
// any time, without notice. This source code is provided for informational
// purposes only.
//
// Nokia and Nokia Connecting People are registered trademarks of Nokia
// Corporation.
// Java and all Java-based marks are trademarks or registered trademarks of
// Sun Microsystems, Inc.
// Other product and company names mentioned herein may be trademarks or
// trade names of their respective owners.
//
// A non-exclusive, non-transferable, worldwide, limited license is hereby
// granted to the Licensee to download, print, reproduce and modify the
// source code. The licensee has the right to market, sell, distribute and
// make available the source code in original or modified form only when
// incorporated into the programs developed by the Licensee. No other
// license, express or implied, by estoppel or otherwise, to any other
// intellectual property rights is granted herein.
package example.tones;
import javax.microedition.lcdui.*;
class TonesCanvas
extends Canvas
implements CommandListener
{
// Constants and frequencies for tone playing
private static final int SILENT = -1; // rogue value for table index
private static int frequencies[][] =
{
{ 523, 554}, // C, C#
{ 587, 622}, // D, D#
{ 659, 659}, // E, E (there is no E#)
{ 698, 740}, // F, F#
{ 784, 831}, // G, G#
{ 880, 932}, // A, A#
{ 988, 988}, // B, B (there is no B#)
{1047, 1109}, // C, C#
{1175, 1245}, // D, D#
{1319, 1319}, // E, E (there is no E#)
{1397, 1480} // F, F#
};
private static final int NATURAL = 0;
private static final int SHARP = 1;
// Constants for screen layout. Top of clef is highest point; bottom
// of middle C note is lowest point. Clef will be drawn at screen left,
// note at screen centre, possible sharp to left of note
private static final int CLEF_G_LINE_Y = 30; // clef curls around 'G' line
private static final int NOTE_WIDTH = 7;
private static final int NOTE_HEIGHT = 7;
private static final int SHARP_WIDTH = 5;
private static final int LINE_SPACING = 6;
private static final int TOP_LINE_Y = CLEF_G_LINE_Y - 3 * LINE_SPACING;
private static final int MIDDLE_C_Y = TOP_LINE_Y + 5 * LINE_SPACING;
private static final int LAYOUT_HEIGHT = MIDDLE_C_Y + NOTE_HEIGHT / 2 + 1;
private static final int SHARP_OFFSET = SHARP_WIDTH + 2; // 2 for spacing
private static final int LEGER_LINE_WIDTH = NOTE_WIDTH + 4;
private final TonesMIDlet parent;
private final Image trebleImg;
private final Image noteImg;
private final Image sharpImg;
private final Command exitCommand;
private final TonePlayer tonePlayer;
private int note = SILENT;
private int currentKey;
private boolean sharp = false;
TonesCanvas(TonesMIDlet parent)
{
this.parent = parent;
trebleImg = createImage("/treble.png");
noteImg = createImage("/note.png");
sharpImg = createImage("/sharp.png");
// create a NokiaTonePlayer if Nokia UI API is available,
// otherwise a dummy TonePlayer
tonePlayer = makeTonePlayer();
exitCommand = new Command("Exit", Command.EXIT, 1);
addCommand(exitCommand);
setCommandListener(this);
}
public void paint(Graphics g)
{
int width = getWidth();
int height = getHeight();
g.setColor(0x00FFFFFF); // white
g.fillRect(0, 0, width, height);
int topOffset = (getHeight() - LAYOUT_HEIGHT) / 2;
// draw treble clef, 1 pixel in from left edge
g.drawImage(trebleImg, 1, topOffset, Graphics.TOP | Graphics.LEFT);
if (note != SILENT)
{
// draw note
drawNote(g, topOffset, width);
}
drawLines(g, topOffset, width);
}
// draw the five horizontal lines of the music score
private void drawLines(Graphics g, int topOffset, int width)
{
g.setColor(0x00000000); // black
for (int i = 0; i < 5; ++i)
{
int y = topOffset + TOP_LINE_Y + LINE_SPACING * i;
g.drawLine(0, y, width-1, y);
}
}
private void drawNote(Graphics g, int offset, int width)
{
int y = offset + MIDDLE_C_Y - note * LINE_SPACING / 2;
int x = width / 2;
g.drawImage(noteImg, x, y, Graphics.HCENTER | Graphics.VCENTER);
// this next bit should be made more smart if it ever
// needs to be more general
if (note == 0) // C should have a 'leger line' through it
{
g.setColor(0x00000000); // black
g.drawLine(x-LEGER_LINE_WIDTH/2, y, x+LEGER_LINE_WIDTH/2, y);
}
// is sharp set, and can this note be sharp (E & B can't)
if (sharp &&
(frequencies[note][NATURAL] != frequencies[note][SHARP]))
{
g.drawImage(sharpImg, x - SHARP_OFFSET, y,
Graphics.HCENTER | Graphics.VCENTER);
}
}
public void commandAction(Command c, Displayable d)
{
if (c == exitCommand)
{
parent.exitRequested();
}
}
public void keyPressed(int keyCode)
{
if (keyCode == Canvas.KEY_POUND)
{
sharp = !sharp; // toggle sharp state
}
else
{
switch (keyCode)
{
case Canvas.KEY_NUM1:
note = 0; // middle C
break;
case Canvas.KEY_NUM2:
note = 1; // D
break;
case Canvas.KEY_NUM3:
note = 2; // E
break;
case Canvas.KEY_NUM4:
note = 3; // F
break;
case Canvas.KEY_NUM5:
note = 4; // G
break;
case Canvas.KEY_NUM6:
note = 5; // A
break;
case Canvas.KEY_NUM7:
note = 6; // B
break;
case Canvas.KEY_NUM8:
note = 7; // C
break;
case Canvas.KEY_NUM9:
note = 8; // D
break;
case Canvas.KEY_STAR:
note = 9; // E
break;
case Canvas.KEY_NUM0:
note = 10; // F
break;
default:
note = SILENT;
break;
}
if (note != SILENT)
{
startNote();
}
currentKey = keyCode;
}
repaint();
}
public void keyReleased(int keyCode)
{
// This check deals with the possibility that we have this sequence:
// key A pressed; ...; key B pressed; key A released
// The user will expect that the tone for key B continues playing.
if (keyCode == currentKey)
{
note = SILENT;
stopNote();
}
repaint();
}
private void startNote()
{
tonePlayer.play(frequencies[note][sharp ? SHARP : NATURAL]);
}
void stopNote()
{
tonePlayer.stop();
}
private static Image createImage(String filename)
{
Image image = null;
try
{
image = Image.createImage(filename);
}
catch (java.io.IOException e)
{
// just let return value be null
}
return image;
}
private static TonePlayer makeTonePlayer()
{
TonePlayer player;
try
{
// This statement throws an exception if no Nokia UI API available
Class.forName("com.nokia.mid.sound.Sound");
// If we get here, Nokia UI API is available, so we can safely
// create a player that uses it. But we use Class.forName rather
// than 'new' so that there is no link dependency.
Class clas = Class.forName("example.tones.NokiaTonePlayer");
player = (TonePlayer)(clas.newInstance());
}
catch (Exception e)
{
// If no Nokia UI API, then create a dummy tone player
player = new TonePlayer();
}
return player;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?