📄 logcanvas.java
字号:
* Sets given line at specified position. * * @param i * position of line to set. * @param line * line to set. */ private void setLine(int i, char[] line) { this.page[getLinePos(i)] = line; } /** * Returns position of EOL of line at specified position. * * @param i * position of line, EOL offset of which to return. * @return position of EOL of line. */ private int getEOL(int i) { return this.eols[getLinePos(i)]; } /** * Sets position of EOL of line at specified position. * * @param i * position of line, EOL offset of which to set. * @param eol * EOL offset to set. */ private void setEOL(int i, int eol) { this.eols[getLinePos(i)] = eol; } /** * Retruns line's offset in array * * @param pos * position of line. * @return line's offset in array */ private int getLinePos(int pos) { pos += this.shift; if (pos > this.lpp) pos -= this.lpp + 1; if (pos < 0) pos += this.lpp + 1; return pos; } /** * Scrolls screen one line down. */ protected void nextLine() { if (this.needScrollBar && getEOL(this.lpp - 1) < this.text.length()) { this.vStart = getEOL(0); this.shift++; if (this.shift > this.lpp) this.shift = 0; this.lines--; grabNextLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Scrolls screen one page (all fully visible on page lines except two) down. */ protected void nextPage() { if (this.needScrollBar && getEOL(this.lpp - 1) < this.text.length()) { this.vStart = getEOL(this.lpp - 3); this.shift += this.lpp - 2; if (this.shift > this.lpp) this.shift -= this.lpp + 1; this.lines = 3; grabNextLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Scrolls logging screen one line up. */ protected void prevLine() { if (this.needScrollBar && this.vStart > 0) { if (this.lines > this.lpp) this.lines--; grabPrevLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Scrolls logging screen to top. */ protected void topLine() { if (this.needScrollBar && this.vStart > 0) { this.vStart = this.lines = this.shift = 0; grabNextLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Scrolls logging screen to bottom. */ protected void bottomLine() { int textLength = this.text.length(); if (this.needScrollBar && getEOL(this.lpp - 1) < textLength) { this.lines = this.shift = 0; this.vStart = textLength; grabNextLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Scrolls one page (all visible on page lines except two) up. */ protected void prevPage() { if (this.vStart > 0) { this.lines = 3; grabPrevLines(); show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } } /** * Renders scrollbar on buffer. */ protected void showScrollBar() { Graphics g = graphics(); g.setColor(this.scrollBarColor); g.fillRect(this.textWidthView, 0, 3, this.height); int end = getEOL(this.lpp - 1); int sStart = this.height * this.vStart / this.text.length(); int sLength = this.height * (end - this.vStart) / this.text.length() + 1; if (sLength < 5) { sLength = 5; int d = sStart + sLength - this.height; if (d > 0) sStart -= d; } if (this.vStart == 0 || end == this.text.length()) g.setColor(this.scrollBarCursorEdgeColor); else g.setColor(this.scrollBarCursorColor); g.fillRect(this.textWidthView, sStart, 3, sLength); } /** * Renders view on buffer. */ void show() { Graphics g = graphics(); g.setColor(this.bgColor); g.fillRect(0, 0, this.textWidthView, this.height); g.setColor(this.fgColor); g.setFont(this.font); int curY = 0; for (int i = 0; i < this.lines; curY += this.fontHeight, i++) { char[] line = getLine(i); g.drawChars(line, 2, line[1], 0, curY, TOP_LEFT); } } /** * Initializes logging screen. */ private void initTextView() { this.textWidthView = this.width; this.lines = this.shift = 0; grabNextLines(); this.needScrollBar = this.lines > this.lpp || this.vStart > 0; if (this.needScrollBar) { this.textWidthView -= 3; this.lines = this.shift = 0; grabNextLines(); } show(); if (this.needScrollBar) showScrollBar(); flushGraphics(); repaint(); } /** * Caches next possible not accessed lines. * * @return {@code true} if some lines were cached, {@code false} otherwise. */ private boolean grabNextLines() { boolean res = false; int textLength = this.text.length(); for (int end = this.lines > 0 ? getEOL(this.lines - 1) : this.vStart; end < textLength && this.lines <= this.lpp; this.lines++) { res = true; end = grabNextLine(end, this.lines); } for (; this.vStart > 0 && this.lines < this.lpp; this.lines++) { this.shift--; if (this.shift < 0) this.shift = this.lpp; res = true; this.vStart = grabPrevLine(this.vStart, 0); } return res; } /** * Caches previous possible not accessed lines. * * @return {@code true} if some lines were cached, {@code false} otherwise. */ private boolean grabPrevLines() { boolean res = false; for (; this.vStart > 0 && this.lines <= this.lpp; this.lines++) { this.shift--; if (this.shift < 0) this.shift = this.lpp; res = true; this.vStart = grabPrevLine(this.vStart, 0); } for (int end = getEOL(this.lines - 1); end < this.text.length() && this.lines <= this.lpp; this.lines++) { res = true; end = grabNextLine(end, this.lines); } return res; } /** * Caches next line at specified position starting from specified offset. * * @param start * offset to start grabbing from. * @param linePos * position of line to cache to. * @return offset of next line. */ private int grabNextLine(int start, int linePos) { char c = 0; int l = 2; char[] line = getLine(linePos); int lineSize = line[0] + 2; for (int w = 0; start < this.text.length() && (c = this.text.charAt(start)) != '\n' && (w += this.font.charWidth(c)) <= this.textWidthView; start++) { if (l == lineSize) { int newSize = lineSize * 2; char[] newLine = new char[newSize]; System.arraycopy(line, 1, newLine, 1, lineSize - 1); setLine(linePos, line = newLine); line[0] = (char) ((lineSize = newSize) - 2); } line[l++] = c; } line[1] = (char) (l - 2); if (c == '\n') start++; setEOL(linePos, start); return start; } /** * Caches previous line at specified position starting from specified offset. * * @param start * offset to start grabbing from. * @param linePos * position of line to cache to. * @return offset of previous line. */ private int grabPrevLine(int start, int linePos) { if (start > 0) { char[] line = getLine(linePos); setEOL(linePos, start); int lineSize = line[0]; int l = lineSize + 1; char c = this.text.charAt(--start); if (c == '\n') start--; for (int w = 0; start >= 0 && (c = this.text.charAt(start)) != '\n' && (w += this.font.charWidth(c)) <= this.textWidthView; start--) { if (l == 1) { int newSize = (lineSize + 2) * 2; char[] newLine = new char[newSize]; l = newSize - lineSize - 1; System.arraycopy(line, 2, newLine, l + 1, lineSize); setLine(linePos, line = newLine); line[0] = (char) (lineSize = newSize - 2); } line[l--] = c; } int ll = lineSize - (++l) + 2; System.arraycopy(line, l, line, 2, ll); line[1] = (char) ll; start++; } return start; } /** * Formats given logging event by configured {@link Formatter} and appends it * to the buffer. Sends command to refresh it's view. * * @see momelog.LogListener#onLog(momelog.LogEvent) */ public void onLog(LogEvent event) { Formatter formatter = Logger.getFormatter(); formatter.format(event, this.text); this.text.append('\n'); pushCommand(APPEND_LOG); } /* * (non-Javadoc) * * @see javax.microedition.lcdui.Canvas#keyPressed(int) */ protected void keyPressed(int keyCode) { switch (keyCode) { case RESET_KEY: pushCommand(RESET); break; case TOGGLE_FULLSCREEN_KEY: pushCommand(TOGGLE_FULLSCREEN); break; case TOP_LINE_KEY: pushCommand(TOP_LINE); break; case BOTTOM_LINE_KEY: pushCommand(BOTTOM_LINE); break; default: keyRepeated(keyCode); } } /* * (non-Javadoc) * * @see javax.microedition.lcdui.Canvas#keyRepeated(int) */ protected void keyRepeated(int keyCode) { switch (getGameAction(keyCode)) { case NEXT_LINE_KEY: pushCommand(NEXT_LINE); break; case PREV_LINE_KEY: pushCommand(PREV_LINE); break; case NEXT_PAGE_KEY: pushCommand(NEXT_PAGE); break; case PREV_PAGE_KEY: pushCommand(PREV_PAGE); break; } } /** * Pushes command to the commands execution thread. * * @param cmd * An object identifying the command. * @since 1.0 */ void pushCommand(Object cmd) { synchronized (this.executorLock) { this.cmds.addElement(cmd); this.executorLock.notifyAll(); } } /** * Pops command from queue. * * @return - The first Command in the execution queue if there is one, * {@code null} otherwise. * @since 1.0 */ private Object popCommand() { Object res = null; synchronized (this.executorLock) { while (this.runner != null && res == null) { if (this.cmds.size() > 0) { res = this.cmds.firstElement(); this.cmds.removeElementAt(0); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -