📄 renderer.java
字号:
package xcalc;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
/**
*
* @author Tobias Peirick
* @version
*/
public final class Renderer extends Canvas implements CommandListener {
private XCalc owner;
private Command exitCommand;
private Command clearCommand;
private Command calcCommand;
private Command showOptions;
private Vector formular = new Vector();
private int carretPos = 0;
private static final int OBORDER = 0;
private static final int IBORDER = 2;
private int clientWidth;
private int h1;
private int h2;
private int drawMode; //0 = Menu, 1 = 2d Graph, 2 = 3d Graph
private Real SIN_45 = null;
private Real COS_45 = null;
private static final String[] easterEgg =
{"Nos mathematici sumus",
"isti veri poetae sed",
"quod fingimus nos et","probare decet.","","Leopold Kronecker"};
public Renderer(XCalc xcalc){
this.owner = xcalc;
exitCommand = new Command("Exit", Command.EXIT, 1);
clearCommand = new Command("Clear",Command.EXIT, 1);
calcCommand = new Command("Calc", Command.OK, 1);
showOptions = new Command("Options", Command.SCREEN,1);
addCommand(exitCommand);
addCommand(calcCommand);
addCommand(showOptions);
setCommandListener(this);
SIN_45 = new Real(45);
SIN_45.sin();
COS_45 = new Real(45);
COS_45.cos();
Options.Resolution = this.getWidth()/7;
drawMode = 0;
Menu.initialize();
}
// value = (value - GraphStartX) / graphWidth*clientWidth + OBORDER
private void translateXToScreen(Real value) {
value.sub(Options.GraphStartX);
value.div(Options.graphWidth);
value.mul(clientWidth);
value.add(OBORDER);
}
// value = (h2+OBORDER+h1) - (value - GraphStartY) / graphHeight*h2
private void translateYToScreen(Real value) {
value.sub(Options.GraphStartY);
value.div(Options.graphHeight);
value.mul(h2);
value.neg();
value.add(h2+OBORDER+h1);
}
//value = (h2+OBORDER+h1) - (value - GraphStartZ) / (GraphStopZ-GraphStartZ)*h2
private void translateZToScreen(Real value){
value.sub(Options.GraphStartZ);
value.div(Options.GraphStopZ-Options.GraphStartZ);
value.mul(h2);
value.neg();
value.add(h2+OBORDER+h1);
}
private void translate3dTo2d(final Real x,
final Real y,final Real z,Real x2d, Real y2d){
//x2d = x-cos(45)*y
x2d.assign(COS_45);
x2d.mul(y);
x2d.neg();
x2d.add(x);
//y2d = z-sin(45)*y
y2d.assign(SIN_45);
y2d.mul(y);
y2d.neg();
y2d.add(z);
translateXToScreen(x2d);
//translateYToScreen(y2d);
translateZToScreen(y2d);
}
private void drawLine3d(Graphics g,
final int fx,final int fy,final int fz,
final int tx,final int ty,final int tz){
Real x1 = new Real();
Real y1 = new Real();
Real x2 = new Real();
Real y2 = new Real();
translate3dTo2d(new Real(fx),new Real(fy),new Real(fz),x1,y1);
translate3dTo2d(new Real(tx),new Real(ty),new Real(tz),x2,y2);
g.drawLine(x1.toInteger(),y1.toInteger(),x2.toInteger(),y2.toInteger());
}
private void drawGrid3d(Graphics g) {
//X-Achse
g.setColor(0xFF0000);
drawLine3d(g,Options.GraphStartX,0,0,Options.GraphStopX,0,0);
//Y-Achse
g.setColor(0x00FF00);
drawLine3d(g,0,Options.GraphStartY,0,0,Options.GraphStopY,0);
//Z-Achse
g.setColor(0x000000);
drawLine3d(g,0,0,Options.GraphStartZ,0,0,Options.GraphStopZ);
}
private void drawGraph3d(Graphics g) {
//Farbe des Graphen setzen
g.setColor(0x7F7FFF);
try {
Solver.initialize(formular.elements());
Real xVar = new Real();
Real yVar = new Real();
Real zVar;
Real x2d = new Real();
Real y2d = new Real();
int[] lastX2d = new int[Options.Resolution];
int[] lastY2d = new int[Options.Resolution];
for(int x=0;x<Options.Resolution;++x){
xVar.assign(x);
xVar.div(Options.Resolution);
xVar.mul(Options.graphWidth);
xVar.add(Options.GraphStartX);
for(int y=0;y<Options.Resolution;++y){
yVar.assign(y);
yVar.div(Options.Resolution);
yVar.mul(Options.graphHeight);
yVar.add(Options.GraphStartY);
zVar = Solver.solve(xVar,yVar);
translate3dTo2d(xVar,yVar,zVar,x2d,y2d);
if(x>0){
g.drawLine(lastX2d[y],lastY2d[y],x2d.toInteger(),y2d.toInteger());
}
lastX2d[y] = x2d.toInteger();
lastY2d[y] = y2d.toInteger();
if(y>0){
g.drawLine(lastX2d[y-1],lastY2d[y-1],lastX2d[y],lastY2d[y]);
}
}
}
} catch (Exception e) {
}
}
private void drawGrid2d(Graphics g) {
Real tempReal = new Real();
int tempX =0;
int tempY =0;
//x-axis
tempReal.assign(0);
translateYToScreen(tempReal);
tempY = tempReal.toInteger();
g.drawLine(OBORDER,tempY, this.getWidth()-OBORDER,tempY);
//y-axis
tempReal.assign(0);
translateXToScreen(tempReal);
tempX = tempReal.toInteger();
g.drawLine(tempX,h1+OBORDER,tempX,this.getHeight()-OBORDER);
}
public void drawGraph2d(Graphics g) {
//Farbe des Graphen setzen
g.setColor(0x7F7FFF);
//Reset der temp Variablen
int lastX = 0;
int lastY = 0;
try {
Solver.initialize(formular.elements());
Real currentX = new Real();
Real currentY;
for(int x = 0;x<=Options.Resolution;++x) {
currentX.assign(x);
currentX.div(Options.Resolution);
currentX.mul(Options.graphWidth);
currentX.add(Options.GraphStartX);
currentY = Solver.solve(currentX);
if(currentY.isNan()){
//System.out.println("x="+x+" y=NAN");
} else if (currentY.isInfinity()) {
//System.out.println("x="+x+" y=INF");
} else {
//Umrechnen in Screen Koordinaten
translateXToScreen(currentX);
translateYToScreen(currentY);
//Zeichnen wenn der zweite Punkt berechnent wurde
if( lastX!=0 || lastY!=0) {
g.drawLine(lastX,lastY,currentX.toInteger(),currentY.toInteger());
}
//System.out.println("x="+x+" y="+y);
//Speichern der Koordinaten f黵 n鋍hste Linie
lastX = currentX.toInteger();
lastY = currentY.toInteger();
}
}
} catch (Exception e) {
}
}
private void drawInput(Graphics g){
//Zeichne das Fach
g.setColor(0xFFA500);
g.fillRoundRect(OBORDER,OBORDER,clientWidth,h1,5,5);
g.setColor(0x000000);
g.drawRoundRect(OBORDER,OBORDER,clientWidth,h1,5,5);
int xPos = OBORDER+IBORDER;
int yPos = OBORDER+IBORDER;
String token;
for(int i = 0; i<=formular.size(); ++i){
//Zeichnen der aktuellen Position in der Formel
if(drawMode==0 && i==carretPos){
token = "|";
g.setColor(0xFFFFFF);
g.drawString(token,xPos,yPos,Graphics.TOP|Graphics.LEFT);
g.setColor(0x000000);
xPos+=g.getFont().stringWidth(token);
}
//Zeichnen eines Teils der Formel
if(i<formular.size()){
token = (String)formular.elementAt(i);
//word wrap
if(xPos+g.getFont().stringWidth(token)>=this.getWidth()-OBORDER-IBORDER){
yPos += g.getFont().getHeight();
xPos = OBORDER+IBORDER;
}
//St點k der Formel zeichnen
g.drawString(token,xPos,yPos,Graphics.TOP|Graphics.LEFT);
xPos+=g.getFont().stringWidth(token);
}
}
}
public void paint(Graphics g) {
g.setColor(0x000000);
g.fillRect(0,0,this.getWidth(),this.getHeight());
String formularString = getTokenstring();
//Breite und H鰄en der F鋍her berechnen
clientWidth = this.getWidth()-2*OBORDER;
h1 = g.getFont().getHeight()*(g.getFont().stringWidth(formularString)/clientWidth+1)+2*IBORDER;
h2 = this.getHeight()-2*OBORDER-h1;
drawInput(g);
g.setColor(0xFFFFE0);
g.fillRoundRect(OBORDER,h1+OBORDER,clientWidth,h2,5,5);
g.setColor(0x000000);
g.drawRoundRect(OBORDER,h1+OBORDER,clientWidth,h2,5,5);
//easter egg
if(formularString.equals("70PI")) {
int y = h1+OBORDER+IBORDER;
for(int i = 0; i<easterEgg.length;++i){
g.drawString(easterEgg[i], this.getWidth()/2,y,Graphics.TOP|Graphics.HCENTER);
y += g.getFont().getHeight();
}
} else{
switch(drawMode){
case 0:
Menu.draw(g,OBORDER+IBORDER,h1+OBORDER+IBORDER,
clientWidth-IBORDER,h2-IBORDER);
if(Menu.isRoot()){
g.setColor(0x000000);
int dy = g.getFont().getHeight();
int y = h1+OBORDER+IBORDER;
int x1= OBORDER+IBORDER;
int x2= this.getWidth()-OBORDER-IBORDER;
for (int i = 0; i<XCalc.history.size();++i){
g.drawString(XCalc.history.getFormular(i) + " =",x1,y,Graphics.TOP|Graphics.LEFT);
y += dy;
g.drawString(XCalc.history.getResult(i),x2,y,Graphics.TOP|Graphics.RIGHT);
y += dy;
}
}
break;
case 1:
drawGrid2d(g);
drawGraph2d(g);
break;
case 2:
drawGrid3d(g);
drawGraph3d(g);
break;
}
}
g.setColor(0xFFA500);
g.drawString("peirick@gmail.com",this.getWidth()/2,this.getHeight(),Graphics.BOTTOM|Graphics.HCENTER);
}
public void keyRepeated(int keyCode) {
if(keyCode != KEY_STAR && keyCode != KEY_POUND){
keyPressed(keyCode);
}
}
public void keyPressed(int keyCode){
switch(drawMode){
case 0:
if (Menu.handle(keyCode)) {
if(Menu.selected != null){
addToken(Menu.selected);
}
} else if(!Menu.isRoot() &&
//-11 is special sony ericson backkey
(keyCode == -11 || getGameAction(keyCode)==DOWN )){
Menu.setParent();
} else if(getGameAction(keyCode)==LEFT ) {
if(carretPos>0)
--carretPos;
else
carretPos = formular.size();
} else if(getGameAction(keyCode)==RIGHT ) {
if(carretPos<formular.size())
++carretPos;
else
carretPos = 0;
// -8 is special sony ericson clearkey
} else if(keyCode == -8){
removeToken();
}
repaint();
break;
case 1:
case 2:
switch(getGameAction(keyCode)){
case UP: keyCode = KEY_NUM2; break;
case LEFT: keyCode = KEY_NUM4; break;
case RIGHT: keyCode = KEY_NUM6; break;
case DOWN: keyCode = KEY_NUM8; break;
}
switch(keyCode){
case KEY_NUM2:
--Options.GraphStartY;
--Options.GraphStopY;
break;
case KEY_NUM4:
++Options.GraphStartX;
++Options.GraphStopX;
break;
case KEY_NUM6:
--Options.GraphStartX;
--Options.GraphStopX;
break;
case KEY_NUM8:
++Options.GraphStartY;
++Options.GraphStopY;
break;
case KEY_NUM1:
--Options.GraphStartX;
++Options.GraphStopX;
break;
case KEY_NUM7:
if(Options.GraphStopX-2>Options.GraphStartX){
++Options.GraphStartX;
--Options.GraphStopX;
}
break;
case KEY_NUM3:
--Options.GraphStartY;
++Options.GraphStopY;
break;
case KEY_NUM9:
if(Options.GraphStopY-2>Options.GraphStartY){
++Options.GraphStartY;
--Options.GraphStopY;
}
break;
case KEY_STAR:
drawMode = 0;
}
Options.graphWidth = Options.GraphStopX-Options.GraphStartX;
Options.graphHeight = Options.GraphStopY-Options.GraphStartY;
repaint();
break;
};
}
protected void pointerPressed(int x, int y) {
if(drawMode == 0){
if (Menu.handle(x,y,
OBORDER+IBORDER,
h1+OBORDER+IBORDER,
clientWidth-IBORDER,
h2-IBORDER)){
if(Menu.selected != null){
addToken(Menu.selected);
}
}
} else {
drawMode = 0;
}
repaint();
}
public void commandAction(Command c, Displayable d) {
if (c == exitCommand ) {
owner.notifyDestroyed();
} else if(c == showOptions){
XCalc.options.show();
} else if (c == clearCommand) {
removeToken();
} else if (c == calcCommand) {
//normaler Menu modus
drawMode = 0;
// Enth鋖t formular ein X oder ein Y?
for (Enumeration e = formular.elements() ; e.hasMoreElements();) {
final String element = (String)e.nextElement();
if(element.equals("x") && drawMode == 0){
drawMode = 1; //2d graph
}
if(element.equals("y")){
drawMode = 2; //3d graph
break;
}
}
//Calculate
try {
if (drawMode == 0){
Solver.initialize(formular.elements());
final Real real = Solver.solve();
XCalc.history.add(formular,real);
clearAllToken();
} else {
XCalc.history.add(formular,Real.NAN);
}
} catch(Exception e) {
}
repaint();
}
}
private void clearAllToken(){
formular = new Vector();
carretPos = 0;
removeCommand(clearCommand);
addCommand(exitCommand);
}
private void removeToken(){
if(carretPos>0){
--carretPos;
formular.removeElementAt(carretPos);
}
if (formular.size()==0){
removeCommand(clearCommand);
addCommand(exitCommand);
}
repaint();
}
private void addToken(String token){
if(!token.equals("")){
formular.insertElementAt(token,carretPos);
++carretPos;
if(formular.size()==1) {
removeCommand(exitCommand);
addCommand(clearCommand);
}
if(token == Solver.C_COMMANDS[Solver.K_PER] ||
token == Solver.C_COMMANDS[Solver.K_COM]){
formular.insertElementAt(Solver.C_COMMANDS[Solver.K_SEMI],carretPos);
}
}
}
private String getTokenstring() {
StringBuffer result = new StringBuffer();
for (Enumeration e = formular.elements() ; e.hasMoreElements();) {
result.append(e.nextElement());
}
return result.toString();
}
public void show() {
XCalc.display.setCurrent(this);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -