📄 tonescanvas.java
字号:
import javax.microedition.lcdui.*;
class TonesCanvas
extends Canvas
implements CommandListener
{
// Constants and frequencies for tone playing
static final int SILENT = -1; // 静音
static final int NATURAL = 0;
static final int SHARP = 1;
// 计算位置
static final int CLEF_G_LINE_Y = 30; // 'G' 线
static final int NOTE_WIDTH = 7;
static final int NOTE_HEIGHT = 7;
static final int SHARP_WIDTH = 5;
static final int LINE_SPACING = 6;
static final int TOP_LINE_Y = CLEF_G_LINE_Y - 3 * LINE_SPACING;
static final int MIDDLE_C_Y = TOP_LINE_Y + 5 * LINE_SPACING;
static final int LAYOUT_HEIGHT = MIDDLE_C_Y + NOTE_HEIGHT / 2 + 1;
static final int SHARP_OFFSET = SHARP_WIDTH + 2; // 2 for spacing
static final int LEGER_LINE_WIDTH = NOTE_WIDTH + 4;
final TonesMIDlet parent;
final Image trebleImg;
final Image noteImg;
final Image sharpImg;
final Command exitCommand;
final TonePlayer tonePlayer;
int note = SILENT;
int currentKey;
boolean sharp = false;
TonesCanvas(TonesMIDlet parent)
{
this.parent = parent;
trebleImg = createImage("/treble.png");
noteImg = createImage("/note.png");
sharpImg = createImage("/sharp.png");
// 生成 NokiaTonePlayer 或其他Player,
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;
// 画高音符 treble clef
g.drawImage(trebleImg, 1, topOffset,
Graphics.TOP | Graphics.LEFT);
if (note != SILENT)
{
// 画音符
drawNote(g, topOffset, width);
}
drawLines(g, topOffset, width);
}
// 画五条线
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 && tonePlayer.maySharp( note ) )
{
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)
{
if (keyCode == currentKey)
{
note = SILENT;
stopNote();
}
repaint();
}
private void startNote()
{
tonePlayer.play( note,sharp );
}
void stopNote()
{
tonePlayer.stop();
}
private static Image createImage(String filename)
{
Image image = null;
try
{
image = Image.createImage(filename);
}
catch (java.io.IOException e)
{
}
return image;
}
private static TonePlayer makeTonePlayer()
{
TonePlayer player = null;
// 首先试图使用NokiaTonePlayer
try
{
// 如果不在在Nokia UI API,则下面的语句会抛出异常
Class.forName("com.nokia.mid.sound.Sound");
// 如果没有异常,我们可以创建NokiaTonePlayer
// 这里使用newInstance()而不用new ,可以消除类的依赖
Class clas = Class.forName("NokiaTonePlayer");
player = (TonePlayer)(clas.newInstance());
System.out.println( "NokiaTonePlayer Created" );
}
catch (Exception e){}
// 其次试图使用 MMATonePlayer
if( player == null ) try
{
Class.forName("javax.microedition.media.Player");
Class clas = Class.forName("MMATonePlayer");
player = (TonePlayer)(clas.newInstance());
System.out.println( "MMATonePlayer Created" );
}
catch (Exception e){}
// 如果以上两步都没有创建成功,则创建一个dumy的TonePlayer
if( player == null )
{
player = new TonePlayer();
}
return player;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -