public abstract class Widget extends Object
There are a number of important concepts involving widgets:
Lay out is the process of positioning and setting the size of the widgets on a desktop.
This is performed by evaluating the optimal size of each widget and container in the hierarchy then, considering the layout of the containers and the optimal size of their children, setting the position and actual size of all widgets.
The optimal size is the minimal size that allow to show correctly the content of a widget. For instance the optimal size of a label that displays a string will be the size of the string with the font defined in the style.
The optimal size is computed by computeContentOptimalSize(Size)
method. On this size are applied the boxes
and dimension defined in the style, and the size of the widget is set. This size is then used by the parent container
to lay out (set position and size) the widget along with its siblings.
Whenever the state of a widget changes in a way that may affect its optimal size and the lay out of the desktop of
which it is a part then the hierarchy of the widget must be ask to perform a new lay out. This can be achieved by
invoking requestLayOut()
on one of the parents of the widget or the desktop depending on the lay out
modification.
An application will normally invoke requestLayOut()
after making a set of changes to widgets.
Any widget can be asked to render itself by invoking requestRender()
. If a widget has children it will ask
them to render. If the widget is transparent it will cause the relevant area of its parent to be rendered. Note that
a render request does not trigger a new lay out, and the scope of the rendering that results from a call to
requestRender()
will never exceed the widget itself, its children (recursively), and, if it is transparent,
its parent (recursively if the parent is also transparent).
For heap optimization the position and size are stored as a short
and therefore are limited between
-32768
and 32767
.
Modifier and Type | Field and Description |
---|---|
static int |
NO_CONSTRAINT
A width or height hint equal to
NO_CONSTRAINT means that there is no constraint on this dimension. |
Constructor and Description |
---|
Widget()
Creates a widget.
|
Modifier and Type | Method and Description |
---|---|
void |
addClassSelector(int classSelector)
Adds a class selector.
|
protected abstract void |
computeContentOptimalSize(Size size)
Computes the optimal size of the widget.
|
boolean |
contains(int x,
int y)
Gets whether or not a position (x,y) is in the widget's bounds.
|
boolean |
containsWidget(Widget widget)
Returns whether or not this widget contains the given widget in its hierarchy.
|
int |
getAbsoluteX()
Gets the absolute x coordinate of the widget.
|
int |
getAbsoluteY()
Gets the absolute y coordinate of the widget.
|
Rectangle |
getContentBounds()
Gets the content bounds of this widget (the bounds minus the outlines).
|
Desktop |
getDesktop()
Gets the desktop to which this widget has been added.
|
int |
getHeight()
Gets the height of this widget.
|
Container |
getParent()
Gets the parent of this widget or
null if the widget is not in a hierarchy or if it is the root of
its hierarchy. |
Style |
getStyle()
Gets the current style of the widget.
|
Widget |
getWidgetAt(int x,
int y)
Gets the widget at the specified position.
|
int |
getWidth()
Gets the width of this widget.
|
int |
getX()
Gets the x coordinate of this widget, relative to its parent.
|
int |
getY()
Gets the y coordinate of this widget, relative to its parent.
|
boolean |
handleEvent(int event)
Handles the given event.
|
boolean |
hasClassSelector(int classSelector)
Gets whether or not the widget has the given class selector.
|
boolean |
isAttached()
Gets whether this widget is attached or not.
|
boolean |
isEnabled()
Gets whether or not this widget is enabled.
|
boolean |
isInState(int state)
Gets whether or not the widget is in the given state.
|
boolean |
isShown()
Gets whether this widget is shown or not.
|
boolean |
isTransparent()
Tells whether or not this widget is transparent.
|
protected void |
onAttached()
This method is called as soon as:
the widget is attached to a desktop that is attached,
the desktop of the widget is attached.
|
protected void |
onDetached()
This method is called as soon as:
the widget is detached from a desktop that is attached,
the desktop of the widget is detached.
|
protected void |
onHidden()
This method is called as soon as the widget is no more visible on the display.
|
protected void |
onLaidOut()
This method is called as soon as the widget bounds are set.
|
protected void |
onShown()
This method is called as soon as the widget is visible on the display.
|
void |
removeAllClassSelectors()
Removes all the class selectors.
|
void |
removeClassSelector(int classSelector)
Removes a class selector.
|
void |
render(GraphicsContext g)
Renders the widget on the given graphics context.
|
protected abstract void |
renderContent(GraphicsContext g,
int contentWidth,
int contentHeight)
Renders the content of the widget without the border, margin and padding specified in the style.
|
void |
requestLayOut()
Requests a lay out of all the widgets in the sub hierarchy of this widget.
|
void |
requestRender()
Requests a render of this entire widget on the display.
|
void |
requestRender(int x,
int y,
int width,
int height)
Requests a render of a zone of this widget on the display.
|
void |
setClassSelectors(int[] classSelectors)
Sets the class selectors.
|
void |
setEnabled(boolean enabled)
Sets this widget to be enabled or not.
|
void |
setPosition(int x,
int y)
Sets the position of this widget.
|
void |
setStyle(Style newStyle)
Sets the style of the widget.
|
void |
updateStyle()
Updates the style of this widget.
|
public static final int NO_CONSTRAINT
NO_CONSTRAINT
means that there is no constraint on this dimension.public Widget()
Once created, the widget is disabled. It may be enabled by calling setEnabled(boolean)
. Enabled widgets
can handle events by overriding handleEvent(int)
.
public void addClassSelector(int classSelector)
classSelector
- the class selector to add.NullPointerException
- if the given class selector is null
.protected abstract void computeContentOptimalSize(Size size)
This method does not consider the border, margin, padding and dimension specified in the style.
The given size is the available size for this widget in its parent. A width or a height equal to
Widget#NO_CONSTRAINT
means that there is no constraint on this dimension.
The given size is modified to set the optimal size.
size
- the size available for the content.public boolean contains(int x, int y)
The given position is considered here as a relative position to parent.
Subclasses can override this method if the widget is not reactive to pointer events in its entire bounds. As long as this method is used to dispatch pointer events, its implementation should be as fast as possible (for example by simplifying the shape of the sensitive area).
If this method is overridden, it may be relevant to override the isTransparent()
method as well.
x
- x coordinate.y
- y coordinate.true
if the (x,y)
position is in widget bounds, false
otherwise.public boolean containsWidget(Widget widget)
A widget contains an other widget if one of the children of the former contains the latter or if they reference the same widget.
widget
- the widget to check.true
if this widget contains the given widget, false
otherwise.public int getAbsoluteX()
public int getAbsoluteY()
public Rectangle getContentBounds()
public Desktop getDesktop()
This method can only be called if this widget has been added to a desktop.
public int getHeight()
@Nullable public Container getParent()
null
if the widget is not in a hierarchy or if it is the root of
its hierarchy.null
.public Style getStyle()
This method should not be called before this widget is laid out.
Stylesheet.getStyle(Widget)
@Nullable public Widget getWidgetAt(int x, int y)
If this widget does not contains(x, y)
, null
is returned, else this widget is returned.
The position is considered here as a relative position to parent.
x
- x coordinate.y
- y coordinate.contains(x, y)
, null
otherwise.public int getWidth()
public int getX()
public int getY()
public boolean handleEvent(int event)
false
(does not consume event).
Called by the desktop event manager.
event
- the event to handle.true
if the widget has consumed the event, false
otherwise.public boolean hasClassSelector(int classSelector)
classSelector
- the class selector to check.true
if the widget has the given class selector, false
otherwise.public boolean isAttached()
A widget is considered as attached if it belongs to the hierarchy of an attached desktop.
true
if this widget is attached, false
otherwise.public boolean isEnabled()
true
if this widget is enabled, false
otherwise.public boolean isInState(int state)
state
- the state to check.true
if the widget is in the given state, false
otherwise.public boolean isShown()
true
if this widget is shown, false
otherwise.public boolean isTransparent()
By default, a widget is transparent. A widget is considered as transparent if it does not draw every pixel of its bounds with maximal opacity when it is rendered. If a widget is transparent, its parent (recursively if also transparent) has to be rendered before the widget.
true
if this widget is transparent, false
otherwise.contains(int, int)
protected void onAttached()
After this call, the widget is ready to be rendered.
For example, the widget can allocate some resources useful to render it.
Desktop.setAttached()
protected void onDetached()
After this call, the resources allocated to render the widget must be disposed.
Desktop.setDetached()
protected void onHidden()
After this call, all that has been allocated or started in onShown()
must be disposed or stopped.
protected void onLaidOut()
protected void onShown()
For example, this method can be used to start a task that refreshes the widget periodically.
public void removeAllClassSelectors()
public void removeClassSelector(int classSelector)
classSelector
- the class selector to remove.public void render(GraphicsContext g)
The given graphics context is translated to the origin of the widget and clipped to the area to draw.
First, the different outlines defined in the style are applied, then, the content is rendered.
g
- the graphics context to use to draw the widget.OutlineHelper.applyOutlinesAndBackground(GraphicsContext, Size, Style)
,
renderContent(GraphicsContext, int, int)
protected abstract void renderContent(GraphicsContext g, int contentWidth, int contentHeight)
The given graphics context is translated and clipped according to the given bounds (the border, margin and padding are applied on this graphics context before).
g
- the graphics context where to render the content of the widget.contentWidth
- the width of the content area.contentHeight
- the height of the content area.public void requestLayOut()
This method returns immediately and the layout of the widget is performed asynchronously in the MicroUI thread.
This method can only be called if this widget has been added to a desktop.
Nothing is done if the widget is not attached.
If the widget was not already shown, it is shown as soon as its bounds are set.
The style of all the widgets in the hierarchy is set (or updated) during this phase.
public void requestRender()
If the widget is not shown, nothing is done.
RenderPolicy
public void requestRender(int x, int y, int width, int height)
If the widget is not shown, nothing is done.
If the given area exceeds the bounds of the widget, only the intersection of the widget and the area will be rendered.
x
- the relative x coordinate of the area to render.y
- the relative y coordinate of the area to render.width
- the width of the area to render.height
- the height of the area to render.RenderPolicy
public void setClassSelectors(int[] classSelectors)
If there is already some class selectors, they are removed.
classSelectors
- the class selectors list to split.public void setEnabled(boolean enabled)
enabled
- true
if this widget is to be enabled, false
otherwise.public void setPosition(int x, int y)
x
- the x coordinate to set.y
- the y coordinate to set.public void setStyle(Style newStyle)
newStyle
- the style to set.public void updateStyle()
If the widget is not in a desktop, nothing is done.