Tuesday, 30 April 2013

marquee applet by sunil kumar dheendhwal


//================================================
// MarqueeApplet.java
// Auto-scrolling and dragging text on the screen
// Yannis Stavrakas, Jan '98
//================================================

import java.awt.*;
import java.applet.Applet;

public class MarqueeApplet extends Applet {
    int w, h;  //fixed applet width and height
    String message;
    MarqueeCanvas marquee;
    int mouseX;

//standard applet methods
    public void init() {
        //set html-file-dependent values
        w = Integer.parseInt(getParameter("width"));
        h = Integer.parseInt(getParameter("height"));
        message = getParameter("msg");
        setBackground(Color.white);
        marquee = new MarqueeCanvas(w, h);
    }
    public void start() {
        setLayout(new BorderLayout());
        add("Center", marquee);
        marquee.setMsg(message);
        marquee.initPos();
        marquee.move();
    }
    public void stop() {
        marquee.hold();
        remove(marquee);
    }
    public void destroy() {
    }
    String[][] parameterInfo = {
        {"width", "int", "the applet width"},
        {"height", "int", "the applet height"},
        {"msg", "String", "the marquee message"}
    };

//additional behaviour methods
    public boolean handleEvent (Event evt) {
        switch (evt.id) {
        case Event.MOUSE_DOWN:
            mouseX = evt.x;
            return true;
        case Event.MOUSE_UP:  //change scrolling direction
            if (evt.x == mouseX) {
                marquee.hold();
            }
            else if (evt.x < mouseX) {
                marquee.goLeft(true);
                marquee.move();
            }
            else {  //if (evt.x > mouseX)
                marquee.goLeft(false);
                marquee.move();
            }
            return true;
        }
        return super.handleEvent(evt);
    }
}

