📄 displayable.java
字号:
* can occur as a result of the addition, removal, or changed contents of * any of these display features. * * <p> This method is called at least once before the * <code>Displayable</code> is shown for the first time. * If the size of a <code>Displayable</code> changes while * it is visible, * <CODE>sizeChanged</CODE> will be called. If the size of a * <code>Displayable</code> * changes while it is <em>not</em> visible, calls to * <CODE>sizeChanged</CODE> may be deferred. If the size had changed * while the <code>Displayable</code> was not visible, * <CODE>sizeChanged</CODE> will be * called at least once at the time the * <code>Displayable</code> becomes visible once * again.</p> * * <p>The default implementation of this method in <code>Displayable</code> * and its * subclasses defined in this specification must be empty. * This method is intended solely for being overridden by the * application. This method is defined on <code>Displayable</code> * even though applications are prohibited from creating * direct subclasses of <code>Displayable</code>. * It is defined here so that applications can override it in * subclasses of <code>Canvas</code> and <code>Form</code>. * This is useful for <code>Canvas</code> subclasses to tailor * their graphics and for <code>Forms</code> to modify * <code>Item</code> sizes and layout * directives in order to fit their contents within the the available * display area.</p> * * @param w the new width in pixels of the available area * @param h the new height in pixels of the available area * @since MIDP 2.0 */ protected void sizeChanged(int w, int h) { // this method is intended to be overridden by the application }// ************************************************************// package private methods// ************************************************************ /** * Called to commit any pending user interaction */ void commitPendingInteraction() { } /** * Called to schedule an "invalidate" for this Displayable. Invalidation * is caused by things like size changes, content changes, or spontaneous * traversal within the Item * * @param src The Item who is causing the invalidation. If NULL, * all contents should be considered invalid. */ void invalidate(Item src) { Display d = currentDisplay; if (d != null) { d.invalidate(src); } } /** * Called by the event handler to perform an * invalidation of this Displayable * * @param src The Item who is causing the invalidation. If NULL, * all contents should be considered invalid. */ void callInvalidate(Item src) { } /** * Called to schedule a call to itemStateChanged() due to * a change in the given Item. * * @param src the Item which has changed */ void itemStateChanged(Item src) { Display d = currentDisplay; if (d != null) { d.itemStateChanged(src); } } /** * Called by the event handler to notify any ItemStateListener * of a change in the given Item * * @param src The Item which has changed */ void callItemStateChanged(Item src) { } /** * Set the ticker for this Displayable * * @param t the ticker to set */ void setTickerImpl(Ticker t) { // Return early if there's nothing to do if (this.ticker == t) { return; } Ticker oldTicker = this.ticker; this.ticker = t; // CASES: // 1. Had an invisible non-null ticker, setting a null ticker // - We need to set the new ticker. There's no need to re-layout // or start the new ticker // 2. Had an invisible non-null ticker, setting a non-null ticker // - We need to set the new ticker. There's no need to re-layout // or start the new ticker // 3. Had a visible non-null ticker, setting a null ticker // - We need to set the new ticker and re-layout. There's no // need to start the new ticker. // 4. Had a null ticker, setting a visible non-null ticker // - We need to set the new ticker, re-layout, and // start up the new ticker // 5. Had a visible non-null ticker, setting a non-null ticker // - We need to set the new ticker. There's no need to re-layout boolean sizeChange = ((oldTicker != null) && (ticker == null)) || ((oldTicker == null) && (ticker != null)); if (sizeChange) { if (ticker != null) { ticker.reset(); startTicker(); } else { stopTicker(); } layout(); callSizeChanged(viewport[WIDTH], viewport[HEIGHT]); callRepaint(); } else { ticker.reset(); } } /** * Package private unsynchronized version of setTitle(String) * * @param s Title to set on this Displayable. */ void setTitleImpl(String s) { if (title == s || (title != null && title.equals(s))) { return; } String oldTitle = this.title; this.title = s; if (fullScreenMode) { return; } boolean sizeChange = ((oldTitle != null) && (title == null)) || ((oldTitle == null) && (title != null)); if (sizeChange) { layout(); callSizeChanged(viewport[WIDTH], viewport[HEIGHT]); callRepaint(); } else { repaintTitle(); } } /** * Package private equivalent of sizeChanged() * * @param w the new width * @param h the new height * */ void callSizeChanged(int w, int h) { // If there is no Display, or if this Displayable is not // currently visible, we simply record the fact that the // size has changed sizeChangeOccurred = (currentDisplay == null) || (!currentDisplay.isShown(this)); } /** * Display calls this method on it's current Displayable. * Displayable uses this oppportunity to do necessary stuff * on the Graphics context, this includes, * paint Ticker, paint Title, translate as necessary. * * <p>The target Object of this repaint may be some Object * initially set by this Displayable when the repaint was * requested - allowing this Displayable to know exactly * which Object it needs to call to service this repaint, * rather than potentially querying all of its Objects to * determine the one(s) which need painting. * * SYNC NOTE: The caller of this method handles synchronization. * * @param g the graphics context to paint into. * @param target the target Object of this repaint */ void callPaint(Graphics g, Object target) { /* System.err.println("Displayable:Clip: " + g.getClipX() + "," + g.getClipY() + "," + g.getClipWidth() + "," + g.getClipHeight()); */ synchronized (Display.LCDUILock) { if (!(fullScreenMode || (title == null && ticker == null))) { if (g.getClipY() < totalHeight) { // We always paint "something" for the ticker, rather // than make the title paint more complicated. If there // is no ticker, we draw the darkgray/white saparator line if (g.getClipY() < tickerHeight) { paintTicker(g); } if (title != null) { if (g.getClipY() + g.getClipHeight() > totalHeight - tickerHeight + 1) { g.translate(0, tickerHeight); paintTitle(g); g.translate(0, -tickerHeight); } } } } else { g.setColor(Item.DARK_GRAY_COLOR); g.drawLine(0, 0, Display.WIDTH, 0); g.setColor(Display.FG_COLOR); } } // synchronized } /** * Paint the ticker if it exists, on this graphics object. * * @param g The Graphics object to paint this ticker on. */ void paintTicker(Graphics g) { // paint the ticker here. if (ticker != null) { ticker.paintContent(g); } else if (title != null) { g.setColor(Item.DARK_GRAY_COLOR); g.drawLine(0, 0, Display.WIDTH, 0); g.setColor(Display.ERASE_COLOR); g.drawLine(0, 1, Display.WIDTH, 1); g.setColor(Display.FG_COLOR); } } /** * Paints the title of this Displayable, including it's border. * The graphics context is then translated by the height occupied * by the title area. * * @param g The graphics object to paint this title on. * */ void paintTitle(Graphics g) { g.setColor(Item.LIGHT_GRAY_COLOR); g.fillRect(0, 0, Display.WIDTH, TITLE_HEIGHT - 1); g.setColor(Display.FG_COLOR); Text.paint(title, TITLE_FONT, g, Display.WIDTH, TITLE_HEIGHT, 1, Text.NORMAL, null); g.setColor(Item.DARK_GRAY_COLOR); g.drawLine(0, TITLE_HEIGHT - 1, Display.WIDTH, TITLE_HEIGHT - 1); g.setColor(Display.FG_COLOR); } /** * Perform any necessary layout, and update the viewport * as necessary */ void layout() { setupViewport(); translateViewport(); } /** * Set the full screen mode of this Displayable. If true, * this Displayable will take up as much screen real estate * as possible * * @param onOff true if full screen mode should be turned on */ void fullScreenMode(boolean onOff) { if (fullScreenMode == onOff) { return; } fullScreenMode = onOff; layout(); updateCommandSet(); callSizeChanged(viewport[WIDTH], viewport[HEIGHT]); callRepaint(); if (fullScreenMode) { stopTicker(); } else { startTicker(); } } /** * By default, the viewport array is configured to be * at origin 0,0 with width Display.WIDTH and height * either Display.HEIGHT or Display.ADORNEDHEIGHT, depending * on full screen mode. */ private void setupViewport() { // setup the default viewport, the size of the Display if (viewport == null) { viewport = new int[4]; } viewport[X] = viewport[Y] = 0; viewport[WIDTH] = Display.WIDTH; viewport[HEIGHT] = (fullScreenMode) ? Display.HEIGHT : Display.ADORNEDHEIGHT; } /** * Translate the viewport for any decorations by this Displayable * such as a title or ticker */ private void translateViewport() { if (!(fullScreenMode || (title == null && ticker == null))) { // // determine the right tickerHeight // if (ticker != null) { tickerHeight = Ticker.PREFERRED_HEIGHT; } else { if (title != null) { tickerHeight = 2; } else { tickerHeight = 0; } } // // add to any title height // totalHeight = (title != null) ? TITLE_HEIGHT + tickerHeight : tickerHeight; } else { // // in fullscreen, or with no title or ticker we have // a single dark line under the status bar // totalHeight = 1; } viewport[Y] += totalHeight; viewport[HEIGHT] -= totalHeight; } /** * Handle a key press * * @param keyCode The key that was pressed */ void callKeyPressed(int keyCode) { }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -