compasscanvas.java

来自「这是一个手机上的J2ME程序」· Java 代码 · 共 211 行

JAVA
211
字号
// J2ME Compass
// Copyright (C) 2007 Dana Peters
// http://www.qcontinuum.org/compass

package org.qcontinuum.compass;

import javax.microedition.lcdui.*;
import org.qcontinuum.astro.*;
import henson.midp.Float;
import java.util.*;

class CompassCanvas extends Canvas implements CommandListener, Runnable {

    private Preferences mPreferences;
    private Command mInfoCommand, mLocationCommand;
    private Command mDestinationCommand, mDateCommand, mOptionsCommand;
    private Command mAboutCommand, mExitCommand;
    private SunMoonPosition mSunMoonPosition;

    public CompassCanvas() {
        mPreferences = Compass.getPreferences();
        mSunMoonPosition = null;
        addCommand(mInfoCommand = new Command("Info", Command.SCREEN, 0));
        addCommand(mLocationCommand = new Command("Location", Command.SCREEN, 1));
        addCommand(mDestinationCommand = new Command("Destination", Command.SCREEN, 1));
        addCommand(mDateCommand = new Command("Date", Command.SCREEN, 1));
        addCommand(mOptionsCommand = new Command("Options", Command.SCREEN, 1));
        addCommand(mAboutCommand = new Command("About", Command.SCREEN, 1));
        addCommand(mExitCommand = new Command("Exit", Command.EXIT, 0));
        setCommandListener(this);
    }

    public void commandAction(Command c, Displayable s) {
        if (c == mInfoCommand) {
            if (mPreferences.getLocation() == null)
                Compass.display("Please set location.", this);
            else
                Compass.display(new InfoMenu(this));
        } else if (c == mLocationCommand) {
            Compass.display(new LocationMap(this, false));
        } else if (c == mDestinationCommand) {
            Compass.display(new LocationMap(this, true));
        } else if (c == mDateCommand) {
            Compass.display(new SetDate(this));
        } else if (c == mOptionsCommand) {
            Compass.display(new Options(this));
        } else if (c == mAboutCommand) {
            InfoDisplay infoDisplay = new InfoDisplay("About Compass", this);
            infoDisplay.append(new StringItem(null, "Compass 4.1\n"));
            infoDisplay.append(new StringItem(null, "\u00A9 2007 Dana Peters\n"));
            infoDisplay.append(new StringItem(null, "http://qcontinuum.org/compass\n"));
            infoDisplay.append(new StringItem(null, " \n"));
            infoDisplay.append(new StringItem(null, "This program enables you to use your cell phone as a compass. " +
                "Find north by rotating the phone so that the sun and/or moon icons match their location in the sky.\n"));
            infoDisplay.append(new StringItem(null, " \n"));
            infoDisplay.append(new StringItem(null, "GNU General Public License\n"));
            infoDisplay.append(new StringItem(null, "Absolutely no warranty\n"));
            infoDisplay.append(new StringItem(null, " \n"));
            infoDisplay.append(new StringItem("Math library:", "http://henson.newmail.ru\n"));
            infoDisplay.append(new StringItem("Airport database:", "http://partow.net/miscellaneous/airportdatabase\n"));
            Compass.display(infoDisplay);
        } else if (c == mExitCommand) {
            Compass.exit();
        }
    }

    public void run() {
        recalculate();
        repaint();
    }

    private void recalculate() {
        mSunMoonPosition = new SunMoonPosition(Compass.getDate());
    }

