📄 historycanvas.java
字号:
/* I BlueTooth You -- Simple BlueTooth talker Copyright (C) 2007 Jan Tomka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */package net.sf.btw.ibtu.ui;import java.util.Hashtable;import java.util.Vector;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Command;import javax.microedition.lcdui.CommandListener;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Font;import javax.microedition.lcdui.TextBox;import javax.microedition.lcdui.TextField;import net.sf.btw.btlib.Peer;import net.sf.btw.ibtu.Ibtu;import net.sf.btw.ibtu.Message;/** * <p> * HistoryCanvas is a scrollable canvas displaying list of strings wrapped to * muliple lines as needed. * </p> * * <p> * The only action supported is appending a new string. * </p> * * <p> * Vertical scrollbar is by default snapped to the bottom of canvas, showing the * newest strings as they are appended. * </p> * * @author Jan Tomka * * TODO Move Exit command (alert) here and clean messages vector on exit. */public class HistoryCanvas extends Canvas implements CommandListener { /** * <p> * Number of the topmost line currently visible. This number is reflected by * the position of the scrollbar thumb. * </p> * * <p> * Initial position within an empty history canvas is always 0 and changes * with scrolling the canvas. * </p> */ private int curPos = 0; /** * The last line is currently visible. Initial value is <code>true</code>, * meaning the canvas keeps displaying the most recently appended lines. * This may change with scrolling the canvas, but gets always reset to * <code>true</code> if the last line is visible again. */ private boolean atEnd = true; /** * Font used to draw individual lines in the history canvas. This is always * initialized to the device's default font. TODO Try small font. */ private final static Font font = Font.getDefaultFont(); /** * <p> * Vertical scrollbar. It is notified about the history canvas properties, * such as visible length, actual length and current position. * </p> * * <p> * Scrollbar visually represents the current position within the history. * For more information on scrollbar implementation, see {@link Scrollbar}. * </p> */ private Scrollbar scrollbar; /** * The history canvas background color. TODO Try color other than white * (e.g. very light yellow, or green). */ private final int backgroundColor = 0xffffff; /** * Color values to be used to visually distinguish individual message * senders. TODO Bind color to device address instead of its given name. We * may still run out of colors (!!!) as some devices disconnect and others * join. */ private final int senderColors[] = { 0xff0000, 0x00ff00, 0x0000ff, 0x808000, 0x800080, 0x008080, 0x800000, 0x008000 }; /** * Color used to draw the system message text. */ private final int systemMessageColor = 0x808080; /** * Color used to draw the message body text. */ private final int messageBodyColor = 0x000000; /** * Line's left offset. Number of pixels the history strings are indented * from the left canvas border. */ private final static int leftOffset = 2; /** * Line's right offset. Number of pixels from the scrollbar's right border, * the history strings are wrapped to the following line. */ private final static int rightOffset = 2; /** * Hash table associating the existing message senders with color assigned * for each. */ private final Hashtable colorHash = new Hashtable(); /** * List of messages in history. Callee should not modify this vector. TODO * Hide and create getter (append() is the only allowed setter). */ public final Vector messages = new Vector(); /** * Scrollbar notifier. Notifies scrollbar about current canvas state. */ private IScrollNotifier scrollNotifier; /** * Text box for user to enter a new message to be sent. TODO Move to * HistoryCanvas class (or remove altogether). */ private TextBox inputBox; /** * User sending New in history canvas. TODO Move to HistoryCanvas class. */ final Command commandNew = new Command("Say", Command.SCREEN, 1); /** * User sending Exit in history canvas. */ final Command commandExit = new Command("Quit", Command.BACK, 1); /** * User sending Exit in exit alert. */ final Command commandExitSure = new Command("Sure", Command.OK, 1); /** * User sending Cancel in exit alert. */ final Command commandExitCancel = new Command("Cancel", Command.CANCEL, 1); /** * User sending Cancel in input box. */ final Command inputBoxCommandCancel = new Command("Back", Command.BACK, 1); /** * User sending Send in input box. */ final Command inputBoxCommandSend = new Command("OK", Command.OK, 1); /** * */ final Ibtu ibtu; /** * Constructs a new, empty HistoryCanvas object. Creates an empty line * vector and a vertical scrollbar occupying the entire left border of a * canvas. */ public HistoryCanvas(Ibtu ibtu) { super(); this.ibtu = ibtu; scrollbar = new Scrollbar(getWidth() - 8, 3, 5, getHeight() - 6); scrollNotifier = new HistoryCanvasScrollNotifier(); scrollbar.setIScrollNotifier(scrollNotifier); inputBox = new TextBox("New message", "", 160, TextField.ANY); inputBox.addCommand(inputBoxCommandSend); inputBox.addCommand(inputBoxCommandCancel); inputBox.setCommandListener(this); setHistoryCommandsNormal(); setCommandListener(this); } private void setHistoryCommandsExit() { removeCommand(commandExit); removeCommand(commandNew); addCommand(commandExitSure); addCommand(commandExitCancel); } private void setHistoryCommandsNormal() { removeCommand(commandExitSure); removeCommand(commandExitCancel); addCommand(commandExit); addCommand(commandNew); } /** * Calculates number of text lines drawed using default font. The result is * actually a canvas height divided by the font height. * * @return Number of lines that fit on a device screen. */ public int getLinesPerScreen() { return getHeight() / font.getHeight(); } /** * Normalizes current position value. According to current canvas state, * following rules are applied: * <ol> * <li>if pos is less than zero, set it to zero</li> * <li>if total number of lines is greater than number of lines that fit on * screen and pos is greater than the number of the first line on the last * screen, set it to number of that first line</li> * <li>otherwise leave pos untouched</li> * </ol> * * @param pos * Line number to normalize, usually {@link HistoryCanvas#curPos}. * @return Normalized line number. * * TODO Replace with standard getter. */ private int normalizeCurPos(int pos) { int visLines = getLinesPerScreen(); int size = scrollNotifier.getActualLength(); if (pos < 0 || size <= visLines) pos = 0; else if (size > visLines && pos > (size - visLines)) pos = size - visLines; return pos; } /** * Splits string to multiple lines to make each fit on a line of its own, * when drawn with {@link #font}. * * @param s * String to be split to lines. * @param firstOffset * Left side offset of a first line (usually occupied by colored * sender name). * @return Vector of Strings containing the lines of the original string. * TODO Move to Message class. */ private Vector splitLines(String s, int firstOffset) { Vector splitLines = new Vector();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -