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

📄 popup.java

📁 蓝牙骰子游戏: 用J2ME开发的手机蓝牙骰子游戏
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// For Sony Ericsson Mobile Communications


package bluegammon.gui.popup;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

import bluegammon.Device;
import bluegammon.Resources;

/**
 * <p>
 * The <code>Popup</code> represents a popup with text and zero or many
 * alternatives that user can select among. A popup can be shown for a 
 * specific amount of time or forever, the latter case requiring a user to close
 * the popup. The choice of the alternatives can be reported by implementing
 * a <code>PopupListener</code>
 * </p><p>
 * This class contains all functionality of a popup, i.e. interaction,
 * graphics and callback.
 * </p>
 
 */
public class Popup implements Runnable
{
  /** Preset alternative containing OK */
  public static final char[][] ALT_OK;
  /** Preset alternative containing CANCEL */
  public static final char[][] ALT_CANCEL;
  /** Preset alternatives containing YES and NO */
  public static final char[][] ALT_YES_NO;
  /** Preset alternatives containing OK and CANCEL */
  public static final char[][] ALT_OK_CANCEL;
  /** Preset alternatives containing YES, NO, and CANCEL */
  public static final char[][] ALT_YES_NO_CANCEL;

  // Setup preset alternatives
  static
  {
    ALT_OK = new char[1][];
    ALT_OK[0] = Resources.getChars(Resources.TXT_OK);
    ALT_CANCEL = new char[1][];
    ALT_CANCEL[0] = Resources.getChars(Resources.TXT_CANCEL);
    ALT_YES_NO = new char[2][];
    ALT_YES_NO[0] = Resources.getChars(Resources.TXT_YES);
    ALT_YES_NO[1] = Resources.getChars(Resources.TXT_NO);
    ALT_OK_CANCEL = new char[2][];
    ALT_OK_CANCEL[0] = ALT_OK[0];
    ALT_OK_CANCEL[1] = ALT_CANCEL[0];
    ALT_YES_NO_CANCEL = new char[3][];
    ALT_YES_NO_CANCEL[0] = ALT_YES_NO[0];
    ALT_YES_NO_CANCEL[1] = ALT_YES_NO[1];
    ALT_YES_NO_CANCEL[2] = ALT_CANCEL[0];
  }

  /** The text to show in the popup */
  protected char[] m_text;
  /** Number of alternatives to select in popup */
  protected byte m_alternatives;
  /** Array of texts as chararrays in alternatives */
  protected char[][] m_altTexts;
  /** Time out in seconds */
  protected byte m_timeOut;
  /** Alternative reported back if timeout is reached */
  protected byte m_timeOutAlt;
  /** Current alternative index */
  protected byte m_curAlt;
  /** Listener to this popup */
  protected PopupListener m_listener;
  /** Flag indicating if popup is active */
  protected volatile boolean m_active = true;
  /** Width of popup */
  protected int m_w;
  /** Height of popup */
  protected int m_h;
  /**
   * Indices indicating where to break the text organized as [line][0 = start
   * char offset | 1 = char len]
   */
  protected int[][] m_breakTextData;
  /** Number of visible text lines in popup */
  protected int m_visibleLines;
  /** Current line offset */
  protected int m_curLine;
  /** Maximum line offset */
  protected int m_maxLine;
  /** Horizontal coordinate offset of text */
  protected int m_yoffset;
  /** The life time of this popup */
  protected long m_endTime;

  // Graphical data
  protected Font m_font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD,
      Font.SIZE_SMALL);
  protected int m_fontHeight = m_font.getHeight();
  protected int m_borderColor = 0xdd0000;
  protected int m_backgroundColor = 0xcc440000;
  protected int m_textColor = 0xffffff;
  protected int m_alternativeColor = 0xff2200;
  protected int m_selectedAlternativeColor = 0xffffff;
  protected static int[] m_rgbData;

  /**
   * Space between actual popup graphics and the rectangle reported in method
   * <code>init</code>
   */
  protected static final int OFFSET_POPUP = 8;
  /** Space between popup edges and text content */
  protected static final int OFFSET_TEXT = 2;
  /** Space between alternative texts */
  protected static final int OFFSET_ALT = 4;
  /** Scrollbar width */
  protected static final int SB_WIDTH = 5;
  /** Textbreak constants */
  protected static final char[] TEXTBREAKS =
    { ' ', '?', ';', ',', '.', '!',
      ':', '-', '=', '(', ')', '[', ']' };
  /** New line constant */
  protected static final char NEWLINE = '\n';

  /**
   * Creates an uninitialized popup. Call <code>init</code> to setup
   * this popup instance. This constructor is used for instance cache
   * functionality.
   */
  public Popup() {}

  /**
   * Initializes this popup.
   * 
   * @param text       The text to show in popup.
   * @param altTexts   The alternatives to select among or null if no choices.
   * @param timeOut    Time out for this popup in seconds (0 means no timeout).
   * @param defaultAlt Index of default alternative.
   * @param timeOutAlt Alternative index reported on time out.
   * @param listener   The popuplistener being reported on selection or timeout or null
   *                   if no listener.
   * @param width      Canvas width.
   * @param height     Canvas height.
   */
  public void init(char[] text, char[][] altTexts, byte timeOut,
      byte defaultAlt, byte timeOutAlt, PopupListener listener, int width,
      int height)
  {
    // Set parameters
    m_text = text;
    m_altTexts = altTexts;
    if (altTexts != null)
    {
      m_alternatives = (byte) altTexts.length;
    }
    else
    {
      m_alternatives = 0;
    }
    m_timeOut = timeOut;
    m_timeOutAlt = timeOutAlt;
    m_listener = listener;
    m_curAlt = defaultAlt;
    m_w = width - (OFFSET_POPUP << 1);
    m_h = height - (OFFSET_POPUP << 1);
    m_active = true;
    if (m_timeOut > 0)
    {
      // Set timeout
      m_endTime = System.currentTimeMillis() + (m_timeOut * 1000);
    }
    else if (m_alternatives > 0)
    {
      // No timeout
      m_endTime = 0;
    }
    else
    {
      // This should never happen - a popup with no alternatives and no timeout
      m_endTime = System.currentTimeMillis();
    }

    m_visibleLines =
      Math.max(1, ((m_h - (OFFSET_TEXT << 1)) / m_fontHeight) - 1);
    int w = m_w - (OFFSET_TEXT << 1) - (SB_WIDTH << 1);
    m_curLine = 0;

    m_breakTextData = breakString(text, w);

    // Calculate height
    m_yoffset = 0;
    m_maxLine = m_breakTextData.length - m_visibleLines + 1;
    if (m_breakTextData.length < m_visibleLines)
    {
      int newH = m_breakTextData.length * m_fontHeight;
      if (m_alternatives > 0)
        newH += m_fontHeight;
      newH += OFFSET_TEXT + OFFSET_ALT;
      m_yoffset = (m_h - newH) >> 1;
      m_h = newH;
    }

    // Create transparent rgb buffer if needed (8 lines)
    if (m_rgbData == null || m_rgbData.length != m_w * 8)
    {
      m_rgbData = new int[m_w * 8];
      for (int i = 0; i < m_rgbData.length; i++)
      {
        m_rgbData[i] = m_backgroundColor;
      }
    }

    // Start poll thread
    new Thread(this, "PopupPoll").start();
  }

  /**
   * Breaks specified character array and returns a break matrix by line,
   * organized as [line][0 | 1] where 0 means starting offset in text for this
   * line, 1 means number of characters of this line.
   * 
   * @param text  The string to break
   * @param width Width in pixels to break on
   * @return A break index table
   */
  protected int[][] breakString(char[] text, int width)
  {
    // Count text lines
    int offset = 0;
    int lines = 0;
    int newOffset;

    while (offset < text.length)
    {
      newOffset = 
        findNextBreak(text, offset, text.length - offset, width, m_font);
      offset = newOffset;
      lines++;
    }

    int[][] indices = new int[lines][2];

    // Setting offset data
    lines = 0;
    offset = 0;
    while (offset < text.length)
    {
      newOffset =
        findNextBreak(text, offset, text.length - offset, width, m_font);
      indices[lines][0] = offset;
      indices[lines][1] = newOffset - offset;
      lines++;
      offset = newOffset;
    }

    return indices;
  }

  /**
   * Returns next break when breaking a string.
   * 
   * @param text   The chars to calculate on
   * @param offset From what offset to read in chars
   * @param len    How many characters to read
   * @param w      Width
   * @param f      Font
   * @return Offset of next break or length of text if no more breaks
   */
  public int findNextBreak(char[] text, int offset, int len, int w, Font f)
  {
    int breakOffset = offset;
    int textW = 0;
    int niceB = -1;
    char c;
    charLoop: while (breakOffset <= offset + len && textW < w)
    {
      if (breakOffset == offset + len)
        c = TEXTBREAKS[0]; // last character + 1, fake break char

⌨️ 快捷键说明

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