Programming Java 2 Micro Edition for Symbian OS 2004 (779882), страница 48
Текст из файла (страница 48)
Users can move the current row selection up anddown using the joystick or jog wheel and select a row to ‘‘drill down’’and see detailed information about the expense item.THE EXPENSE APPLICATION255Figure 5.4 UIQ Implementation on Sony Ericsson P900.SelectorItemToolbarButton+setSelectorRange(in from : int, in to : int, in current : int)+setSelectorRange(in from : Date, in to : Date, in current : Date)+getCurrentMonth() : Date+getCurrentOrdinal() : int+setButtons(in buttonMask : int)+addToolbarListener()1*+paint(in width : int, in height : int)+isHit(in x : int, in y : int) : boolean+getId() : int10..1«interface»ToolbarListener+toolbarEvent(in buttonId : int)Figure 5.5 UIQ selection item class diagram.The list item allows columns to be dynamically added, removed andre-sized. In the more complex, UIQ version, column headers can betapped with the pen to change the sort order of the list.
As the number ofrows in the list grows so does the length of the list, until eventually it islonger than the screen. Under these circumstances the list item providesthe currently selected row’s bounding rectangle to the underlying formimplementation so that MIDP can scroll the item and ensure the row isalways visible on the screen (this is covered in detail later).256MIDP 2.0 CASE STUDIESThe Series 60 and UIQ implementations are different. The UIQ versionis more complex because it supports changes in the sort order of thelist.
Both versions of the item have the same three basic classes (seeFigure 5.6):• a midlet.uitools.ListItem class which implements the custom item• an abstract class midlet.uitools.ListModel which encapsulates the data that the list contains in a similar fashion to the JavaStandard Edition javax.swing.ListModel interface• a midlet.uitools.ListColumn class which represents individual columns and is responsible for painting the column header in thelist item.The UIQ version has an additional interface and class. The midlet.utils.Comparator interface provides a method that allows twoinstances of a class to be compared. It is used in conjunction with themidlet.utils.Sorter class, which sorts a Vector using a simplebubble sort algorithm.
Java 2 Standard Edition (J2SE) has numerous utilityclasses for sorting and comparing. Unfortunately, due to size constraints,these are not included in J2ME and developers must re-implement themas needed.5.2.4.2 ImplementationTo create a custom item you must derive a class from the abstractjavax.microedition.lcdui.CustomItem class.
The abstract methods that must be implemented fulfill the form’s most basic requirements:the dimensions of the custom item and how it should be painted.ListItemListColumn+setModel(in model : ListModel)+addColumn(in title : String, in width : int)+removeAllColumns()+getCurrentSelection() : int+setCurrentSelection(in selection : int)+paintHeader()+getWidth() : int+getHeight() : int+getTitle() : String+isHit() : boolean1*11ListModel+getRowCount() : int+getData(in row : int, in column : int) : StringFigure 5.6Class diagram for the list.THE EXPENSE APPLICATION257Item SizeThe custom item’s dimensions are handled by four methods, getMinContentWidth(), getMinContentHeight(), getPrefContentWidth() and getPrefContentHeight().
The form and basecustom item implementations use these methods when calculating thelayout of the form that surrounds the custom item.The selector and list custom items developed for the expense MIDlethave the minimum and preferred width set as the width of the display.The selector item has a fixed height that is set at design time and neverchanges. The list item must be of variable height to allow for differingnumbers of rows. Initially, the list has a small height that allows the listheader and up two rows to be shown. The preferred height is set to alarge value that allows the list to grow as required, eventually to severaltimes the screen length if needed.Item PaintingPainting of the item is handled in the paint() method.
It is passed ajavax.microedition.lcdui.Graphics object and the width andheight of the item’s area. The top right (0,0) of the paint area correspondsto the top right position of the item on the screen; the underlyingimplementation takes care of transforming the drawing commands to thecorrect location on the physical screen.If the custom item is larger than the physical screen size, the heightand width passed to paint() reflect the item size, not the screen size.When painting a custom item the simplest approach is to draw everythingwhenever paint() is called. This method is used for the items in theexpense application: neither has a sufficiently complex paint operationas to cause a noticeable flicker during painting.
Various techniquesexist to optimize painting by painting only the areas that have changed;discussion of these techniques is outside the scope of this chapter.The following code shows the paint() method of the Series 60selector item. The code has been pared down slightly by removingthe ordinal mode painting. The paint() method breaks down into aseries of simple operations. Firstly, the stage is set by painting the item’sbackground color white using the fillRect() method followed by adrawRect() call to draw a single line border around the item. Nextthe text that will be displayed is formatted and its size and x and yoffsets within the item calculated so that the text can be centrally aligned,horizontally and vertically. drawString is used to render the text.Finally, the item’s current selection is compared to the upper and lowerbounds of the item’s range to determine whether we need to paint the leftand right arrows using drawImage.// Series 60 Selector Custom Item paint() method.protected void paint(Graphics g, int width, int height) {258MIDP 2.0 CASE STUDIES// blank canvasint oldCol = g.getColor();g.setColor(0xffffff);// whiteg.fillRect(0, 0, width, height);// paint toolbar borderg.setColor(thisDisplay.getColor(Display.COLOR_BORDER));g.drawRect(0, 0, width - 1, height - 1);g.setColor(oldCol);// format display textint yr = currentSelection / 12;String selectText = months[currentSelection % 12] + " " +((yr < 10) ? "0" : "") + yr;// work out some draw metricsFont font = g.getFont();Display thisDisplay = ExpenseMIDlet.getInstance().getDisplay();int selectTextY = (height - font.getHeight()) / 2;int xOfs = (width - font.stringWidth(selectText)) / 2;g.drawString(selectText, xOfs, selectTextY,Graphics.TOP | Graphics.LEFT);// draw left / right arrows if neededif (currentSelection != selectFrom) {g.drawImage(leftSelect, SELECTOR_SPACER,((SELECTOR_HEIGHT - leftSelect.getHeight()) / 2),Graphics.TOP | Graphics.LEFT);}if (currentSelection != selectTo) {g.drawImage(rightSelect,width - SELECTOR_SPACER - rightSelect.getWidth(),((SELECTOR_HEIGHT - rightSelect.getHeight()) / 2),Graphics.TOP | Graphics.LEFT);}}The code for painting the list item is slightly more complex in that weneed to paint columns and rows and ensure that the current selection ishighlighted.
The list item has a list of columns and a model that representsthe data within the list. The painting of the column headers is delegatedto the individual column objects and a loop iterates through the modeland draws the individual rows.5.2.4.3 Event handlingOnce the basic custom item methods have been implemented, it istime to consider how the item will interact with the user.
Events aretriggered when the keypad, joystick or pen are used. How the events arehandled determines the nature of the interaction between the user andthe custom item.When discussing how to handle keypad events we must considertraversal. When there are several form items only one has the focus atTHE EXPENSE APPLICATION259any time; as the user navigates the form, different items gain and losethe focus. The developer does not have any code to write to make thishappen, the underlying form takes care of all the details. In MIDP this isknown as traversal: as users navigate around a form, they are traversingbetween form items.Some form items, such as javax.microedition.lcdui.TextField, support internal traversal.
While the item has focus, movingleft and right moves the cursor position within the text. It does not changethe focus to another form item. Internal traversal allows an item to specifya rectangle that should be currently visible on the screen: this is useful foritems such as the list item created for the expense application which maybecome longer than the physical screen. By specifying the rectangle ofthe current row, the underlying implementation will ensure that the itemis scrolled so that the current row is visible.Key events can be handled in two ways: the first uses traversal totrap the directional buttons by overriding the traverse() method; thesecond overrides the keyPressed(), keyReleased() and keyRepeated() methods.