2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2019 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import java
.io
.IOException
;
32 import java
.util
.List
;
33 import java
.util
.ArrayList
;
35 import jexer
.backend
.Screen
;
36 import jexer
.bits
.Cell
;
37 import jexer
.bits
.CellAttributes
;
38 import jexer
.bits
.ColorTheme
;
39 import jexer
.event
.TCommandEvent
;
40 import jexer
.event
.TInputEvent
;
41 import jexer
.event
.TKeypressEvent
;
42 import jexer
.event
.TMenuEvent
;
43 import jexer
.event
.TMouseEvent
;
44 import jexer
.event
.TResizeEvent
;
45 import jexer
.menu
.TMenu
;
46 import jexer
.ttree
.TTreeItem
;
47 import jexer
.ttree
.TTreeView
;
48 import jexer
.ttree
.TTreeViewWidget
;
49 import static jexer
.TKeypress
.*;
52 * TWidget is the base class of all objects that can be drawn on screen or
53 * handle user input events.
55 public abstract class TWidget
implements Comparable
<TWidget
> {
57 // ------------------------------------------------------------------------
58 // Variables --------------------------------------------------------------
59 // ------------------------------------------------------------------------
62 * Every widget has a parent widget that it may be "contained" in. For
63 * example, a TWindow might contain several TFields, or a TComboBox may
64 * contain a TList that itself contains a TVScroller.
66 private TWidget parent
= null;
69 * Child widgets that this widget contains.
71 private List
<TWidget
> children
;
74 * The currently active child widget that will receive keypress events.
76 private TWidget activeChild
= null;
79 * If true, this widget will receive events.
81 private boolean active
= false;
84 * The window that this widget draws to.
86 private TWindow window
= null;
89 * Absolute X position of the top-left corner.
94 * Absolute Y position of the top-left corner.
101 private int width
= 0;
106 private int height
= 0;
109 * My tab order inside a window or containing widget.
111 private int tabOrder
= 0;
114 * If true, this widget can be tabbed to or receive events.
116 private boolean enabled
= true;
119 * If true, this widget will be rendered.
121 private boolean visible
= true;
124 * If true, this widget has a cursor.
126 private boolean cursorVisible
= false;
129 * Cursor column position in relative coordinates.
131 private int cursorX
= 0;
134 * Cursor row position in relative coordinates.
136 private int cursorY
= 0;
138 // ------------------------------------------------------------------------
139 // Constructors -----------------------------------------------------------
140 // ------------------------------------------------------------------------
143 * Default constructor for subclasses.
145 protected TWidget() {
146 children
= new ArrayList
<TWidget
>();
150 * Protected constructor.
152 * @param parent parent widget
154 protected TWidget(final TWidget parent
) {
159 * Protected constructor.
161 * @param parent parent widget
162 * @param x column relative to parent
163 * @param y row relative to parent
164 * @param width width of widget
165 * @param height height of widget
167 protected TWidget(final TWidget parent
, final int x
, final int y
,
168 final int width
, final int height
) {
170 this(parent
, true, x
, y
, width
, height
);
174 * Protected constructor used by subclasses that are disabled by default.
176 * @param parent parent widget
177 * @param enabled if true assume enabled
179 protected TWidget(final TWidget parent
, final boolean enabled
) {
180 this.enabled
= enabled
;
181 this.parent
= parent
;
182 this.window
= parent
.window
;
183 children
= new ArrayList
<TWidget
>();
185 // Do not add TStatusBars, they are drawn by TApplication.
186 if (this instanceof TStatusBar
) {
189 parent
.addChild(this);
194 * Protected constructor used by subclasses that are disabled by default.
196 * @param parent parent widget
197 * @param enabled if true assume enabled
198 * @param x column relative to parent
199 * @param y row relative to parent
200 * @param width width of widget
201 * @param height height of widget
203 protected TWidget(final TWidget parent
, final boolean enabled
,
204 final int x
, final int y
, final int width
, final int height
) {
206 this.enabled
= enabled
;
207 this.parent
= parent
;
208 this.window
= parent
.window
;
209 children
= new ArrayList
<TWidget
>();
211 // Do not add TStatusBars, they are drawn by TApplication.
212 if (this instanceof TStatusBar
) {
215 parent
.addChild(this);
221 this.height
= height
;
225 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
227 * @param window the top-level window
228 * @param x column relative to parent
229 * @param y row relative to parent
230 * @param width width of window
231 * @param height height of window
233 protected final void setupForTWindow(final TWindow window
,
234 final int x
, final int y
, final int width
, final int height
) {
236 this.parent
= window
;
237 this.window
= window
;
241 this.height
= height
;
244 // ------------------------------------------------------------------------
245 // Event handlers ---------------------------------------------------------
246 // ------------------------------------------------------------------------
249 * Subclasses should override this method to cleanup resources. This is
250 * called by TWindow.onClose().
252 protected void close() {
253 // Default: call close() on children.
254 for (TWidget w
: getChildren()) {
260 * Check if a mouse press/release event coordinate is contained in this
263 * @param mouse a mouse-based event
264 * @return whether or not a mouse click would be sent to this widget
266 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
272 if ((this instanceof TTreeItem
)
273 && ((y
< 0) || (y
> parent
.getHeight() - 1))
278 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
279 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
280 && (mouse
.getAbsoluteY() >= getAbsoluteY())
281 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
289 * Method that subclasses can override to handle keystrokes.
291 * @param keypress keystroke event
293 public void onKeypress(final TKeypressEvent keypress
) {
295 if ((children
.size() == 0)
296 || (this instanceof TTreeView
)
297 || (this instanceof TText
)
298 || (this instanceof TComboBox
)
302 // tab / shift-tab - switch to next/previous widget
303 // left-arrow or up-arrow: same as shift-tab
304 if ((keypress
.equals(kbTab
))
305 || (keypress
.equals(kbDown
) && !(this instanceof TComboBox
))
307 parent
.switchWidget(true);
309 } else if ((keypress
.equals(kbShiftTab
))
310 || (keypress
.equals(kbBackTab
))
311 || (keypress
.equals(kbUp
) && !(this instanceof TComboBox
))
313 parent
.switchWidget(false);
318 if ((children
.size() == 0)
319 && !(this instanceof TTreeView
)
323 // right-arrow or down-arrow: same as tab
324 if (keypress
.equals(kbRight
)) {
325 parent
.switchWidget(true);
327 } else if (keypress
.equals(kbLeft
)) {
328 parent
.switchWidget(false);
333 // If I have any buttons on me AND this is an Alt-key that matches
334 // its mnemonic, send it an Enter keystroke
335 for (TWidget widget
: children
) {
336 if (widget
instanceof TButton
) {
337 TButton button
= (TButton
) widget
;
338 if (button
.isEnabled()
339 && !keypress
.getKey().isFnKey()
340 && keypress
.getKey().isAlt()
341 && !keypress
.getKey().isCtrl()
342 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
343 == Character
.toLowerCase(keypress
.getKey().getChar()))
346 widget
.onKeypress(new TKeypressEvent(kbEnter
));
352 // Dispatch the keypress to an active widget
353 for (TWidget widget
: children
) {
355 widget
.onKeypress(keypress
);
362 * Method that subclasses can override to handle mouse button presses.
364 * @param mouse mouse button event
366 public void onMouseDown(final TMouseEvent mouse
) {
367 // Default: do nothing, pass to children instead
368 if (activeChild
!= null) {
369 if (activeChild
.mouseWouldHit(mouse
)) {
370 // Dispatch to the active child
372 // Set x and y relative to the child's coordinates
373 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
374 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
375 activeChild
.onMouseDown(mouse
);
379 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
380 TWidget widget
= children
.get(i
);
381 if (widget
.mouseWouldHit(mouse
)) {
382 // Dispatch to this child, also activate it
385 // Set x and y relative to the child's coordinates
386 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
387 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
388 widget
.onMouseDown(mouse
);
395 * Method that subclasses can override to handle mouse button releases.
397 * @param mouse mouse button event
399 public void onMouseUp(final TMouseEvent mouse
) {
400 // Default: do nothing, pass to children instead
401 if (activeChild
!= null) {
402 if (activeChild
.mouseWouldHit(mouse
)) {
403 // Dispatch to the active child
405 // Set x and y relative to the child's coordinates
406 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
407 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
408 activeChild
.onMouseUp(mouse
);
412 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
413 TWidget widget
= children
.get(i
);
414 if (widget
.mouseWouldHit(mouse
)) {
415 // Dispatch to this child, also activate it
418 // Set x and y relative to the child's coordinates
419 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
420 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
421 widget
.onMouseUp(mouse
);
428 * Method that subclasses can override to handle mouse movements.
430 * @param mouse mouse motion event
432 public void onMouseMotion(final TMouseEvent mouse
) {
433 // Default: do nothing, pass it on to ALL of my children. This way
434 // the children can see the mouse "leaving" their area.
435 for (TWidget widget
: children
) {
436 // Set x and y relative to the child's coordinates
437 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
438 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
439 widget
.onMouseMotion(mouse
);
444 * Method that subclasses can override to handle mouse button
447 * @param mouse mouse button event
449 public void onMouseDoubleClick(final TMouseEvent mouse
) {
450 // Default: do nothing, pass to children instead
451 if (activeChild
!= null) {
452 if (activeChild
.mouseWouldHit(mouse
)) {
453 // Dispatch to the active child
455 // Set x and y relative to the child's coordinates
456 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
457 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
458 activeChild
.onMouseDoubleClick(mouse
);
462 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
463 TWidget widget
= children
.get(i
);
464 if (widget
.mouseWouldHit(mouse
)) {
465 // Dispatch to this child, also activate it
468 // Set x and y relative to the child's coordinates
469 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
470 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
471 widget
.onMouseDoubleClick(mouse
);
478 * Method that subclasses can override to handle window/screen resize
481 * @param resize resize event
483 public void onResize(final TResizeEvent resize
) {
484 // Default: change my width/height.
485 if (resize
.getType() == TResizeEvent
.Type
.WIDGET
) {
486 width
= resize
.getWidth();
487 height
= resize
.getHeight();
489 // Let children see the screen resize
490 for (TWidget widget
: children
) {
491 widget
.onResize(resize
);
497 * Method that subclasses can override to handle posted command events.
499 * @param command command event
501 public void onCommand(final TCommandEvent command
) {
502 // Default: do nothing, pass to children instead
503 for (TWidget widget
: children
) {
504 widget
.onCommand(command
);
509 * Method that subclasses can override to handle menu or posted menu
512 * @param menu menu event
514 public void onMenu(final TMenuEvent menu
) {
515 // Default: do nothing, pass to children instead
516 for (TWidget widget
: children
) {
522 * Method that subclasses can override to do processing when the UI is
523 * idle. Note that repainting is NOT assumed. To get a refresh after
524 * onIdle, call doRepaint().
526 public void onIdle() {
527 // Default: do nothing, pass to children instead
528 for (TWidget widget
: children
) {
534 * Consume event. Subclasses that want to intercept all events in one go
535 * can override this method.
537 * @param event keyboard, mouse, resize, command, or menu event
539 public void handleEvent(final TInputEvent event
) {
541 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
547 // System.err.println(" -- discard --");
551 if (event
instanceof TKeypressEvent
) {
552 onKeypress((TKeypressEvent
) event
);
553 } else if (event
instanceof TMouseEvent
) {
555 TMouseEvent mouse
= (TMouseEvent
) event
;
557 switch (mouse
.getType()) {
568 onMouseMotion(mouse
);
571 case MOUSE_DOUBLE_CLICK
:
572 onMouseDoubleClick(mouse
);
576 throw new IllegalArgumentException("Invalid mouse event type: "
579 } else if (event
instanceof TResizeEvent
) {
580 onResize((TResizeEvent
) event
);
581 } else if (event
instanceof TCommandEvent
) {
582 onCommand((TCommandEvent
) event
);
583 } else if (event
instanceof TMenuEvent
) {
584 onMenu((TMenuEvent
) event
);
591 // ------------------------------------------------------------------------
592 // TWidget ----------------------------------------------------------------
593 // ------------------------------------------------------------------------
598 * @return parent widget
600 public final TWidget
getParent() {
605 * Get the list of child widgets that this widget contains.
607 * @return the list of child widgets
609 public List
<TWidget
> getChildren() {
616 * @return if true, this widget will receive events
618 public final boolean isActive() {
625 * @param active if true, this widget will receive events
627 public final void setActive(final boolean active
) {
628 this.active
= active
;
632 * Get the window this widget is on.
636 public final TWindow
getWindow() {
643 * @return absolute X position of the top-left corner
645 public final int getX() {
652 * @param x absolute X position of the top-left corner
654 public final void setX(final int x
) {
661 * @return absolute Y position of the top-left corner
663 public final int getY() {
670 * @param y absolute Y position of the top-left corner
672 public final void setY(final int y
) {
679 * @return widget width
681 public final int getWidth() {
688 * @param width new widget width
690 public final void setWidth(final int width
) {
697 * @return widget height
699 public final int getHeight() {
706 * @param height new widget height
708 public final void setHeight(final int height
) {
709 this.height
= height
;
713 * Change the dimensions.
715 * @param x absolute X position of the top-left corner
716 * @param y absolute Y position of the top-left corner
717 * @param width new widget width
718 * @param height new widget height
720 public final void setDimensions(final int x
, final int y
, final int width
,
732 * @return if true, this widget can be tabbed to or receive events
734 public final boolean isEnabled() {
741 * @param enabled if true, this widget can be tabbed to or receive events
743 public final void setEnabled(final boolean enabled
) {
744 this.enabled
= enabled
;
747 // See if there are any active siblings to switch to
748 boolean foundSibling
= false;
749 if (parent
!= null) {
750 for (TWidget w
: parent
.children
) {
752 && !(this instanceof THScroller
)
753 && !(this instanceof TVScroller
)
761 parent
.activeChild
= null;
770 * @param visible if true, this widget will be drawn
772 public final void setVisible(final boolean visible
) {
773 this.visible
= visible
;
777 * See if this widget is visible.
779 * @return if true, this widget will be drawn
781 public final boolean isVisible() {
786 * Set visible cursor flag.
788 * @param cursorVisible if true, this widget has a cursor
790 public final void setCursorVisible(final boolean cursorVisible
) {
791 this.cursorVisible
= cursorVisible
;
795 * See if this widget has a visible cursor.
797 * @return if true, this widget has a visible cursor
799 public final boolean isCursorVisible() {
800 // If cursor is out of my bounds, it is not visible.
801 if ((cursorX
>= width
)
803 || (cursorY
>= height
)
809 // If cursor is out of my window's bounds, it is not visible.
810 if ((getCursorAbsoluteX() >= window
.getAbsoluteX()
811 + window
.getWidth() - 1)
812 || (getCursorAbsoluteX() < 0)
813 || (getCursorAbsoluteY() >= window
.getAbsoluteY()
814 + window
.getHeight() - 1)
815 || (getCursorAbsoluteY() < 0)
819 return cursorVisible
;
823 * Get cursor X value.
825 * @return cursor column position in relative coordinates
827 public final int getCursorX() {
832 * Set cursor X value.
834 * @param cursorX column position in relative coordinates
836 public final void setCursorX(final int cursorX
) {
837 this.cursorX
= cursorX
;
841 * Get cursor Y value.
843 * @return cursor row position in relative coordinates
845 public final int getCursorY() {
850 * Set cursor Y value.
852 * @param cursorY row position in relative coordinates
854 public final void setCursorY(final int cursorY
) {
855 this.cursorY
= cursorY
;
859 * Get this TWidget's parent TApplication.
861 * @return the parent TApplication
863 public TApplication
getApplication() {
864 return window
.getApplication();
872 public Screen
getScreen() {
873 return window
.getScreen();
877 * Comparison operator. For various subclasses it sorts on:
879 * <li>tabOrder for TWidgets</li>
880 * <li>z for TWindows</li>
881 * <li>text for TTreeItems</li>
884 * @param that another TWidget, TWindow, or TTreeItem instance
885 * @return difference between this.tabOrder and that.tabOrder, or
886 * difference between this.z and that.z, or String.compareTo(text)
888 public final int compareTo(final TWidget that
) {
889 if ((this instanceof TWindow
)
890 && (that
instanceof TWindow
)
892 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
894 if ((this instanceof TTreeItem
)
895 && (that
instanceof TTreeItem
)
897 return (((TTreeItem
) this).getText().compareTo(
898 ((TTreeItem
) that
).getText()));
900 return (this.tabOrder
- that
.tabOrder
);
904 * See if this widget should render with the active color.
906 * @return true if this widget is active and all of its parents are
909 public final boolean isAbsoluteActive() {
910 if (parent
== this) {
913 return (active
&& parent
.isAbsoluteActive());
917 * Returns the cursor X position.
919 * @return absolute screen column number for the cursor's X position
921 public final int getCursorAbsoluteX() {
922 return getAbsoluteX() + cursorX
;
926 * Returns the cursor Y position.
928 * @return absolute screen row number for the cursor's Y position
930 public final int getCursorAbsoluteY() {
931 return getAbsoluteY() + cursorY
;
935 * Compute my absolute X position as the sum of my X plus all my parent's
938 * @return absolute screen column number for my X position
940 public final int getAbsoluteX() {
941 assert (parent
!= null);
942 if (parent
== this) {
945 if ((parent
instanceof TWindow
)
946 && !(parent
instanceof TMenu
)
947 && !(parent
instanceof TDesktop
)
949 // Widgets on a TWindow have (0,0) as their top-left, but this is
950 // actually the TWindow's (1,1).
951 return parent
.getAbsoluteX() + x
+ 1;
953 return parent
.getAbsoluteX() + x
;
957 * Compute my absolute Y position as the sum of my Y plus all my parent's
960 * @return absolute screen row number for my Y position
962 public final int getAbsoluteY() {
963 assert (parent
!= null);
964 if (parent
== this) {
967 if ((parent
instanceof TWindow
)
968 && !(parent
instanceof TMenu
)
969 && !(parent
instanceof TDesktop
)
971 // Widgets on a TWindow have (0,0) as their top-left, but this is
972 // actually the TWindow's (1,1).
973 return parent
.getAbsoluteY() + y
+ 1;
975 return parent
.getAbsoluteY() + y
;
979 * Get the global color theme.
981 * @return the ColorTheme
983 protected final ColorTheme
getTheme() {
984 return window
.getApplication().getTheme();
988 * Draw my specific widget. When called, the screen rectangle I draw
989 * into is already setup (offset and clipping).
992 // Default widget draws nothing.
996 * Called by parent to render to TWindow. Note package private access.
998 final void drawChildren() {
999 // Set my clipping rectangle
1000 assert (window
!= null);
1001 assert (getScreen() != null);
1002 Screen screen
= getScreen();
1004 // Special case: TStatusBar is drawn by TApplication, not anything
1006 if (this instanceof TStatusBar
) {
1010 screen
.setClipRight(width
);
1011 screen
.setClipBottom(height
);
1013 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
1014 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
1015 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
1016 absoluteRightEdge
-= 1;
1018 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
1019 absoluteBottomEdge
-= 1;
1021 int myRightEdge
= getAbsoluteX() + width
;
1022 int myBottomEdge
= getAbsoluteY() + height
;
1023 if (getAbsoluteX() > absoluteRightEdge
) {
1025 screen
.setClipRight(0);
1026 } else if (myRightEdge
> absoluteRightEdge
) {
1027 screen
.setClipRight(screen
.getClipRight()
1028 - (myRightEdge
- absoluteRightEdge
));
1030 if (getAbsoluteY() > absoluteBottomEdge
) {
1032 screen
.setClipBottom(0);
1033 } else if (myBottomEdge
> absoluteBottomEdge
) {
1034 screen
.setClipBottom(screen
.getClipBottom()
1035 - (myBottomEdge
- absoluteBottomEdge
));
1039 screen
.setOffsetX(getAbsoluteX());
1040 screen
.setOffsetY(getAbsoluteY());
1045 // Continue down the chain. Draw the active child last so that it
1047 for (TWidget widget
: children
) {
1048 if (widget
.isVisible() && (widget
!= activeChild
)) {
1049 widget
.drawChildren();
1052 if (activeChild
!= null) {
1053 activeChild
.drawChildren();
1058 * Repaint the screen on the next update.
1060 protected final void doRepaint() {
1061 window
.getApplication().doRepaint();
1065 * Add a child widget to my list of children. We set its tabOrder to 0
1066 * and increment the tabOrder of all other children.
1068 * @param child TWidget to add
1070 private void addChild(final TWidget child
) {
1071 children
.add(child
);
1074 && !(child
instanceof THScroller
)
1075 && !(child
instanceof TVScroller
)
1077 for (TWidget widget
: children
) {
1078 widget
.active
= false;
1080 child
.active
= true;
1081 activeChild
= child
;
1083 for (int i
= 0; i
< children
.size(); i
++) {
1084 children
.get(i
).tabOrder
= i
;
1089 * Switch the active child.
1091 * @param child TWidget to activate
1093 public final void activate(final TWidget child
) {
1094 assert (child
.enabled
);
1095 if ((child
instanceof THScroller
)
1096 || (child
instanceof TVScroller
)
1101 if (child
!= activeChild
) {
1102 if (activeChild
!= null) {
1103 activeChild
.active
= false;
1105 child
.active
= true;
1106 activeChild
= child
;
1111 * Switch the active child.
1113 * @param tabOrder tabOrder of the child to activate. If that child
1114 * isn't enabled, then the next enabled child will be activated.
1116 public final void activate(final int tabOrder
) {
1117 if (activeChild
== null) {
1120 TWidget child
= null;
1121 for (TWidget widget
: children
) {
1122 if ((widget
.enabled
)
1123 && !(widget
instanceof THScroller
)
1124 && !(widget
instanceof TVScroller
)
1125 && (widget
.tabOrder
>= tabOrder
)
1131 if ((child
!= null) && (child
!= activeChild
)) {
1132 activeChild
.active
= false;
1133 assert (child
.enabled
);
1134 child
.active
= true;
1135 activeChild
= child
;
1140 * Switch the active widget with the next in the tab order.
1142 * @param forward if true, then switch to the next enabled widget in the
1143 * list, otherwise switch to the previous enabled widget in the list
1145 public final void switchWidget(final boolean forward
) {
1147 // Only switch if there are multiple enabled widgets
1148 if ((children
.size() < 2) || (activeChild
== null)) {
1152 int tabOrder
= activeChild
.tabOrder
;
1161 // If at the end, pass the switch to my parent.
1162 if ((!forward
) && (parent
!= this)) {
1163 parent
.switchWidget(forward
);
1167 tabOrder
= children
.size() - 1;
1168 } else if (tabOrder
== children
.size()) {
1169 // If at the end, pass the switch to my parent.
1170 if ((forward
) && (parent
!= this)) {
1171 parent
.switchWidget(forward
);
1177 if (activeChild
.tabOrder
== tabOrder
) {
1178 // We wrapped around
1181 } while ((!children
.get(tabOrder
).enabled
)
1182 && !(children
.get(tabOrder
) instanceof THScroller
)
1183 && !(children
.get(tabOrder
) instanceof TVScroller
));
1185 assert (children
.get(tabOrder
).enabled
);
1187 activeChild
.active
= false;
1188 children
.get(tabOrder
).active
= true;
1189 activeChild
= children
.get(tabOrder
);
1193 * Returns my active widget.
1195 * @return widget that is active, or this if no children
1197 public TWidget
getActiveChild() {
1198 if ((this instanceof THScroller
)
1199 || (this instanceof TVScroller
)
1204 for (TWidget widget
: children
) {
1205 if (widget
.active
) {
1206 return widget
.getActiveChild();
1209 // No active children, return me
1213 // ------------------------------------------------------------------------
1214 // Passthru for Screen functions ------------------------------------------
1215 // ------------------------------------------------------------------------
1218 * Get the attributes at one location.
1220 * @param x column coordinate. 0 is the left-most column.
1221 * @param y row coordinate. 0 is the top-most row.
1222 * @return attributes at (x, y)
1224 protected final CellAttributes
getAttrXY(final int x
, final int y
) {
1225 return getScreen().getAttrXY(x
, y
);
1229 * Set the attributes at one location.
1231 * @param x column coordinate. 0 is the left-most column.
1232 * @param y row coordinate. 0 is the top-most row.
1233 * @param attr attributes to use (bold, foreColor, backColor)
1235 protected final void putAttrXY(final int x
, final int y
,
1236 final CellAttributes attr
) {
1238 getScreen().putAttrXY(x
, y
, attr
);
1242 * Set the attributes at one location.
1244 * @param x column coordinate. 0 is the left-most column.
1245 * @param y row coordinate. 0 is the top-most row.
1246 * @param attr attributes to use (bold, foreColor, backColor)
1247 * @param clip if true, honor clipping/offset
1249 protected final void putAttrXY(final int x
, final int y
,
1250 final CellAttributes attr
, final boolean clip
) {
1252 getScreen().putAttrXY(x
, y
, attr
, clip
);
1256 * Fill the entire screen with one character with attributes.
1258 * @param ch character to draw
1259 * @param attr attributes to use (bold, foreColor, backColor)
1261 protected final void putAll(final char ch
, final CellAttributes attr
) {
1262 getScreen().putAll(ch
, attr
);
1266 * Render one character with attributes.
1268 * @param x column coordinate. 0 is the left-most column.
1269 * @param y row coordinate. 0 is the top-most row.
1270 * @param ch character + attributes to draw
1272 protected final void putCharXY(final int x
, final int y
, final Cell ch
) {
1273 getScreen().putCharXY(x
, y
, ch
);
1277 * Render one character with attributes.
1279 * @param x column coordinate. 0 is the left-most column.
1280 * @param y row coordinate. 0 is the top-most row.
1281 * @param ch character to draw
1282 * @param attr attributes to use (bold, foreColor, backColor)
1284 protected final void putCharXY(final int x
, final int y
, final char ch
,
1285 final CellAttributes attr
) {
1287 getScreen().putCharXY(x
, y
, ch
, attr
);
1291 * Render one character without changing the underlying attributes.
1293 * @param x column coordinate. 0 is the left-most column.
1294 * @param y row coordinate. 0 is the top-most row.
1295 * @param ch character to draw
1297 protected final void putCharXY(final int x
, final int y
, final char ch
) {
1298 getScreen().putCharXY(x
, y
, ch
);
1302 * Render a string. Does not wrap if the string exceeds the line.
1304 * @param x column coordinate. 0 is the left-most column.
1305 * @param y row coordinate. 0 is the top-most row.
1306 * @param str string to draw
1307 * @param attr attributes to use (bold, foreColor, backColor)
1309 protected final void putStringXY(final int x
, final int y
, final String str
,
1310 final CellAttributes attr
) {
1312 getScreen().putStringXY(x
, y
, str
, attr
);
1316 * Render a string without changing the underlying attribute. Does not
1317 * wrap if the string exceeds the line.
1319 * @param x column coordinate. 0 is the left-most column.
1320 * @param y row coordinate. 0 is the top-most row.
1321 * @param str string to draw
1323 protected final void putStringXY(final int x
, final int y
, final String str
) {
1324 getScreen().putStringXY(x
, y
, str
);
1328 * Draw a vertical line from (x, y) to (x, y + n).
1330 * @param x column coordinate. 0 is the left-most column.
1331 * @param y row coordinate. 0 is the top-most row.
1332 * @param n number of characters to draw
1333 * @param ch character to draw
1334 * @param attr attributes to use (bold, foreColor, backColor)
1336 protected final void vLineXY(final int x
, final int y
, final int n
,
1337 final char ch
, final CellAttributes attr
) {
1339 getScreen().vLineXY(x
, y
, n
, ch
, attr
);
1343 * Draw a horizontal line from (x, y) to (x + n, y).
1345 * @param x column coordinate. 0 is the left-most column.
1346 * @param y row coordinate. 0 is the top-most row.
1347 * @param n number of characters to draw
1348 * @param ch character to draw
1349 * @param attr attributes to use (bold, foreColor, backColor)
1351 protected final void hLineXY(final int x
, final int y
, final int n
,
1352 final char ch
, final CellAttributes attr
) {
1354 getScreen().hLineXY(x
, y
, n
, ch
, attr
);
1358 * Draw a box with a border and empty background.
1360 * @param left left column of box. 0 is the left-most row.
1361 * @param top top row of the box. 0 is the top-most row.
1362 * @param right right column of box
1363 * @param bottom bottom row of the box
1364 * @param border attributes to use for the border
1365 * @param background attributes to use for the background
1367 protected final void drawBox(final int left
, final int top
,
1368 final int right
, final int bottom
,
1369 final CellAttributes border
, final CellAttributes background
) {
1371 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
);
1375 * Draw a box with a border and empty background.
1377 * @param left left column of box. 0 is the left-most row.
1378 * @param top top row of the box. 0 is the top-most row.
1379 * @param right right column of box
1380 * @param bottom bottom row of the box
1381 * @param border attributes to use for the border
1382 * @param background attributes to use for the background
1383 * @param borderType if 1, draw a single-line border; if 2, draw a
1384 * double-line border; if 3, draw double-line top/bottom edges and
1385 * single-line left/right edges (like Qmodem)
1386 * @param shadow if true, draw a "shadow" on the box
1388 protected final void drawBox(final int left
, final int top
,
1389 final int right
, final int bottom
,
1390 final CellAttributes border
, final CellAttributes background
,
1391 final int borderType
, final boolean shadow
) {
1393 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
,
1394 borderType
, shadow
);
1398 * Draw a box shadow.
1400 * @param left left column of box. 0 is the left-most row.
1401 * @param top top row of the box. 0 is the top-most row.
1402 * @param right right column of box
1403 * @param bottom bottom row of the box
1405 protected final void drawBoxShadow(final int left
, final int top
,
1406 final int right
, final int bottom
) {
1408 getScreen().drawBoxShadow(left
, top
, right
, bottom
);
1411 // ------------------------------------------------------------------------
1412 // Other TWidget constructors ---------------------------------------------
1413 // ------------------------------------------------------------------------
1416 * Convenience function to add a label to this container/window.
1419 * @param x column relative to parent
1420 * @param y row relative to parent
1421 * @return the new label
1423 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1424 return addLabel(text
, x
, y
, "tlabel");
1428 * Convenience function to add a label to this container/window.
1431 * @param x column relative to parent
1432 * @param y row relative to parent
1433 * @param colorKey ColorTheme key color to use for foreground text.
1434 * Default is "tlabel"
1435 * @return the new label
1437 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1438 final String colorKey
) {
1440 return new TLabel(this, text
, x
, y
, colorKey
);
1444 * Convenience function to add a label to this container/window.
1447 * @param x column relative to parent
1448 * @param y row relative to parent
1449 * @param colorKey ColorTheme key color to use for foreground text.
1450 * Default is "tlabel"
1451 * @param useWindowBackground if true, use the window's background color
1452 * @return the new label
1454 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1455 final String colorKey
, final boolean useWindowBackground
) {
1457 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
);
1461 * Convenience function to add a button to this container/window.
1463 * @param text label on the button
1464 * @param x column relative to parent
1465 * @param y row relative to parent
1466 * @param action action to call when button is pressed
1467 * @return the new button
1469 public final TButton
addButton(final String text
, final int x
, final int y
,
1470 final TAction action
) {
1472 return new TButton(this, text
, x
, y
, action
);
1476 * Convenience function to add a checkbox to this container/window.
1478 * @param x column relative to parent
1479 * @param y row relative to parent
1480 * @param label label to display next to (right of) the checkbox
1481 * @param checked initial check state
1482 * @return the new checkbox
1484 public final TCheckBox
addCheckBox(final int x
, final int y
,
1485 final String label
, final boolean checked
) {
1487 return new TCheckBox(this, x
, y
, label
, checked
);
1491 * Convenience function to add a combobox to this container/window.
1493 * @param x column relative to parent
1494 * @param y row relative to parent
1495 * @param width visible combobox width, including the down-arrow
1496 * @param values the possible values for the box, shown in the drop-down
1497 * @param valuesIndex the initial index in values, or -1 for no default
1499 * @param valuesHeight the height of the values drop-down when it is
1501 * @param updateAction action to call when a new value is selected from
1502 * the list or enter is pressed in the edit field
1503 * @return the new combobox
1505 public final TComboBox
addComboBox(final int x
, final int y
,
1506 final int width
, final List
<String
> values
, final int valuesIndex
,
1507 final int valuesHeight
, final TAction updateAction
) {
1509 return new TComboBox(this, x
, y
, width
, values
, valuesIndex
,
1510 valuesHeight
, updateAction
);
1514 * Convenience function to add a spinner to this container/window.
1516 * @param x column relative to parent
1517 * @param y row relative to parent
1518 * @param upAction action to call when the up arrow is clicked or pressed
1519 * @param downAction action to call when the down arrow is clicked or
1521 * @return the new spinner
1523 public final TSpinner
addSpinner(final int x
, final int y
,
1524 final TAction upAction
, final TAction downAction
) {
1526 return new TSpinner(this, x
, y
, upAction
, downAction
);
1530 * Convenience function to add a calendar to this container/window.
1532 * @param x column relative to parent
1533 * @param y row relative to parent
1534 * @param updateAction action to call when the user changes the value of
1536 * @return the new calendar
1538 public final TCalendar
addCalendar(final int x
, final int y
,
1539 final TAction updateAction
) {
1541 return new TCalendar(this, x
, y
, updateAction
);
1545 * Convenience function to add a progress bar to this container/window.
1547 * @param x column relative to parent
1548 * @param y row relative to parent
1549 * @param width width of progress bar
1550 * @param value initial value of percent complete
1551 * @return the new progress bar
1553 public final TProgressBar
addProgressBar(final int x
, final int y
,
1554 final int width
, final int value
) {
1556 return new TProgressBar(this, x
, y
, width
, value
);
1560 * Convenience function to add a radio button group to this
1563 * @param x column relative to parent
1564 * @param y row relative to parent
1565 * @param label label to display on the group box
1566 * @return the new radio button group
1568 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1569 final String label
) {
1571 return new TRadioGroup(this, x
, y
, label
);
1575 * Convenience function to add a text field to this container/window.
1577 * @param x column relative to parent
1578 * @param y row relative to parent
1579 * @param width visible text width
1580 * @param fixed if true, the text cannot exceed the display width
1581 * @return the new text field
1583 public final TField
addField(final int x
, final int y
,
1584 final int width
, final boolean fixed
) {
1586 return new TField(this, x
, y
, width
, fixed
);
1590 * Convenience function to add a text field to this container/window.
1592 * @param x column relative to parent
1593 * @param y row relative to parent
1594 * @param width visible text width
1595 * @param fixed if true, the text cannot exceed the display width
1596 * @param text initial text, default is empty string
1597 * @return the new text field
1599 public final TField
addField(final int x
, final int y
,
1600 final int width
, final boolean fixed
, final String text
) {
1602 return new TField(this, x
, y
, width
, fixed
, text
);
1606 * Convenience function to add a text field to this container/window.
1608 * @param x column relative to parent
1609 * @param y row relative to parent
1610 * @param width visible text width
1611 * @param fixed if true, the text cannot exceed the display width
1612 * @param text initial text, default is empty string
1613 * @param enterAction function to call when enter key is pressed
1614 * @param updateAction function to call when the text is updated
1615 * @return the new text field
1617 public final TField
addField(final int x
, final int y
,
1618 final int width
, final boolean fixed
, final String text
,
1619 final TAction enterAction
, final TAction updateAction
) {
1621 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1626 * Convenience function to add a scrollable text box to this
1629 * @param text text on the screen
1630 * @param x column relative to parent
1631 * @param y row relative to parent
1632 * @param width width of text area
1633 * @param height height of text area
1634 * @param colorKey ColorTheme key color to use for foreground text
1635 * @return the new text box
1637 public final TText
addText(final String text
, final int x
,
1638 final int y
, final int width
, final int height
, final String colorKey
) {
1640 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1644 * Convenience function to add a scrollable text box to this
1647 * @param text text on the screen
1648 * @param x column relative to parent
1649 * @param y row relative to parent
1650 * @param width width of text area
1651 * @param height height of text area
1652 * @return the new text box
1654 public final TText
addText(final String text
, final int x
, final int y
,
1655 final int width
, final int height
) {
1657 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1661 * Convenience function to add an editable text area box to this
1664 * @param text text on the screen
1665 * @param x column relative to parent
1666 * @param y row relative to parent
1667 * @param width width of text area
1668 * @param height height of text area
1669 * @return the new text box
1671 public final TEditorWidget
addEditor(final String text
, final int x
,
1672 final int y
, final int width
, final int height
) {
1674 return new TEditorWidget(this, text
, x
, y
, width
, height
);
1678 * Convenience function to spawn a message box.
1680 * @param title window title, will be centered along the top border
1681 * @param caption message to display. Use embedded newlines to get a
1683 * @return the new message box
1685 public final TMessageBox
messageBox(final String title
,
1686 final String caption
) {
1688 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
1692 * Convenience function to spawn a message box.
1694 * @param title window title, will be centered along the top border
1695 * @param caption message to display. Use embedded newlines to get a
1697 * @param type one of the TMessageBox.Type constants. Default is
1699 * @return the new message box
1701 public final TMessageBox
messageBox(final String title
,
1702 final String caption
, final TMessageBox
.Type type
) {
1704 return getApplication().messageBox(title
, caption
, type
);
1708 * Convenience function to spawn an input box.
1710 * @param title window title, will be centered along the top border
1711 * @param caption message to display. Use embedded newlines to get a
1713 * @return the new input box
1715 public final TInputBox
inputBox(final String title
, final String caption
) {
1717 return getApplication().inputBox(title
, caption
);
1721 * Convenience function to spawn an input box.
1723 * @param title window title, will be centered along the top border
1724 * @param caption message to display. Use embedded newlines to get a
1726 * @param text initial text to seed the field with
1727 * @return the new input box
1729 public final TInputBox
inputBox(final String title
, final String caption
,
1730 final String text
) {
1732 return getApplication().inputBox(title
, caption
, text
);
1736 * Convenience function to add a password text field to this
1739 * @param x column relative to parent
1740 * @param y row relative to parent
1741 * @param width visible text width
1742 * @param fixed if true, the text cannot exceed the display width
1743 * @return the new text field
1745 public final TPasswordField
addPasswordField(final int x
, final int y
,
1746 final int width
, final boolean fixed
) {
1748 return new TPasswordField(this, x
, y
, width
, fixed
);
1752 * Convenience function to add a password text field to this
1755 * @param x column relative to parent
1756 * @param y row relative to parent
1757 * @param width visible text width
1758 * @param fixed if true, the text cannot exceed the display width
1759 * @param text initial text, default is empty string
1760 * @return the new text field
1762 public final TPasswordField
addPasswordField(final int x
, final int y
,
1763 final int width
, final boolean fixed
, final String text
) {
1765 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
1769 * Convenience function to add a password text field to this
1772 * @param x column relative to parent
1773 * @param y row relative to parent
1774 * @param width visible text width
1775 * @param fixed if true, the text cannot exceed the display width
1776 * @param text initial text, default is empty string
1777 * @param enterAction function to call when enter key is pressed
1778 * @param updateAction function to call when the text is updated
1779 * @return the new text field
1781 public final TPasswordField
addPasswordField(final int x
, final int y
,
1782 final int width
, final boolean fixed
, final String text
,
1783 final TAction enterAction
, final TAction updateAction
) {
1785 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
1790 * Convenience function to add a scrollable tree view to this
1793 * @param x column relative to parent
1794 * @param y row relative to parent
1795 * @param width width of tree view
1796 * @param height height of tree view
1797 * @return the new tree view
1799 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
1800 final int width
, final int height
) {
1802 return new TTreeViewWidget(this, x
, y
, width
, height
);
1806 * Convenience function to add a scrollable tree view to this
1809 * @param x column relative to parent
1810 * @param y row relative to parent
1811 * @param width width of tree view
1812 * @param height height of tree view
1813 * @param action action to perform when an item is selected
1814 * @return the new tree view
1816 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
1817 final int width
, final int height
, final TAction action
) {
1819 return new TTreeViewWidget(this, x
, y
, width
, height
, action
);
1823 * Convenience function to spawn a file open box.
1825 * @param path path of selected file
1826 * @return the result of the new file open box
1827 * @throws IOException if a java.io operation throws
1829 public final String
fileOpenBox(final String path
) throws IOException
{
1830 return getApplication().fileOpenBox(path
);
1834 * Convenience function to spawn a file save box.
1836 * @param path path of selected file
1837 * @return the result of the new file open box
1838 * @throws IOException if a java.io operation throws
1840 public final String
fileSaveBox(final String path
) throws IOException
{
1841 return getApplication().fileOpenBox(path
, TFileOpenBox
.Type
.SAVE
);
1845 * Convenience function to spawn a file open box.
1847 * @param path path of selected file
1848 * @param type one of the Type constants
1849 * @return the result of the new file open box
1850 * @throws IOException if a java.io operation throws
1852 public final String
fileOpenBox(final String path
,
1853 final TFileOpenBox
.Type type
) throws IOException
{
1855 return getApplication().fileOpenBox(path
, type
);
1859 * Convenience function to spawn a file open box.
1861 * @param path path of selected file
1862 * @param type one of the Type constants
1863 * @param filter a string that files must match to be displayed
1864 * @return the result of the new file open box
1865 * @throws IOException of a java.io operation throws
1867 public final String
fileOpenBox(final String path
,
1868 final TFileOpenBox
.Type type
, final String filter
) throws IOException
{
1870 ArrayList
<String
> filters
= new ArrayList
<String
>();
1871 filters
.add(filter
);
1873 return getApplication().fileOpenBox(path
, type
, filters
);
1877 * Convenience function to spawn a file open box.
1879 * @param path path of selected file
1880 * @param type one of the Type constants
1881 * @param filters a list of strings that files must match to be displayed
1882 * @return the result of the new file open box
1883 * @throws IOException of a java.io operation throws
1885 public final String
fileOpenBox(final String path
,
1886 final TFileOpenBox
.Type type
,
1887 final List
<String
> filters
) throws IOException
{
1889 return getApplication().fileOpenBox(path
, type
, filters
);
1893 * Convenience function to add a directory list to this container/window.
1895 * @param path directory path, must be a directory
1896 * @param x column relative to parent
1897 * @param y row relative to parent
1898 * @param width width of text area
1899 * @param height height of text area
1900 * @return the new directory list
1902 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1903 final int y
, final int width
, final int height
) {
1905 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
1909 * Convenience function to add a directory list to this container/window.
1911 * @param path directory path, must be a directory
1912 * @param x column relative to parent
1913 * @param y row relative to parent
1914 * @param width width of text area
1915 * @param height height of text area
1916 * @param action action to perform when an item is selected (enter or
1918 * @return the new directory list
1920 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1921 final int y
, final int width
, final int height
, final TAction action
) {
1923 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
1927 * Convenience function to add a directory list to this container/window.
1929 * @param path directory path, must be a directory
1930 * @param x column relative to parent
1931 * @param y row relative to parent
1932 * @param width width of text area
1933 * @param height height of text area
1934 * @param action action to perform when an item is selected (enter or
1936 * @param singleClickAction action to perform when an item is selected
1938 * @return the new directory list
1940 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1941 final int y
, final int width
, final int height
, final TAction action
,
1942 final TAction singleClickAction
) {
1944 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
1949 * Convenience function to add a directory list to this container/window.
1951 * @param path directory path, must be a directory
1952 * @param x column relative to parent
1953 * @param y row relative to parent
1954 * @param width width of text area
1955 * @param height height of text area
1956 * @param action action to perform when an item is selected (enter or
1958 * @param singleClickAction action to perform when an item is selected
1960 * @param filters a list of strings that files must match to be displayed
1961 * @return the new directory list
1963 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1964 final int y
, final int width
, final int height
, final TAction action
,
1965 final TAction singleClickAction
, final List
<String
> filters
) {
1967 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
1968 singleClickAction
, filters
);
1972 * Convenience function to add a list to this container/window.
1974 * @param strings list of strings to show
1975 * @param x column relative to parent
1976 * @param y row relative to parent
1977 * @param width width of text area
1978 * @param height height of text area
1979 * @return the new directory list
1981 public final TList
addList(final List
<String
> strings
, final int x
,
1982 final int y
, final int width
, final int height
) {
1984 return new TList(this, strings
, x
, y
, width
, height
, null);
1988 * Convenience function to add a list to this container/window.
1990 * @param strings list of strings to show
1991 * @param x column relative to parent
1992 * @param y row relative to parent
1993 * @param width width of text area
1994 * @param height height of text area
1995 * @param enterAction action to perform when an item is selected
1996 * @return the new directory list
1998 public final TList
addList(final List
<String
> strings
, final int x
,
1999 final int y
, final int width
, final int height
,
2000 final TAction enterAction
) {
2002 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
2006 * Convenience function to add a list to this container/window.
2008 * @param strings list of strings to show
2009 * @param x column relative to parent
2010 * @param y row relative to parent
2011 * @param width width of text area
2012 * @param height height of text area
2013 * @param enterAction action to perform when an item is selected
2014 * @param moveAction action to perform when the user navigates to a new
2015 * item with arrow/page keys
2016 * @return the new directory list
2018 public final TList
addList(final List
<String
> strings
, final int x
,
2019 final int y
, final int width
, final int height
,
2020 final TAction enterAction
, final TAction moveAction
) {
2022 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,