Form
是包含任意
Item
组合的
Screen
:
image
、只读的
text field
、可编辑的
text field
、可编辑的
data field
、
gauge
、
choice group
和
custom item
。通常来说,一个
form
可以包任意一个
item
的子类。系统负责处理布局、横向和纵向的滚动。
Form
的所有组件在滚动时作为一个整体。
Item
管理
可以向一个
Form
里添加、删除和插入
item
。
Form
中的
itme
通过从
0
到
size()-1
的连续整数来索引,
0
是第一个
item
的索引,
size()-1
是最后一个。
任何
item
只能放在一个
Form
里。如果应用程序试图把一个已经属于另一人
Form
的
Item
放到一个新的
Form
里,将会抛出一个
IllegalStateException
的异常。应用程序必须在把
item
放入新的
Form
前把它从当前的
Form
里移除。
如果应用程序要求改变一个
Form
的组件时该
Form
是屏幕可见的,对屏幕的更新会在系统可行的时候立即执行。
布局
Form
里的布局规则是按行来组织的。行同
screen
的宽度、相对的空白边框、滚动轴特别相关。一个特定的
Form
中的所有行都有相同的宽度。行宽的该行包含的
item
无关,虽然它们可能在某些情况下改变所有的行宽,比如添加或是删除一个滚动轴的时候。
Form
通过不会水平滚动。
Form
的增长是垂直的,所以滚动也是垂直的。
Form
的高度取决于包含的行数和每一行的高度。每一行的高度由列于该行的
item
的高度来决定。行高不一定要都相同。系统可能会通过行高来对
item
标签提供适当的填充和垂直布局。
系统根据使用的语言习惯选择是从左到右还是从右到左来排列
item
。一个
Form
中的所有行的排列方向都应该相同。
在布局算法开始之前,
Form
被认为不含任何行。布局算法一个接一个的处理每一个
item
,从第
0
个
item
开始直到
form
中的最后一个
item
。如果排列方向为从左到右,行的开始端在
Form
的左边。如果排列方向为从右到左,行的开始端在
Form
的右边。
Item
从每一个的开始处排起,按选定的排列方向排列每一行,把尽可能多的
item
放入同一行中,除非提前换行的情况发生。新行这时候被添加,
itme
按上面的方法继续放入该行中。
Item
被放到每一行,只要有必要就添加新行直到所有
item
都被布局算法处理完毕。
布局算法里有一个
current alignment
的概念。它可以是
LAYOUT_LEFT
、
LAYOUT_CENTER
和
LAYOUT_RIGHT
三个值中的一个。布局算法开始时
current alignment
有值由这个
Form
的排列方向来决定。如果排列方向是从左到右,那么初始的
alignment
值必须是
LAYOUT_LEFT
。如果排列方向是从右到左,那么初始的
alignment
值必须是
LAYOUT_RIGHT
。
Current alignment
的值会在布局算法遇到一个含有
LAYOUT_LEFT
、
LAYOUT_CENTER
和
LAYOUT_RIGHT
中一个值的
itme
时改变。如果
item
中没有任何一个值,当前的值就不会改变。这个规则使得
Form
里按顺序连续的
item
拥有相同的
alignment
值。每个
item
的
alignment
值是由
Form
内部管理,并不会对由
Item.getLayout
方法返回的
layout
值有影响。
布局算法通常试图把一个
item
和它前一个
item
排列在同一行,除非遇到换行的情况。当需要换行时,当前的
item
会被放在下一行的开始而不是前一个
item
的后面,即使该行仍有空间。
下面情况之一发生时将在一个
item
前面换行:
前一个
item
后面一个换行符
该
item
拥有
LAYOUT_NEWLINE_BEFORE
字段
是一个以
”/n”
开头的字符串
是一个
LAYOUT_2
字段未设置的
ChoiceGroup
、
DateField
、
Gauge
或
TextField
该
item
包含
LAYOUT_LEFT
、
LAYOUT_CENTER
或
LAYOUT_RIGHT
这些值并和
Form
的
current alignment
不同
下面的情况之一发生时,将在一个
item
之后发生换行
是一个以
”/n”
字符结束的字符串
它拥有一个
LAYOUT_NEWLINE_AFTER
字段
是一个
Layout_2
未设置的
ChoiceGroup
、
DateField
、
Gauge
或
TextField
LAYOUT_NEWLINE_BEFORE
或
LAYOUT_NEWLINE_AFTER
字段不会在已经有一个换行的时候产生多余的换行。比如,如果一个以
”/n”
开头的
StringItem
包含
LAYOUT_NEWLINE_BEFORE
字段,将只产生一个换行。一个相似的情况是,
”/n”
结尾并包含
LAYOUT_NEWLINE_AFTER
字段。同样如果前一个
item
包含
LAYOUT_NEWLINE_AFER
而接下来的
item
包含
LAYOUT_NEWLINE_BEFORE
字段。但是,无论是在单独的
StringItem
或是在相连的
StringItem
里显示连续的
”/n”
字符,都会根据
”/n”
的个数产生换行的数目。这会造成空行。空行的高度是由包含
”/n”
字符的
StringItem
中主要的字体高度在决定的。
系统会为换行发生提供额外的条件。比如,一个系统的布局算法会特别对待
label
,隐式的对每一个包含
label
的
item
产生换行。或者,再比如,一个特定的系统用户界面样式会规定
DateField item
总是单独显式在一行中。这种情况下,系统会在每个
DateField item
的前后都产生换行。
两个连续的
item
,如果没有换行或是系统定义的换行发生,并且如果有足够的空间,这两个
item
会被放在同一行中。
当把一个
item
放在行中是,
item
的宽度将和行剩余的宽度相比较。
item
的宽度用的是最佳宽度,除非
item
含有
LAYOUT_SHRINK
字段,这时
item
的最小宽度被应用。如果一个
item
太宽已至于不能放在一行中剩余的空间里,这时行被认为已满,一个新行将在下面被创建,并且该
item
将被放入新的一行里。
一旦一行中的内容被确定,行内剩余的空间通过扩展
item
和在
item
之间添加空格来分配。如果行中任何一个
item
含有
LAYOUT_SHRINK
字段(就是说,是可收缩的),空间会先分配给这些
item
。剩余空间按这些
item
最大宽度和最小宽度的差按比例分配给它们。在这个阶段,没有一个可收缩的
item
的宽度可以超过它们最佳宽度。
比如,考虑一个含有
30
个像素剩余空间的行,行中包含两个可收缩的
item A
和
B
。
Item A
的最佳宽度是
15
,最小宽度是
10
,
B
的最佳宽度是
30
,最小宽度是
20
。
A
的最佳宽度和最小宽度的差是
5
,
B
的最佳宽度和最小宽度的差是
10
。
30
个像素根据两个
item
的差值按比例分配。所以,
10
个像素分配给
A
,
20
个像素分配给
B
。
如果扩展所有可收缩的
item
之后,行中仍有剩余空间,这些剩余空间就在含有
LAYOUT_EXPAND
字段的
item
(可扩展的
item
)中平均分配。仍何一个可扩展的
item
都会使这一行的空间被占满。
如果行中没有可扩展的
item
,而且行中仍有一些剩余空间,
item
会按照它们的
current alignment
尽可紧的排列在一起。(因为改变
current alignment
会引起换行,所以一行中的所有
item
拥有相同的
alignment
值。)如果
alignment
值是
LAYOUT_LEFT
,
item
被放在一行的最左边剩余空间被放在一行的右边。如果
alignment
值是
LAYOUT_RIGHT
,
item
被放在一行的最右边剩余空间被放在一行的左边。如果
alignment
值是
LAYOUT_CENTER
,
item
会放在行的中央,剩余空间分在左右两边平分。
在一个特定行的
item
集中,这些
item
的高度是被子检查过的。对每一个
item
,高度用的是最佳高度,除非
item
含有
LAYOUT_VSHRINK
字段,这时
item
的最小高度被使用。行中最高的
item
决定该行的高度。含有
LAYOUT_VSHRINK
字段的
item
被扩展到它们的最佳高度或是行高中最小的那一个。那些仍旧小于行高的
item
如果含有
LAYOUT_VEXPAND
字段分扩展到行高。
Item
中的
LAYOUT_VEXPAND
字段不会增加行高。
剩余那些比行高小的
item
会根据
LAYOUT_TOP
、
LAYOUT_BOTTOM
和
LAYOUT_VCENTER
字段放在行中。如果没有指定的垂直布局字段,
item
必须排列在一行的底部。
StringItem
的排列同上面的排列算法有所不同。如果一个
StringItem
的内容(即它的值,除了它的
label
)包含一个换行符(
”/n”
),字符串会被分开,后半部分会在下一行的开始处排列。
如果
StringItem
的一维或是两个维度的最佳大小被锁定,
StringItem
被包装以适合这两个大小,并且被看做是一个最佳和最小的高度和宽度都是这个高度和宽度的矩形框。这时,
LAYOUT_SHRINK
、
LAYOUT_EXPAND
和
LAYOUT_VEXPAND
将被忽略。
如果两个维度的最佳大小都没被锁定,
StringItem
中的文本可能会跨越多行。这时在布局算法里
item
的宽度和剩余的行宽比较,把尽可能多的
StringItem
前面的文本放入当前行。这行的内容根据
current alignment
的值排列。
StringItem
中剩余的文本被放在接下来的行中。每一个被填满的行排照
current alighment
排列。最后一行可能会留有剩余空间。如果
StringItem
后没有换行符,后面的
item
被放入该行中,并且该行的内容按照
current alignment
的值排列。这个规则对作为文本设置为
flush-left
、
flush-right
或
centered
段落的
StringItem
的显示有影响,这取决于
current alignment
的值是
LAYOUT_LEFT
、
LAYOUT_RIGHTG
还是
LAYOUT_CENTER
。方法
Item.getPreferredWidth
和
Item.getPreferredHeight
返回的
StringItem
的最佳高度和宽度定义了包装文本的矩形边框。
ImageItems
同样和上面的排列方法有所不风吹草动。前面关于水平排列的值和
LAYOUT_LEFT
、
LAYOUT_RIGHT
和
LAYOUT_CENTER
字段,只有在
ImageItem
拥有
LAYOUT_2
字段时才有效。如果一个
ImageItem
没有
LAYOUT_2
字段,
LAYOUT_LEFT
、
LAYOUT_RIGHT
和
LAYOUT_CENTER
的行为由系统定义。
一个
Form
的布局如果必要会重新排列。这种情况可能会在一个
item
由于内容的变化而引起的大小改变或是因为由应用程序请求改变一个
item
的最佳大小是发生。还可能在一个
item
的
layout
字段被应用程序改变。应用程序没有必要执行任何特定的行为来引起
Form
的布局更新。
挽行和包装
在所有文本被包装的情况下,换行必须在每一个换行符出现的地方发生(
”/n”=Unicode ‘U+000A’
)。如果空间不允许完全显示文本,它将在换行符的地方被裁减。如果没有合适的换行符,建议在词间之前进行系统换行。如果没有词间,建议在字符间进行系统换行。
包含换行符的
Label
可能会在换行处被裁减,剩余的部分可能不被显示。
用户界面
当一个
Form
显示在屏幕上时,用户可能一确定的和它或是它的
item
交互(比如,
traversing
和可能的
scrolling
)。这些
traversing
和
scrolling
操作不会改变应用程序的可见事件发和。系统在用户修改一个
Form
中的交互组件的状态时通知应用程序。通知通过调用利用
setItemStateListener()
方法设置给
Form
的监听器的
itemStateChanged()
方法。
同其它的
Displayable
对象相同,
Form
可以声明
command
并通过
setCommandListener()
方法注册一个
command listener
。
CommandListener
对象和
ItemStateListener
对象不同,并且分别声明和调用。
给应用程序开发人员的提示
虽然这个类允许构建任意组件的组合,应用程序开发者应该记住最小屏幕的概念。
Form
应该包含最少的密切相关的
UI
组件
如果
item
的数量屏幕容纳不下,系统会让它可滚动或是在某些组件被编辑时转到个一单独的屏幕。
javax.microedition.lcdui
Class Form
Class Form
java.lang.Object javax.microedition.lcdui.Displayable javax.microedition.lcdui.Screen javax.microedition.lcdui.Form
public class
Form
extends Screen
A
Form
is a
Screen
that contains an arbitrary mixture of items: images, read-only text fields, editable text fields, editable date fields, gauges, choice groups, and custom items. In general, any subclass of the
ItemForm
scrolls together.
class may be contained within a form. The implementation handles layout, traversal, and scrolling. The entire contents of the
Item Management
The items contained within a
Form
may be edited using append, delete, insert, and set methods.
Items
within a
Form
are referred to by their indexes, which are consecutive integers in the range from zero to
size()-1
, with zero referring to the first item and
size()-1
to the last item.
An item may be placed within at most one
Form
. If the application attempts to place an item into a
Form
, and the item is already owned by this or another
Form
, an
IllegalStateException
is thrown. The application must remove the item from its currently containing
Form
before inserting it into the new
Form
.
If the
Form
is visible on the display when changes to its contents are requested by the application, updates to the display take place as soon as it is feasible for the implementation to do so. Applications need not take any special action to refresh a
Form's
display after its contents have been modified.
Layout
Layout policy in
Form
is organized around rows. Rows are typically related to the width of the screen, respective of margins, scroll bars, and such. All rows in a particular
Form
will have the same width. Rows do not vary in width based on the
Items
contained within the
Form
, although they may all change width in certain circumstances, such as when a scroll bar needs to be added or removed.
Forms
generally do not scroll horizontally.
Forms
grow vertically and scroll vertically as necessary. The height of a
Form
varies depending upon the number of rows and the height of each row. The height of each row is determined by the items that are positioned on that row. Rows need not all have the same height. Implementations may also vary row heights to provide proper padding or vertical alignment of
Item
labels.
An implementation may choose to lay out
Items
in a left-to-right or right-to-left direction depending upon the language conventions in use. The same choice of layout direction must apply to all rows within a particular
Form
.
Prior to the start of the layout algorithm, the
Form
is considered to have one empty row at the top. The layout algorithm considers each Item in turn, starting at
Item
zero and proceeding in order through each
Item
until the last
Item
in the
Form
has been processed. If the layout direction (as described above) is left-to-right, the beginning of the row is the left edge of the
Form
. If the layout direction is right-to-left, the beginning of the row is the right edge of the
Form
.
Items
are laid out at the beginning of each row, proceeding across each row in the chosen layout direction, packing as many
Items
onto each row as will fit, unless a condition occurs that causes the packing of a row to be terminated early. A new row is then added, and
Items
are packed onto it as described above.
Items
are packed onto rows, and new rows are added below existing rows as necessary until all
Items
have been processed by the layout algorithm.
The layout algorithm has a concept of a
current alignment. It can have the value
LAYOUT_LEFT
,
LAYOUT_CENTER
, or
LAYOUT_RIGHT
. The value of the current alignment at the start of the layout algorithm depends upon the layout direction in effect for this
Form
. If the layout direction is left-to-right, the initial alignment value must be
LAYOUT_LEFT
. If the layout direction is right-to-left, the initial alignment value must be
LAYOUT_RIGHT
. The current alignment changes when the layout algorithm encounters an
Item
that has one of the layout directives
LAYOUT_LEFT
,
LAYOUT_CENTER
, or
LAYOUT_RIGHT
. If none of these directives is present on an
Item
, the current layout directive does not change. This rule has the effect of grouping the contents of the
Form
into sequences of consecutive
Items
sharing an alignment value. The alignment value of each
Item
is maintained internally to the
Form
and does not affect the
Items'
layout value as reported by the
Item.getLayout
method.
The layout algorithm generally attempts to place an item on the same row as the previous item, unless certain conditions occur that cause a "row break." When there is a row break, the current item will be placed at the beginning of a new row instead of being placed after the previous item, even if there is room.
A row break occurs before an item if any of the following conditions occurs:
- the previous item has a row break after it;
- it has the
LAYOUT_NEWLINE_BEFORE
directive; or - it is a
StringItem
whose contents starts with "/n"; - it is a
ChoiceGroup
,DateField
,Gauge
, or aTextField
, and theLAYOUT_2
directive is not set; or - this
Item
has aLAYOUT_LEFT
,LAYOUT_CENTER
, orLAYOUT_RIGHT
directive that differs from theForm's
current alignment.
A row break occurs after an item if any of the following conditions occurs:
- it is a
StringItem
whose contents ends with "/n"; or - it has the
LAYOUT_NEWLINE_AFTER
directive; or - it is a
ChoiceGroup
,DateField
,Gauge
, or aTextField
, and theLAYOUT_2
directive is not set.
The presence of the
LAYOUT_NEWLINE_BEFORE
or
LAYOUT_NEWLINE_AFTER
directive does not cause an additional row break if there is one already present. For example, if a
LAYOUT_NEWLINE_BEFORE
directive appears on a
StringItem
whose contents starts with "/n", there is only a single row break. A similar rule applies with a trailing "/n" and
LAYOUT_NEWLINE_AFTER
. Also, there is only a single row break if an item has the
LAYOUT_NEWLINE_AFTER
directive and the next item has the
LAYOUT_NEWLINE_BEFORE
directive. However, the presence of consecutive "/n" characters, either within a single
StringItem
or in adjacent
StringItems
, will cause as many row breaks as there are "/n" characters. This will cause empty rows to be present. The height of an empty row is determined by the prevailing font height of the
StringItem
within which the "/n" that ends the row occurs.
Implementations may provide additional conditions under which a row break occurs. For example, an implementation's layout policy may lay out labels specially, implicitly causing a break before every
Item
that has a label. Or, as another example, a particular implementation's user interface style may dictate that a DateField item always appears on a row by itself. In this case, this implementation may cause row breaks to occur both before and after every
DateField
item.
Given two items with adjacent
Form
indexes, if none of the specified or implementation-specific conditions for a row break between them occurs, and if space permits, these items should be placed on the same row.
When packing
Items
onto a row, the width of the item is compared with the remaining space on the row. For this purpose, the width used is the
Item's
preferred width, unless the
Item
has the
LAYOUT_SHRINK
directive, in which case the
Item's
minimum width is used. If the
Item
is too wide to fit in the space remaining on the row, the row is considered to be full, a new row is added beneath this one, and the
Item
is laid out on this new row.
Once the contents of a row have been determined, the space available on the row is distributed by expanding items and by adding space between items. If any items on this row have the
LAYOUT_SHRINK
directive (that is, they are shrinkable), space is first distributed to these items. Space is distributed to each of these items proportionally to the difference between the each
Item's
preferred size and its minimum size. At this stage, no shrinkable item is expanded beyond its preferred width.
For example, consider a row that has
30
pixels of space available and that has two shrinkable items
A
and
B
. Item
A's
preferred size is
15
and its minimum size is
10
. Item
B's
preferred size is
30
and its minimum size is
20
. The difference between
A's
preferred and minimum size is
5
, and
B's
difference is
10
. The
30
pixels are distributed to these items proportionally to these differences. Therefore,
10
pixels are distributed to item
A
and
20
pixels to item
B
.
If after expanding all the shrinkable items to their preferred widths, there is still space left on the row, this remaining space is distributed equally among the Items that have the
LAYOUT_EXPAND
directive (the stretchable
Items
). The presence of any stretchable items on a row will cause the
Items
on this row to occupy the full width of the row.
If there are no stretchable items on this row, and there is still space available on this row, the
Items
are packed as tightly as possible and are placed on the row according to the alignment value shared by the
Items
on this row. (Since changing the current alignment causes a row break, all
Items
on the same row must share the same alignment value.) If the alignment value is
LAYOUT_LEFT
, the
Items
are positioned at the left end of the row and the remaining space is placed at the right end of the row. If the alignment value is
LAYOUT_RIGHT
, the
Items
are positioned at the right end of the row and the remaining space is placed at the left end of the row. If the alignment value is
LAYOUT_CENTER
, the
Items
are positioned in the middle of the row such that the remaining space on the row is divided evenly between the left and right ends of the row.
Given the set of items on a particular row, the heights of these
Items
are inspected. For each
Item
, the height that is used is the preferred height, unless the
Item
has the
LAYOUT_VSHRINK
directive, in which case the
Item's
minimum height is used. The height of the tallest
Item
determines the height of the row.
Items
that have the
LAYOUT_VSHRINK
directive are expanded to their preferred height or to the height of the row, whichever is smaller.
Items
that are still shorter than the row height and that have the
LAYOUT_VEXPAND
directive will expand to the height of the row. The
LAYOUT_VEXPAND
directive on an item will never increase the height of a row.
Remaining
Items
shorter than the row height will be positioned vertically within the row using the
LAYOUT_TOP
,
LAYOUT_BOTTOM
, and
LAYOUT_VCENTER
directives. If no vertical layout directive is specified, the item must be aligned along the bottom of the row.
StringItems
are treated specially in the above algorithm. If the contents of a
StringItem
(its string value, exclusive of its label) contain a newline character ("/n"), the string should be split at that point and the remainder laid out starting on the next row.
If one or both dimensions of the preferred size of a
StringItem
have been locked, the
StringItem
is wrapped to fit that width and height and is treated as a rectangle whose minimum and preferred width and height are the width and height of this rectangle. In this case, the
LAYOUT_SHRINK
,
LAYOUT_EXPAND
, and
LAYOUT_VEXPAND
directives are ignored.
If both dimensions of the preferred size of a
StringItem
are unlocked, the text from the
StringItem
may be wrapped across multiple rows. At the point in the layout algorithm where the width of the
Item
is compared to the remaining space on the row, as much text is taken from the beginning of the
StringItem
as will fit onto the current row. The contents of this row are then positioned according to the current alignment value. The remainder of the text in the
StringItem
is line-wrapped to the full width of as many new rows as are necessary to accommodate the text. Each full row is positioned according to the current alignment value. The last line of the text might leave space available on its row. If there is no row break following this
StringItem
, subsequent
Items
are packed into the remaining space and the contents of the row are positioned according to the current alignment value. This rule has the effect of displaying the contents of a
StringItem
as a paragraph of text set flush-left, flush-right, or centered, depending upon whether the current alignment value is
LAYOUT_LEFT
,
LAYOUT_RIGHT
, or
LAYOUT_CENTER
, respectively. The preferred width and height of a
StringItem
wrapped across multiple rows, as reported by the
Item.getPreferredWidth
and
Item.getPreferredHeight
methods, describe the width and height of the bounding rectangle of the wrapped text.
ImageItems
are also treated specially by the above algorithm. The foregoing rules concerning the horizontal alignment value and the
LAYOUT_LEFT
,
LAYOUT_RIGHT
, and
LAYOUT_CENTER
directives, apply to
ImageItems
only when the
LAYOUT_2
directive is also present on that item. If the
LAYOUT_2
directive is not present on an
ImageItem
, the behavior of the
LAYOUT_LEFT
,
LAYOUT_RIGHT
, and
LAYOUT_CENTER
directives is implementation-specific.
A
Form's
layout is recomputed automatically as necessary. This may occur because of a change in an
Item's
size caused by a change in its contents or because of a request by the application to change the Item's preferred size. It may also occur if an
Item's
layout directives are changed by the application. The application does not need to perform any specific action to cause the
Form's
layout to be updated.
Line Breaks and Wrapping
For all cases where text is wrapped, line breaks must occur at each newline character (
'/n'
= Unicode
'U+000A'
). If space does not permit the full text to be displayed it is truncated at line breaks. If there are no suitable line breaks, it is recommended that implementations break text at word boundaries. If there are no word boundaries, it is recommended that implementations break text at character boundaries.
Labels that contain line breaks may be truncated at the line break and cause the rest of the label not to be shown.
User Interaction
When a
Form
is present on the display the user can interact with it and its
Items
indefinitely (for instance, traversing from
Item
to
Item
and possibly scrolling). These traversing and scrolling operations do not cause application-visible events. The system notifies the application when the user modifies the state of an interactive
Item
contained within the
Form
. This notification is accomplished by calling the
itemStateChanged()Form
with the setItemStateListener()
method.
method of the listener declared to the
As with other
Displayable
objects, a
Form
can declare
commands
and declare a command listener with the
setCommandListener()
method.
CommandListener
objects are distinct from
ItemStateListener
objects, and they are declared and invoked separately.
Notes for Application Developers
- Although this class allows creation of arbitrary combination of components the application developers should keep the small screen size in mind.
Form
is designed to contain a small number of closely related UI elements. - If the number of items does not fit on the screen, the implementation may choose to make it scrollable or to fold some components so that a separate screen appears when the element is edited.
Since:
MIDP 1.0
See Also:
Item 翻译:lori.wang