//======================================================
// Marquee msg with scrolling & dragging capabilities
// REDUCED CLASS VERSION FOR MINIMAL APPLET SIZE
//======================================================
class MarqueeCanvas extends Canvas implements Runnable {
    //marquee message
    boolean isPicture;  //marquee message is picture or text?
    Image picture;
    String text;
    Font font;
    Color color;
    //marquee dimensions
    int w;
    int h;
    //offscreen marquee image
    Image im = null;
    int imWidth = 0;
    int imHeight = 0;
    Insets insets = new Insets(2, 2, 2, 2);
    //position of image relative to canvas viewport
    int viewX = 0;
    int viewY = 0;
    //mouse X coord while draging
    int mouseX;
    //thread used as a timer for scrolling image
    Thread timerThread = null;
    boolean tempStop = false;  //class stops thread
    boolean stopped = true;    //user stops thread
    //scrolling parameters
    boolean toLeft = true;
    int advance = 1;
    int interval = 10;
    //coords of rectangle to be erased
    int dirtyX = 0;
    int dirtyY = 0;
    int dirtyW = 0;
    int dirtyH = 0;
    //component readiness to create image
    boolean ready = false;
    //draw component borders or not
    boolean borders = false;

//constructors
    public MarqueeCanvas(int w, int h) {
        this.w = w;
        this.h = h;
        //default marquee message attributes
        isPicture = false;
        picture = null;
        text = "";
        font = new Font("Helvetica", Font.BOLD, 12);
        color = Color.red;

        resize(w, h);
    }

//marquee message methods
    public void setMsg(String text) {
        if (timerThread!=null) {
            tempStop = true;
            startTimerThread(false);
        }
        dirtyRect(viewX, viewY, imWidth, imHeight);
        isPicture = false;
        this.picture = null;
        this.text = text;
        makeImage(this.text);
        repaint();
        if (tempStop) {
            tempStop = false;
            startTimerThread(true);
        }
    }

//scrolling parameter methods
    public void goLeft(boolean toLeft) {
        if (timerThread!=null) {
            tempStop = true;
            startTimerThread(false);
        }
        this.toLeft = toLeft;
        if (tempStop) {
            tempStop = false;
            startTimerThread(true);
        }
    }

//image positioning methods (relative to canvas)
    public void initPos() {
        initX();
        initY();
    }
    public void initX() {
        if (timerThread!=null) {
            tempStop = true;
            startTimerThread(false);
        }
        dirtyRect(viewX, viewY, imWidth, imHeight);
        viewX = toLeft? w-1: -(imWidth-1);       //to the edge
        repaint();
        if (tempStop) {
            tempStop = false;
            startTimerThread(true);
        }
    }
    public void initY() {
        if (timerThread!=null) {
            tempStop = true;
            startTimerThread(false);
        }
        dirtyRect(viewX, viewY, imWidth, imHeight);
        viewY = (int)Math.round((h - imHeight) / 2);  //center
        repaint();
        if (tempStop) {
            tempStop = false;
            startTimerThread(true);
        }
    }

//scrolling movement methods
    public void move() {
        startTimerThread(true);
        stopped = false;
    }
    public void hold() {
        startTimerThread(false);
        stopped = true;
    }

//standard overriden methods
    public void paint(Graphics g) {
        g.clearRect(dirtyX, dirtyY, dirtyW, dirtyH);
        resetDirtyRect();
        if (im != null) {
            g.drawImage(im, viewX, viewY, this);
        }
        if (borders) {
            g.drawRect(0, 0, w-1, h-1);
        }
    }
    public void update(Graphics g) {
        paint(g);  //this, with dirtyRect, gives smooth movement
    }
    public boolean handleEvent (Event evt) {
        Component theFrame;  //the father of all
        switch (evt.id) {
        case Event.MOUSE_ENTER:
            theFrame = getParent();
            while (theFrame.getParent() != null)
                theFrame = theFrame.getParent();
            ((Frame)theFrame).setCursor(Frame.W_RESIZE_CURSOR);
            return false;  //allow parent to get the message too
        case Event.MOUSE_EXIT:
            theFrame = getParent();
            while (theFrame.getParent() != null)
                theFrame = theFrame.getParent();
            ((Frame)theFrame).setCursor(Frame.DEFAULT_CURSOR);
            return false;
        case Event.MOUSE_DOWN:
            if (timerThread!=null) {
                tempStop = true;
                startTimerThread(false);
            }
            mouseX = evt.x;
            return false;
        case Event.MOUSE_DRAG:
            dirtyRect(viewX, viewY, imWidth, imHeight);
            viewX += evt.x - mouseX;
            mouseX = evt.x;
            if (viewX < -(imWidth-1)) viewX = -(imWidth-1);
            if (viewX > w-1) viewX = w-1;
            repaint();
            return false;
        case Event.MOUSE_UP:
            if (tempStop) {
                tempStop = false;
                startTimerThread(true);
            }
            return false;
        }
        return super.handleEvent(evt);
    }

//thread methods
    public void run() {
        while (timerThread == Thread.currentThread()) {
            if (toLeft) {
                dirtyRect(viewX+imWidth-advance, viewY, advance, imHeight);
                viewX -= advance;
                if (viewX < -(imWidth-1)) viewX = w-1;
            }
            else {
                dirtyRect(viewX, viewY, advance, imHeight);
                viewX += advance;
                if (viewX > w-1) viewX = -(imWidth-1);
            }
            repaint();
            try { Thread.sleep(interval); }
            catch (Exception e) {};
        }
    }
    void startTimerThread(boolean start) {
        if (start) {
            timerThread = new Thread(this);
            timerThread.start();
        }
        else {
            timerThread = null;
        }
    }

//create image with marquee message
    void makeImage(String text) {
        if ( ! ready) return;
        FontMetrics fm = getFontMetrics(font);
        imWidth = fm.stringWidth(text) + insets.left + insets.right;
        imHeight = fm.getHeight() + insets.top + insets.bottom;
        im = createImage(imWidth, imHeight);

        Graphics imGraph = im.getGraphics();
        imGraph.setColor(color);
        imGraph.setFont(font);
        int fontDescent = fm.getDescent();
        imGraph.drawString(text, insets.left, imHeight-fontDescent-insets.bottom);
        if (borders) {
            imGraph.drawRect(0, 0, imWidth-1, imHeight-1);
        }
        imGraph.dispose();
    }

//sets coords for dirty rectangle
    void dirtyRect(int x, int y, int w, int h) {
        //if first call after resetDirtyRect
        if (dirtyW == 0 || dirtyH == 0) {
            dirtyX = x;
            dirtyY = y;
            dirtyW = w;
            dirtyH = h;
            return;
        }
        //else calculate the bounding rect
        int minX = x < dirtyX? x: dirtyX;
        int maxX = x+w > dirtyX+dirtyW? x+w: dirtyX+dirtyW;
        int minY = y < dirtyY? y: dirtyY;
        int maxY = y+h > dirtyY+dirtyH? y+h: dirtyY+dirtyH;
        dirtyX = minX;
        dirtyY = minY;
        dirtyW = maxX - minX;
        dirtyH = maxY - minY;
    }
    void resetDirtyRect() {
        dirtyW = 0;
        dirtyH = 0;
    }

//overriden method, called by system
    public void addNotify() {
        super.addNotify();
        ready = true;  //green light to create image
    }
}

No comments:

Post a Comment