    public void paint(Graphics g) {
        synchronized (g) {
            int midX = getWidth() / 2;
            int midY = getHeight() / 2;
            int maxR = Math.min(midX, midY);
            int i;
            for (i = 6; i > 0; i--) {
                int r = maxR * i / 6;
                if (i == 6) {
                    if (mSunMoonPosition == null || mSunMoonPosition.getSunPosition().getElevation() > -10) {
                        g.setColor(0xFFFFFF);
                        g.fillRect(0, 0, getWidth(), getHeight());
                        g.setColor(mPreferences.DayColour);
                    } else {
                        g.setColor(0x000000);
                        g.fillRect(0, 0, getWidth(), getHeight());
                        g.setColor(mPreferences.NightColour);
                    }
                    g.fillArc(midX - r, midY - r, r * 2, r * 2, 0, 360);
                    g.setColor(g.getRedComponent()/2, g.getGreenComponent()/2, g.getBlueComponent()/2);
                }
                g.drawArc(midX - r, midY - r, r * 2, r * 2, 0, 360);
            }
            HorizontalPosition lineSkyPosition = new HorizontalPosition(0, 0);
            int step;
            int azimuthOffset = 0;
            if (mSunMoonPosition != null) {
                HorizontalPosition sunPosition = mSunMoonPosition.getSunPosition();
                HorizontalPosition moonPosition = mSunMoonPosition.getMoonPosition();
                EarthHeading destinationHeading = mSunMoonPosition.getDestinationHeading();
                switch (mPreferences.ScreenTop) {
                    case 0: // North up
                        break;
                    case 1: // Sun or Moon up
                        if (sunPosition.getElevation() > -10)
                            azimuthOffset = sunPosition.getAzimuth();
                        else if (moonPosition.getElevation() > -5)
                            azimuthOffset = moonPosition.getAzimuth();
                        break;
                    case 2: // Destination up
                        if (destinationHeading != null)
                            azimuthOffset = destinationHeading.getHeading();
                        break;
                }
            }
            boolean flipX = mPreferences.ScreenDown;
            for (step = 0; step < 8; step++) {
                lineSkyPosition.setAzimuth(step * 45);
                ScreenPosition lineScreenPosition = lineSkyPosition.toScreenPosition(this, azimuthOffset, flipX);
                g.drawLine(midX, midY, lineScreenPosition.x, lineScreenPosition.y);
            }
            Font labelFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
            g.setFont(labelFont);
            HorizontalPosition labelSkyPosition = new HorizontalPosition(0, 10);
            String labels[] = {"N", "E", "S", "W"};
            int radius = Math.max(labelFont.charWidth('W'), labelFont.getHeight())/2;
            for (i = 0; i < labels.length; i++) {
                labelSkyPosition.setAzimuth(i * 90);
                ScreenPosition label = labelSkyPosition.toScreenPosition(this, azimuthOffset, flipX);
                g.setColor(0x008080);
                g.fillRoundRect(label.x - radius, label.y - radius, radius * 2, radius * 2, 8, 8);
                g.setColor(0x000000);
                g.drawString(labels[i], label.x, label.y - labelFont.getHeight()/2, g.TOP|g.HCENTER);
            }
            if (mPreferences.getLocation() == null) {
                g.drawString("Please set", midX, midY, g.BOTTOM|g.HCENTER);
                g.drawString("Location", midX, midY, g.TOP|g.HCENTER);
            } else if (Compass.getRefresh() || mSunMoonPosition == null) {
                Compass.setRefresh(false);
                g.drawString("Please", midX, midY, g.BOTTOM|g.HCENTER);
                g.drawString("Wait", midX, midY, g.TOP|g.HCENTER);
                Compass.getDisplay().callSerially(this);
            } else {
                HorizontalPosition sunPosition = mSunMoonPosition.getSunPosition();
                HorizontalPosition moonPosition = mSunMoonPosition.getMoonPosition();
                Float moonPhase = mSunMoonPosition.getMoonPhase();
                EarthHeading destinationHeading = mSunMoonPosition.getDestinationHeading();
                if (sunPosition.getElevation() <= -10 && moonPosition.getElevation() <= -5) {
                    g.drawString("No Sun", midX, midY, g.BOTTOM|g.HCENTER);
                    g.drawString("or Moon", midX, midY, g.TOP|g.HCENTER);
                }
                int r = Math.max(maxR / 6, 8);
                int d = r * 2;
                if (moonPosition.getElevation() > -5) {
                    ScreenPosition moon = moonPosition.toScreenPosition(this, azimuthOffset, flipX);
                    HorizontalPosition line = new HorizontalPosition(moonPosition.getAzimuth(), 0);
                    ScreenPosition line1 = line.toScreenPosition(this, azimuthOffset, flipX);
                    line.setAzimuth(line.getAzimuth() + 180);
                    ScreenPosition line2 = line.toScreenPosition(this, azimuthOffset, flipX);
                    g.setStrokeStyle(g.DOTTED);
                    g.drawLine(line1.x, line1.y, line2.x, line2.y);
                    g.setStrokeStyle(g.SOLID);
                    g.setColor(0xffffff);
                    g.fillArc(moon.x - r, moon.y - r, d, d, 90, 180);
                    g.setColor(0x000000);
                    g.fillArc(moon.x - r, moon.y - r, d, d, 270, 180);
                    int arcWidth = (int)(moonPhase.Sub(new Float(5, -1)).Mul(d * 2).toLong());
                    g.setColor(arcWidth < 0 ? 0x000000 : 0xffffff);
                    g.fillArc(moon.x - Math.abs(arcWidth)/2, moon.y - r, Math.abs(arcWidth), d, 0, 360);
                    g.setColor(0x000000);
                    g.drawArc(moon.x - r, moon.y - r, d, d, 0, 360);
                }
                if (sunPosition.getElevation() > -10) {
                    ScreenPosition sun = sunPosition.toScreenPosition(this, azimuthOffset, flipX);
                    HorizontalPosition line = new HorizontalPosition(sunPosition.getAzimuth(), 0);
                    ScreenPosition line1 = line.toScreenPosition(this, azimuthOffset, flipX);
                    line.setAzimuth(line.getAzimuth()+ 180);
                    ScreenPosition line2 = line.toScreenPosition(this, azimuthOffset, flipX);
                    g.setStrokeStyle(g.DOTTED);
                    g.drawLine(line1.x, line1.y, line2.x, line2.y);
                    g.setStrokeStyle(g.SOLID);
                    g.setColor(0xffff00);
                    g.fillArc(sun.x - r, sun.y - r, d, d, 0, 360);
                    g.setColor(0x000000);
                    g.drawArc(sun.x - r, sun.y - r, d, d, 0, 360);
                }
                if (destinationHeading != null) {
                    g.setColor(0x00ffff);
                    HorizontalPosition destinationSkyPosition = new HorizontalPosition(destinationHeading.getHeading(), 0);
                    ScreenPosition line1 = destinationSkyPosition.toScreenPosition(this, azimuthOffset, flipX);
                    destinationSkyPosition.setAzimuth(destinationSkyPosition.getAzimuth() + 180);
                    ScreenPosition line2 = destinationSkyPosition.toScreenPosition(this, azimuthOffset, flipX);
                    g.setStrokeStyle(g.DOTTED);
                    g.drawLine(line1.x, line1.y, line2.x, line2.y);
                    destinationSkyPosition.setElevation(10);
                    destinationSkyPosition.setAzimuth(destinationHeading.getHeading());
                    ScreenPosition labelPosition = destinationSkyPosition.toScreenPosition(this, azimuthOffset, flipX);
                    g.fillRoundRect(labelPosition.x - radius, labelPosition.y - radius, radius * 2, radius * 2, 8, 8);
                    g.setColor(0x000000);
                    g.drawString("D", labelPosition.x, labelPosition.y - labelFont.getHeight()/2, g.TOP|g.HCENTER);
                }
            }
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?