⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postcardcanvas.java

📁 J2ME MIDP_Example_Applications
💻 JAVA
字号:
// Copyright 2002 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.postcard;

import javax.microedition.lcdui.*;
import java.util.Random;
import java.util.Vector;


// The main canvas of the MIDlet. It contains text and a floating
// animation, and plays a tune (Smart Messaging Ringing Tone format).

class PostcardCanvas
    extends Canvas
    implements CommandListener, Runnable
{
    private static final int BORDER = 2;
    private static final int SLIDER_WIDTH = 4;
    private static final Font FONT = Font.getFont(Font.FACE_MONOSPACE,
        Font.STYLE_PLAIN, Font.SIZE_SMALL);

    private final PostcardMIDlet midlet;
    private final Command exitCommand;
    private final Command silentCommand;
    private final Command playCommand;
    private final ContinuousTunePlayer player;

    private final int lineHeight, lineWidth, maxLines;
    private final Vector textLines = new Vector();

    private int topLine = 0;
    private volatile Thread animationThread = null;
    private Animation animation = null;
    private boolean isUpPressed = false;
    private boolean isDownPressed = false;
    private boolean firstPlayRequest = true;
    private volatile boolean isPlaying = false;


    // The constructor for the PostcardCanvas:
    // 'midlet' is the parent MIDlet, used for callbacks such as exit requests.
    // 'message' is the text message to be displayed.
    // 'tune' is a hexadecimal representation of the tune to be played.
    //     The bytes are in Smart Messaging Ringing Tone format.
    // 'animationSequence' is the sequence of animation images.
    //     It may be null. In that case, no animation is
    //     performed and just the text and tune are used.

    PostcardCanvas(PostcardMIDlet midlet, String message, String tune,
        AnimationSequence animationSequence)
    {
        this.midlet = midlet;

        lineWidth = getWidth() - (2 * BORDER) - SLIDER_WIDTH;
        lineHeight = FONT.getHeight();
        maxLines = (getHeight() - (2 * BORDER)) / lineHeight;


        // Split the message into multiple lines of text.
        // The approach used isn't very smart. It doesn't do word
        // splitting or word wrapping, to keep this example simple.
        if (FONT.stringWidth(message) < lineWidth)
        {
            // the message fits in a single line of text
            textLines.addElement(message);
        }
        else
        {
            // multiple lines of text are needed
            int offset = 0;
            int len = 1;
            while((offset + len) <= message.length())
            {
                while(((offset + len) <= message.length()) &&
                     (FONT.substringWidth(message, offset, len) <= lineWidth))
                {
                    len++;
                }
                textLines.addElement(message.substring(offset,
                                                       offset + len - 1));
                offset += (len - 1);
                len = 1;
            }
        }


        // create the animation sequence
        if (animationSequence != null)
        {
            try
            {
                animation = new Animation(animationSequence, BORDER, BORDER,
                                          (getWidth() - SLIDER_WIDTH - BORDER),
                                          (getHeight() - BORDER));
            }
            catch(Exception e)
            {
                // By default, animation is null.
            }
        }


        // create the tune player
        player = makeContinuousTunePlayer();
        if (tune != null)
        {
            try
            {
                player.setTune(tune);
            }
            catch(Exception e)
            {
                // There is some problem with the setting (e.g. invalid
                // hexadecimal data, invalide tune data) or playing the tune.
                // A tune will not be played in this case.
            }
        }


        // add the screen's commands
        exitCommand = new Command("Exit", Command.EXIT, 1);
        addCommand(exitCommand);
        if (player.hasSoundSupport())
        {
            playCommand = new Command("Play", Command.SCREEN, 2);
            silentCommand = new Command("Silent", Command.SCREEN, 2);
            addCommand(playCommand);
        }
        else
        {
            playCommand = null;
            silentCommand = null;
        }
        setCommandListener(this);
    }


    synchronized void start()
    {
        animationThread = new Thread(this);
        animationThread.start();

        player.restart();
    }


    synchronized void stop()
    {
        animationThread = null;

        player.stop();
    }


    public void run()
    {
        int millisPerTick = 100;

        Thread currentThread = Thread.currentThread();

        try
        {
            // This ends when animationThread is set to null, or when
            // it is subsequently set to a new thread; either way, the
            // current thread should terminate
            while (currentThread == animationThread)
            {
                long startTime = System.currentTimeMillis();

                // No animation progress if we are hidden by a system screen.
                if (isShown())
                {
                    tick();

                    repaint(0, 0, getWidth(), getHeight());
                    serviceRepaints();
                }

                long timeTaken = System.currentTimeMillis() - startTime;
                if (timeTaken < millisPerTick)
                {
                    synchronized (this)
                    {
                        wait(millisPerTick - timeTaken);
                    }
                }
                else
                {
                    currentThread.yield();
                }
            }
        }
        catch (InterruptedException e)
        {
        }
    }


    private void tick()
    {
        if (isUpPressed)
        {
            if ((topLine - 1) < 0)
            {
                topLine = 0;
            }
            else
            {
                topLine--;
            }
        }
        else if (isDownPressed)
        {
            if (textLines.size() > 0)
            {
                if ((topLine + maxLines) < textLines.size())
                {
                    topLine++;
                }
            }
        }

        if (animation != null)
        {
            animation.tick();
        }
    }


    public void paint(Graphics g)
    {
        // wipe the entire canavas clean
        g.setColor(0xffffff); // WHITE
        g.fillRect(0, 0, getWidth(), getHeight());

        // draw the animation

        g.setColor(0x000000); // BLACK
        g.setFont(FONT);
        int ix=0;
        for (ix=0; ((ix < maxLines) && ((topLine + ix) < textLines.size()));
             ix++)
        {
            g.drawString((String)textLines.elementAt(topLine + ix),
                         BORDER, (BORDER + (lineHeight * ix)),
                         (Graphics.TOP | Graphics.LEFT));
        }

        // Add a 'slider' in case the number of text lines
        // is longer than fits on one display.
        if (textLines.size() > maxLines)
        {
            drawSlider(g, topLine, textLines.size());
        }

        animation.draw(g);
    }


    public void keyPressed(int keyCode)
    {
        int action = getGameAction(keyCode);
        if (action == UP)
        {
            isUpPressed = true;
            isDownPressed = false;
            if (topLine > 0)
            {
                topLine--;
            }
        }
        else if (action == DOWN)
        {
            isDownPressed = true;
            isUpPressed = false;
            if((topLine + maxLines) < textLines.size())
            {
                topLine++;
            }
        }
    }


    public void keyReleased(int keyCode)
    {
        int action = getGameAction(keyCode);
        if (action == UP)
        {
            isUpPressed = false;
        }
        else if (action == DOWN)
        {
            isDownPressed = false;
        }
    }


    // If the number of text lines exceeds the amount that can
    // be displayed in one screen, then a text slider is drawn
    // to indicate the position of the displayed text within
    // the entire text message.

    private void drawSlider(Graphics g, int index, int length)
    {
        int x = getWidth() - SLIDER_WIDTH;
        int y = 0;
        // The text slider is drawn in the area from
        // {x, y} = {x, 0} to {x + SLIDER_WIDTH, getHeight()}

        int sy = 2; // initial slider y-position
        int sh = 6; // slider height in pixels

        // Leave a 2 pixel offset at the top and bottom, for the slider's rail
        // to protrude past the slider. The rail's length = full canvas height.
        int syMax = getHeight() - sh - 2 - 2;

        if ((index == 0) || (length == 0))
        {
            sy = 2;
        }
        else
        {
            sy = 2 + ((syMax * index) / length);
        }

                                               // (x+0 is empty space)
        g.setColor(0x000000);                  // BLACK
        g.drawLine(x+1, sy, x+1, sy+sh);       //   slider
        g.drawLine(x+2, 0,  x+2, getHeight()); //   rail
        g.drawLine(x+3, sy, x+3, sy+sh);       //   slider
        g.setColor(0xffffff);                  // WHITE
        g.drawLine(x+2, sy, x+2, sy+sh);       //   slider
    }


    public void commandAction(Command c, Displayable d)
    {
        if (c == exitCommand)
        {
            stop();
            midlet.exitRequested();
        }
        else if (player.hasSoundSupport() && (c == silentCommand))
        {
            setIsPlaying(false);
            player.stop();
            removeCommand(silentCommand);
            addCommand(playCommand);
        }
        else if (player.hasSoundSupport() && (c == playCommand))
        {
            setIsPlaying(true);
            if (firstPlayRequest)
            {
                firstPlayRequest = false;
                player.playContinuously();
            }
            else
            {
                player.restart();
            }
            removeCommand(playCommand);
            addCommand(silentCommand);
        }
    }


    private synchronized void setIsPlaying(boolean isPlaying)
    {
        this.isPlaying = isPlaying;
    }


    public void hideNotify()
    {
        setIsPlaying(false);
        player.stop();

        // We aren't sure which commands are currently available;
        // we remove both to be safe and add the play command so
        // it's available when the MIDlet is visible again.
        // Rather than using 'showNotify' to resume playing, allow
        // a manually requested resume using the 'Play' command.
        removeCommand(playCommand);
        removeCommand(silentCommand);
        addCommand(playCommand);
    }


    private static ContinuousTunePlayer makeContinuousTunePlayer()
    {
       // Other types of ContinuousTunePlayers could be
       // added here in the future if needed.

       ContinuousTunePlayer player;
       try
       {
           // Throw an exception if no Nokia UI API available.
           Class.forName("com.nokia.mid.sound.Sound");
           Class clas = Class.forName(
               "example.postcard.NokiaContinuousTunePlayer");
           player = (ContinuousTunePlayer)(clas.newInstance());
       }
       catch (Exception e)
       {
           player = new ContinuousTunePlayer();
       }

       return player;
    }
}

⌨️ 快捷键说明

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