📄 display.java
字号:
synchronized (LCDUILock) { newCurrent = pendingAlert; if (newCurrent == null) { newCurrent = nextScreen; } else if (alertDelay != Alert.FOREVER) { eventHandler.scheduleTimer(EventHandler.SCREEN, alertDelay); } // If the current screen is the same as the new incoming // screen we can simply return, but only if we are not in // a suspended state. If we are in a suspended state, we // want to interrupt and actually re-set the Display to // 'newCurrent', even though technically it is already // the 'current' Displayable of this Display if (current == newCurrent && !paintSuspended) { return; } } // synchronized registerNewCurrent(newCurrent, false); } } // timerEvent() /** * Change the foreground/background status of the Display * associated with this DisplayAccess instance. * * @param hasForeground true if the Display should be put in * the foreground. */ public void setForeground(boolean hasForeground) { eventHandler.setEventRecipient(this, hasForeground); if (hasForeground) { registerNewCurrent(current, true); } else { suspendPainting(); } } /** * Called from the event delivery loop when an input method * event is seen. * @param str input text string */ public void inputMethodEvent(String str) { TextBox textBoxCopy = null; synchronized (LCDUILock) { if (current instanceof TextBox) { textBoxCopy = (TextBox) current; } } // SYNC NOTE: TextBox.insert() does its own locking so we // move the call outside of our lock using a local variable if (textBoxCopy != null) { textBoxCopy.insert(str, textBoxCopy.getCaretPosition()); } } /** * get the flag indicating the most recently set * Displayable was non-null. * @return true, if most recent displayable was non-null. */ public boolean hasCurrent() { return hascurrent; } /** * get a hnadle to the current display * @return current Display handle. */ public Display getDisplay() { // return display; return Display.this; } /** local handle for current Display. */ // private Display display; // No events will be delivered while these are false // This is our attempt at avoiding spurious up events /** true, if a pointer press is in progress. */ boolean sawPointerPress; /** true, if a key press is in progress. */ boolean sawKeyPress; } // END DisplayAccessor Class /** true, if painting operations are suspended. */ private boolean paintSuspended = false; /** true, if the Display is the foreground object. */ private boolean hasForeground = false; /** * <p> Causes the Runnable object <code>r</code> to have its run() method * called later, serialized with the event stream, soon after completion of * the repaint cycle. As noted in section on * <a href="Canvas.html#eventdelivery">event delivery</a> in the Canvas * class, * the methods that deliver event notifications to the current canvas * are all called serially. The call to r.run() will be * serialized along with * the event calls on the current canvas. The run() method will be called * exactly once for each call to callSerially(). Calls to * run() will occur in * the order in which they were requested by calls to callSerially(). * </p> * * <p> If there is a repaint pending at the time of a call to * callSerially(), the current Canvas's paint() method will be called and * will return, and a buffer switch will occur (if double buffering is in * effect), before the Runnable's run() method is called. Calls to the * run() method will occur in a timely fashion, but they are not guaranteed * to occur immediately after the repaint cycle finishes, or even before * the next event is delivered. </p> * * <p> The callSerially() method may be called from any thread. The call to * the run() method will occur independently of the call to callSerially(). * In particular, callSerially() will <em>never</em> block * waiting for r.run() * to return. </p> * * <p> As with other callbacks, the call to r.run() must return quickly. If * it is necessary to perform a long-running operation, it may be initiated * from within the run() method. The operation itself should be performed * within another thread, allowing run() to return. </p> * * <p> The callSerially() facility may be used by applications to run an * animation that is properly synchronized with the repaint cycle. A * typical application will set up a frame to be displayed and then call * repaint(). The application must then wait until the frame is actually * displayed, after which the setup for the next frame may occur. The call * to run() notifies the application that the previous frame has finished * painting. The example below shows callSerially() being used for this * purpose. </p> * * <pre> * class Animation extends Canvas implements Runnable { * * void paint(Graphics g) { ... } // paint the current frame * * void startAnimation() { * // set up initial frame * repaint(); * callSerially(this); * } * * void run() { // called after previous repaint is finished * if ( /* there are more frames */ ) { * // set up the next frame * repaint(); * callSerially(this); * } * } * } * </pre> * * @param r instance of interface Runnable to be called */ public void callSerially(Runnable r) { if (r == null) { throw new NullPointerException(); } synchronized (LCDUILock) { currentQueue.addElement(r); eventHandler.scheduleTimer(EventHandler.CALLED_SERIALLY, 0); } } /** first queue of serialized repaint operations. */ private static java.util.Vector queue1 = new java.util.Vector(); /** second queue of serialized repaint operations. */ private static java.util.Vector queue2 = new java.util.Vector(); /** current active queue for serially repainted operations. */ private static java.util.Vector currentQueue = queue1; /** * run the serially repainted operations. */ private void getCallSerially() { java.util.Vector q = null; synchronized (LCDUILock) { q = currentQueue; currentQueue = (q == queue1) ? queue2 : queue1; } synchronized (calloutLock) { for (int i = 0; i < q.size(); i++) { try { Runnable r = (Runnable) q.elementAt(i); r.run(); } catch (Throwable thr) { handleThrowable(thr); } } } q.removeAllElements(); } /** * Registers a new Displayable object to this Display. This means that * it is now the current Displayable object, eligible to receive input * events, and eligible to paint. If necessary, showNotify() is called * on this Displayable and hideNotify() is called on the Displayable * being replaced. This method is used to initialize a Displayable as * a result of either: * - a SCREEN change timerEvent() * - a call to resumePainting() * - a change in foreground status of this Display (results in a call * to resumePainting()) * * @param newCurrent The Displayable to take effect as the new * "current" Displayable * @param fgChange If True, then this call to registerNewCurrent() is a * result of this Display being moved to the foreground, * i.e. setForeground(true) */ private void registerNewCurrent(Displayable newCurrent, boolean fgChange) { Displayable currentCopy = null; // SYNC NOTE: The implementation of Displayable.showNotify() // will use LCDUILock to lock around the internal call to // showNotifyImpl() and will then release LCDUILock and // obtain calloutLock around the call (potentially) into // the application's showNotify() method. if (newCurrent != null) { newCurrent.showNotify(Display.this); } synchronized (LCDUILock) { // We've avoided re-setting the pending alert so we // do it now if necessary if (newCurrent == pendingAlert) { pendingAlert = null; } if (fgChange) { hasForeground = true; if (nextScreen != null || pendingAlert != null) { eventHandler.scheduleTimer(EventHandler.SCREEN, 0); } // On the very first setForeground() call, newCurrent // will be null. We can shortcircuit the rest of the // call and simply return. if (newCurrent == null) { return; } } // This will suppress drags, repeats and ups until a // corresponding down is seen. accessor.sawPointerPress = accessor.sawKeyPress = false; // We re-set our suspended state to false. paintSuspended = false; // We make a copy of the current Displayable to call // hideNotify() when we're done currentCopy = current; current = newCurrent; updatePending = false; // we're holding the lock, so the actual painting won't // happen until later. repaintImpl(current, 0, 0, WIDTH, HEIGHT, 0); setVerticalScroll( current.getVerticalScrollPosition(), current.getVerticalScrollProportion()); setHorizontalScroll( current.getHorizontalScrollPosition(), current.getHorizontalScrollProportion()); // Next, update the command set eventHandler.updateCommandSet(current.getCommands(), current.getCommandCount()); TextBox.imHandler.setFocus(current instanceof TextBox); if (current instanceof Alert) { AlertType at = ((Alert)current).getType(); if (at != null) { playAlertSound(at.getType()); } } } // synchronized // SYNC NOTE: The implementation of Displayable.hideNotify() // will use LCDUILock to lock around the internal call to // hideNotifyImpl() and will then release LCDUILock and // obtain calloutLock around the call (potentially) into // the application's hideNotify() method. // NOTE: the reason we test for currentCopy != current is // for cases when the Display has interrupted its suspension // by a system screen to immediately return to its "current" // Displayable. In this case, currentCopy == current, and // we've just called showNotify() above (no need to call // hideNotify()) if (currentCopy != null && currentCopy != current) { currentCopy.hideNotify(Display.this); } } // registerNewCurrent()}/** * Current device capabilities. */class DeviceCaps { /** horizontal width of the current device */ int width; /** vertical height of the current device */ int height; /** color to use when erasing pixels in the device. */ int eraseColor; /** depth of the display, e.g. 8 is full color */ int displayDepth; /** true, if the device supports color */ boolean displayIsColor; /** true, if the device supports a pointing device. */ boolean pointerSupported; /** true, if the device supports motion events. */ boolean motionSupported; /** true, if the device supported repeated events. */ boolean repeatSupported; /** true, if the device supports double buffering. */ boolean isDoubleBuffered; /** initialize the device capabilities. */ DeviceCaps() { init(); } /** * native method to retreive initial settings for * display capabilities */ private native void init();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -