Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Ticker panel



Here's the "view" portion (graphical display) of a ticker:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

public class Typewriter extends Component
{
	/////////////////
	// Global vars //
	/////////////////
	public static final boolean DEBUG = true;

	// Use high quality graphics?
	public static final boolean HQ_GRAPHICS = true;

	private static final int WIDTH  = 600;
	private static final int HEIGHT = 300;

	private static final int IMAGE_WIDTH  = 432;
	private static final int IMAGE_HEIGHT = 270;

private static final Dimension imageSize = new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT);;

	private static final int LINE_WIDTH = 58;

    /////////////////////////
    // Class instance vars //
    /////////////////////////
	private BufferedImage image;

	private final Color bgColor = Color.white;
	private final Color fgColor = rgb("000099");
	private final Color borderColor = rgb("ffd700");
	private final int borderWidth = 3;

private final String fontName = "Verdana"; // "Arial" "Verdana" "Helvetica" "SansSerif"
private final int fontSize = 14;
private final Font font = new Font(fontName, Font.PLAIN, fontSize); // Font.BOLD
private final int x = fontSize >> 1;
private final int dy = fontSize + 1;
private int y = dy;
private Ticker ticker = null;
private String text = " ";
private String[] wrappedText = null;


	//////////////////////
	// Thread variables //
	//////////////////////
	private Thread animation = null;
	private volatile boolean noStopRequested;
	private volatile boolean paused;
	private final Object lock = new Object();

/////////////////
// Constructor //
/////////////////
public Typewriter()
{
// Set up image
image = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice ().getDefaultConfiguration().createCompatibleImage(imageSize.width, imageSize.height);


		// Render initial blank image
		if (HQ_GRAPHICS)
			renderImageHQ();
		else
			renderImage();

		// Set component's dimensions
		setSize(IMAGE_WIDTH, IMAGE_HEIGHT);

// Create the ticker
// final String msg = "I've thunk/3ought/ about it and the question /9answer/ is 42.";
ticker = new Ticker();


		// Acts like start()
		startThread();
	}

	public Dimension getMinimumSize()
	{
		return imageSize;
	}

	public Dimension getMaximumSize()
	{
		return imageSize;
	}

	public Dimension getPreferredSize()
	{
		return imageSize;
	}

	//////////////////////////////////////////
	// Clear the ticker and the back buffer //
	//////////////////////////////////////////
	private void clear()
	{
		if (isRunning()) stop();

		text = " ";
		ticker.clearTheTicker();

		final Graphics gBB = image.createGraphics();

		gBB.setColor(borderColor);
		gBB.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);

gBB.setColor(bgColor);
gBB.fillRect(borderWidth, borderWidth, IMAGE_WIDTH-2*borderWidth, IMAGE_HEIGHT-2*borderWidth);


		gBB.dispose();

		repaint(0);
	}

	//////////////////////////////
	// Set the ticker's message //
	//////////////////////////////
	public synchronized void setTickerText(final String msg)
	{
		if (ticker != null)
		{
			clear();
			ticker.setFirstStory(msg);
			start();
		}
	}

	//////////////////////////////////////
	// Render to off-screen/back buffer //
	//////////////////////////////////////
	private void renderImage()
	{
		final Graphics gBB = image.createGraphics();

		gBB.setColor(borderColor);
		gBB.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);

gBB.setColor(bgColor);
gBB.fillRect(borderWidth, borderWidth, IMAGE_WIDTH-2*borderWidth, IMAGE_HEIGHT-2*borderWidth);


		gBB.setColor(fgColor);
		gBB.setFont(font);
		if (text.length() <= LINE_WIDTH)
		{
			gBB.drawString(text, x,y);
		}
		else
		{
			for (int i=0; i<wrappedText.length; i++)
			{
				gBB.drawString(wrappedText[i], x,y);
				y += dy;
			}
			wrappedText = null;
		}
		gBB.dispose();
	}

	///////////////////////////////////////////////////
	// High-quality render to off-screen/back buffer //
	///////////////////////////////////////////////////
	private void renderImageHQ()
	{
		// Request that the drawing be done with anti-aliasing
		// turned on and the quality high.
		final RenderingHints renderHints = new RenderingHints
		(
			RenderingHints.KEY_ANTIALIASING,
			RenderingHints.VALUE_ANTIALIAS_ON
		);
		renderHints.put
		(
			RenderingHints.KEY_RENDERING,
			RenderingHints.VALUE_RENDER_QUALITY
		);

		final Graphics2D gBB = image.createGraphics();
		gBB.setRenderingHints(renderHints);

gBB.setColor(bgColor);
gBB.fillRect(borderWidth, borderWidth, IMAGE_WIDTH-2*borderWidth, IMAGE_HEIGHT-2*borderWidth);


		gBB.setColor(fgColor);
		gBB.setFont(font);
		if (text.length() <= LINE_WIDTH)
		{
			gBB.drawString(text, x,y);
		}
		else
		{
			for (int i=0; i<wrappedText.length; i++)
			{
				gBB.drawString(wrappedText[i], x,y);
				y += dy;
			}
			wrappedText = null;
		}
		gBB.dispose();
	}

	///////////
	// paint //
	///////////
	public void paint(final Graphics g)
	{
		// Precaution for Linux systems
		Toolkit.getDefaultToolkit().sync();

		// Use DOUBLE-BUFFERING:
		// Blit offscreen/back buffer to screen.
		g.drawImage(image, 0, 0, this);
	}

	////////////////////////////////////////////////
	// Override update so it doesn't erase screen //
	////////////////////////////////////////////////
	public void update(final Graphics g)
	{
		paint(g);
	}

	/////////////////////////
	// Start the animation //
	/////////////////////////
	public void startThread()
	{
		paused = true;
		noStopRequested = true;

		// Use this inner class to hide the public run method
		Runnable r = new Runnable()
		{
			public void run()
			{
				runWork();
			}
		};
		animation = new Thread(r, "Animation");
		animation.start();
	}

	////////////////////
	// Animation Loop //
	////////////////////
	private void runWork()	// note that this is private
	{
		try
		{
			while (noStopRequested)
			{
				waitWhilePaused();
				
				// Advance ticker one letter
				text = ticker.tick();
//				System.out.println("Text: " + text);

				// Insert line breaks into text if necessary
				if (text.length() > LINE_WIDTH)
				{
					wrappedText = wrap(text, LINE_WIDTH, '|').split("\\|");
					y = dy;
				}

				// Render the text onto an image
				if (HQ_GRAPHICS)
					renderImageHQ();
				else
					renderImage();

				// Refresh display
				repaint(0);

				// Let the ticker determine its own frame rate
				Thread.sleep(ticker.getDelay());
			}
		}
		catch (InterruptedException x)
		{
			Thread.currentThread().interrupt();
			System.out.println("Thread interrupted in run()");
		}
	}

	/////////////////////////////
	// Animation thread alive? //
	/////////////////////////////
	public boolean isAlive()
	{
		return animation.isAlive();
	}

	/////////////////////
	// start animation //
	/////////////////////
	public void start()
	{
		setPaused(false);
		System.out.println("<< start >>");
	}

	///////////////
	// Soft stop //
	///////////////
	public void stop()
	{
		setPaused(true);
		System.out.println(">> stop <<");
	}

	///////////////
	// Hard stop //
	///////////////
	private void stopThread()
	{
		noStopRequested = false;
		animation.interrupt();
	}

	/////////////
	// destroy //
	/////////////
	public void destroy()
	{
		stopThread();
	}

	///////////////////////////////////////////
	// Set paused state - running or paused? //
	///////////////////////////////////////////
	private void setPaused(final boolean newPauseState)
	{
		synchronized(lock)
		{
			if (paused != newPauseState)
			{
				paused = newPauseState;
				lock.notifyAll();
			}
		}
	}

	////////////////////////////
	// Pause animation thread //
	////////////////////////////
	private void waitWhilePaused() throws InterruptedException
	{
		synchronized(lock)
		{
			while (paused)
			{
				lock.wait();
			}
		}
	}

	/////////////////////
	// Are we running? //
	/////////////////////
	public synchronized boolean isRunning()
	{
		return !paused;
	}

	///////////////////////////////////////////
	// Create a color using web hex notation //
	///////////////////////////////////////////
	private Color rgb(final String hexValue)
	{
		return (new Color(Integer.parseInt(hexValue.substring(0, 2), 16),
		                  Integer.parseInt(hexValue.substring(2, 4), 16),
		                  Integer.parseInt(hexValue.substring(4   ), 16)));
	}

///////////////////////////////////////////////
// Break text into lines of width wrapLength //
///////////////////////////////////////////////
public static String wrap(final String s, final int wrapLength, final char lineSeparator)
{
StringBuffer sb = new StringBuffer(s);
int i = wrapLength;


		while (i<sb.length() && i>0)
		{
			if (Character.isWhitespace(sb.charAt(i)))
			{
				// If character is whitespace, replace it with a
				// lineSeparator and increment index i by wrapLength.
				sb.setCharAt(i, lineSeparator);
				i += wrapLength;
			}
			else
			{
				// Decrement index i by 1 to find the nearest space
				// to the left in the sentence at which to wrap.
				i--;
			}
		}

		return sb.toString();
	}

//////////
// main //
//////////
public static void main(final String[] args)
{
final Typewriter tw = new Typewriter();
final String msg = "Here's to the foolish/7crazy/ ones. The misfits. The rebels. The troublemakers. The round pegs in the hexagonal/9square/ holes. The ones who see things differently. They're not fond of rules. And they have no respect for the status quo. You can praise them, disagree with them, quote them, disbelieve them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They invent. They imagine. They heal. They explore. They create. They inspire. They push the human race forward. Maybe they have to be crazy. How else can you stare at an empty canvas and see a work of art? Or sit in silence and hear a song that's never been written? Or gaze at a red planet and see a laboratory on wheels? We make tools for these kinds of people. While some see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.";
tw.setTickerText(msg);


		final Button button;
		if (tw.isRunning())
			button = new Button("Stop");
		else
			button = new Button("Start");
		button.setBackground(Color.black);
		button.addActionListener
		(
			new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					if (tw.isRunning())
					{
						tw.stop();
//						tw.clear();
						button.setLabel("Start");
					}
					else
					{
						tw.start();
						button.setLabel("Stop");
					}
				}
			}
		);

		final Panel p = new Panel(new FlowLayout());
		p.setBackground(Color.black);
		p.add(tw);	p.add(button);

		final Frame f = new Frame("Ticker Demo");
		f.setSize(WIDTH, HEIGHT);
		f.addWindowListener
		(
			new WindowAdapter()
			{
            	public void windowClosing(WindowEvent we)
            	{
            		System.exit(0);
            	}
			}
		);
		f.add(p);
//		snooze(1000);
		f.setVisible(true);
	}

}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden


Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.