8833f8ff7d0668fb232222ef6fa032a232976be8
2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 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
.ColorTheme
;
37 import jexer
.event
.TCommandEvent
;
38 import jexer
.event
.TInputEvent
;
39 import jexer
.event
.TKeypressEvent
;
40 import jexer
.event
.TMenuEvent
;
41 import jexer
.event
.TMouseEvent
;
42 import jexer
.event
.TResizeEvent
;
43 import jexer
.menu
.TMenu
;
44 import static jexer
.TKeypress
.*;
47 * TWidget is the base class of all objects that can be drawn on screen or
48 * handle user input events.
50 public abstract class TWidget
implements Comparable
<TWidget
> {
52 // ------------------------------------------------------------------------
53 // Common widget attributes -----------------------------------------------
54 // ------------------------------------------------------------------------
57 * Every widget has a parent widget that it may be "contained" in. For
58 * example, a TWindow might contain several TTextFields, or a TComboBox
59 * may contain a TScrollBar.
61 private TWidget parent
= null;
66 * @return parent widget
68 public final TWidget
getParent() {
73 * Child widgets that this widget contains.
75 private List
<TWidget
> children
;
78 * Get the list of child widgets that this widget contains.
80 * @return the list of child widgets
82 public List
<TWidget
> getChildren() {
87 * The currently active child widget that will receive keypress events.
89 private TWidget activeChild
= null;
92 * If true, this widget will receive events.
94 private boolean active
= false;
99 * @return if true, this widget will receive events
101 public final boolean isActive() {
108 * @param active if true, this widget will receive events
110 public final void setActive(final boolean active
) {
111 this.active
= active
;
115 * The window that this widget draws to.
117 private TWindow window
= null;
120 * Get the window this widget is on.
124 public final TWindow
getWindow() {
129 * Absolute X position of the top-left corner.
136 * @return absolute X position of the top-left corner
138 public final int getX() {
145 * @param x absolute X position of the top-left corner
147 public final void setX(final int x
) {
152 * Absolute Y position of the top-left corner.
159 * @return absolute Y position of the top-left corner
161 public final int getY() {
168 * @param y absolute Y position of the top-left corner
170 public final void setY(final int y
) {
177 private int width
= 0;
182 * @return widget width
184 public final int getWidth() {
191 * @param width new widget width
193 public final void setWidth(final int width
) {
200 private int height
= 0;
205 * @return widget height
207 public final int getHeight() {
214 * @param height new widget height
216 public final void setHeight(final int height
) {
217 this.height
= height
;
221 * Change the dimensions.
223 * @param x absolute X position of the top-left corner
224 * @param y absolute Y position of the top-left corner
225 * @param width new widget width
226 * @param height new widget height
228 public final void setDimensions(final int x
, final int y
, final int width
,
238 * My tab order inside a window or containing widget.
240 private int tabOrder
= 0;
243 * If true, this widget can be tabbed to or receive events.
245 private boolean enabled
= true;
250 * @return if true, this widget can be tabbed to or receive events
252 public final boolean isEnabled() {
259 * @param enabled if true, this widget can be tabbed to or receive events
261 public final void setEnabled(final boolean enabled
) {
262 this.enabled
= enabled
;
265 // See if there are any active siblings to switch to
266 boolean foundSibling
= false;
267 if (parent
!= null) {
268 for (TWidget w
: parent
.children
) {
270 && !(this instanceof THScroller
)
271 && !(this instanceof TVScroller
)
279 parent
.activeChild
= null;
286 * If true, this widget has a cursor.
288 private boolean cursorVisible
= false;
291 * Set visible cursor flag.
293 * @param cursorVisible if true, this widget has a cursor
295 public final void setCursorVisible(final boolean cursorVisible
) {
296 this.cursorVisible
= cursorVisible
;
300 * See if this widget has a visible cursor.
302 * @return if true, this widget has a visible cursor
304 public final boolean isCursorVisible() {
305 // If cursor is out of my bounds, it is not visible.
306 if ((cursorX
>= width
)
308 || (cursorY
>= height
)
314 // If cursor is out of my window's bounds, it is not visible.
315 if ((getCursorAbsoluteX() >= window
.getAbsoluteX()
316 + window
.getWidth() - 1)
317 || (getCursorAbsoluteX() < 0)
318 || (getCursorAbsoluteY() >= window
.getAbsoluteY()
319 + window
.getHeight() - 1)
320 || (getCursorAbsoluteY() < 0)
324 return cursorVisible
;
328 * Cursor column position in relative coordinates.
330 private int cursorX
= 0;
333 * Get cursor X value.
335 * @return cursor column position in relative coordinates
337 public final int getCursorX() {
342 * Set cursor X value.
344 * @param cursorX column position in relative coordinates
346 public final void setCursorX(final int cursorX
) {
347 this.cursorX
= cursorX
;
351 * Cursor row position in relative coordinates.
353 private int cursorY
= 0;
356 * Get cursor Y value.
358 * @return cursor row position in relative coordinates
360 public final int getCursorY() {
365 * Set cursor Y value.
367 * @param cursorY row position in relative coordinates
369 public final void setCursorY(final int cursorY
) {
370 this.cursorY
= cursorY
;
373 // ------------------------------------------------------------------------
374 // TApplication integration -----------------------------------------------
375 // ------------------------------------------------------------------------
378 * Get this TWidget's parent TApplication.
380 * @return the parent TApplication
382 public TApplication
getApplication() {
383 return window
.getApplication();
391 public Screen
getScreen() {
392 return window
.getScreen();
396 * Comparison operator. For various subclasses it sorts on:
398 * <li>tabOrder for TWidgets</li>
399 * <li>z for TWindows</li>
400 * <li>text for TTreeItems</li>
403 * @param that another TWidget, TWindow, or TTreeItem instance
404 * @return difference between this.tabOrder and that.tabOrder, or
405 * difference between this.z and that.z, or String.compareTo(text)
407 public final int compareTo(final TWidget that
) {
408 if ((this instanceof TWindow
)
409 && (that
instanceof TWindow
)
411 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
413 if ((this instanceof TTreeItem
)
414 && (that
instanceof TTreeItem
)
416 return (((TTreeItem
) this).getText().compareTo(
417 ((TTreeItem
) that
).getText()));
419 return (this.tabOrder
- that
.tabOrder
);
423 * See if this widget should render with the active color.
425 * @return true if this widget is active and all of its parents are
428 public final boolean isAbsoluteActive() {
429 if (parent
== this) {
432 return (active
&& parent
.isAbsoluteActive());
436 * Returns the cursor X position.
438 * @return absolute screen column number for the cursor's X position
440 public final int getCursorAbsoluteX() {
441 assert (cursorVisible
);
442 return getAbsoluteX() + cursorX
;
446 * Returns the cursor Y position.
448 * @return absolute screen row number for the cursor's Y position
450 public final int getCursorAbsoluteY() {
451 assert (cursorVisible
);
452 return getAbsoluteY() + cursorY
;
456 * Compute my absolute X position as the sum of my X plus all my parent's
459 * @return absolute screen column number for my X position
461 public final int getAbsoluteX() {
462 assert (parent
!= null);
463 if (parent
== this) {
466 if ((parent
instanceof TWindow
)
467 && !(parent
instanceof TMenu
)
468 && !(parent
instanceof TDesktop
)
470 // Widgets on a TWindow have (0,0) as their top-left, but this is
471 // actually the TWindow's (1,1).
472 return parent
.getAbsoluteX() + x
+ 1;
474 return parent
.getAbsoluteX() + x
;
478 * Compute my absolute Y position as the sum of my Y plus all my parent's
481 * @return absolute screen row number for my Y position
483 public final int getAbsoluteY() {
484 assert (parent
!= null);
485 if (parent
== this) {
488 if ((parent
instanceof TWindow
)
489 && !(parent
instanceof TMenu
)
490 && !(parent
instanceof TDesktop
)
492 // Widgets on a TWindow have (0,0) as their top-left, but this is
493 // actually the TWindow's (1,1).
494 return parent
.getAbsoluteY() + y
+ 1;
496 return parent
.getAbsoluteY() + y
;
500 * Get the global color theme.
502 * @return the ColorTheme
504 public final ColorTheme
getTheme() {
505 return window
.getApplication().getTheme();
509 * Draw my specific widget. When called, the screen rectangle I draw
510 * into is already setup (offset and clipping).
513 // Default widget draws nothing.
517 * Called by parent to render to TWindow.
519 public final void drawChildren() {
520 // Set my clipping rectangle
521 assert (window
!= null);
522 assert (getScreen() != null);
523 Screen screen
= getScreen();
525 // Special case: TStatusBar is drawn by TApplication, not anything
527 if (this instanceof TStatusBar
) {
531 screen
.setClipRight(width
);
532 screen
.setClipBottom(height
);
534 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
535 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
536 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
537 absoluteRightEdge
-= 1;
539 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
540 absoluteBottomEdge
-= 1;
542 int myRightEdge
= getAbsoluteX() + width
;
543 int myBottomEdge
= getAbsoluteY() + height
;
544 if (getAbsoluteX() > absoluteRightEdge
) {
546 screen
.setClipRight(0);
547 } else if (myRightEdge
> absoluteRightEdge
) {
548 screen
.setClipRight(screen
.getClipRight()
549 - (myRightEdge
- absoluteRightEdge
));
551 if (getAbsoluteY() > absoluteBottomEdge
) {
553 screen
.setClipBottom(0);
554 } else if (myBottomEdge
> absoluteBottomEdge
) {
555 screen
.setClipBottom(screen
.getClipBottom()
556 - (myBottomEdge
- absoluteBottomEdge
));
560 screen
.setOffsetX(getAbsoluteX());
561 screen
.setOffsetY(getAbsoluteY());
566 // Continue down the chain
567 for (TWidget widget
: children
) {
568 widget
.drawChildren();
573 * Repaint the screen on the next update.
575 public void doRepaint() {
576 window
.getApplication().doRepaint();
579 // ------------------------------------------------------------------------
580 // Constructors -----------------------------------------------------------
581 // ------------------------------------------------------------------------
584 * Default constructor for subclasses.
586 protected TWidget() {
587 children
= new ArrayList
<TWidget
>();
591 * Protected constructor.
593 * @param parent parent widget
595 protected TWidget(final TWidget parent
) {
600 * Protected constructor.
602 * @param parent parent widget
603 * @param x column relative to parent
604 * @param y row relative to parent
605 * @param width width of widget
606 * @param height height of widget
608 protected TWidget(final TWidget parent
, final int x
, final int y
,
609 final int width
, final int height
) {
611 this(parent
, true, x
, y
, width
, height
);
615 * Protected constructor used by subclasses that are disabled by default.
617 * @param parent parent widget
618 * @param enabled if true assume enabled
620 protected TWidget(final TWidget parent
, final boolean enabled
) {
621 this.enabled
= enabled
;
622 this.parent
= parent
;
623 this.window
= parent
.window
;
624 children
= new ArrayList
<TWidget
>();
626 // Do not add TStatusBars, they are drawn by TApplication
627 if (this instanceof TStatusBar
) {
629 parent
.addChild(this);
634 * Protected constructor used by subclasses that are disabled by default.
636 * @param parent parent widget
637 * @param enabled if true assume enabled
638 * @param x column relative to parent
639 * @param y row relative to parent
640 * @param width width of widget
641 * @param height height of widget
643 protected TWidget(final TWidget parent
, final boolean enabled
,
644 final int x
, final int y
, final int width
, final int height
) {
646 this.enabled
= enabled
;
647 this.parent
= parent
;
648 this.window
= parent
.window
;
649 children
= new ArrayList
<TWidget
>();
651 // Do not add TStatusBars, they are drawn by TApplication
652 if (this instanceof TStatusBar
) {
654 parent
.addChild(this);
660 this.height
= height
;
664 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
666 * @param window the top-level window
667 * @param x column relative to parent
668 * @param y row relative to parent
669 * @param width width of window
670 * @param height height of window
672 protected final void setupForTWindow(final TWindow window
,
673 final int x
, final int y
, final int width
, final int height
) {
675 this.parent
= window
;
676 this.window
= window
;
680 this.height
= height
;
683 // ------------------------------------------------------------------------
684 // General behavior -------------------------------------------------------
685 // ------------------------------------------------------------------------
688 * Add a child widget to my list of children. We set its tabOrder to 0
689 * and increment the tabOrder of all other children.
691 * @param child TWidget to add
693 private void addChild(final TWidget child
) {
697 && !(child
instanceof THScroller
)
698 && !(child
instanceof TVScroller
)
700 for (TWidget widget
: children
) {
701 widget
.active
= false;
706 for (int i
= 0; i
< children
.size(); i
++) {
707 children
.get(i
).tabOrder
= i
;
712 * Switch the active child.
714 * @param child TWidget to activate
716 public final void activate(final TWidget child
) {
717 assert (child
.enabled
);
718 if ((child
instanceof THScroller
)
719 || (child
instanceof TVScroller
)
724 if (child
!= activeChild
) {
725 if (activeChild
!= null) {
726 activeChild
.active
= false;
734 * Switch the active child.
736 * @param tabOrder tabOrder of the child to activate. If that child
737 * isn't enabled, then the next enabled child will be activated.
739 public final void activate(final int tabOrder
) {
740 if (activeChild
== null) {
743 TWidget child
= null;
744 for (TWidget widget
: children
) {
746 && !(widget
instanceof THScroller
)
747 && !(widget
instanceof TVScroller
)
748 && (widget
.tabOrder
>= tabOrder
)
754 if ((child
!= null) && (child
!= activeChild
)) {
755 activeChild
.active
= false;
756 assert (child
.enabled
);
763 * Switch the active widget with the next in the tab order.
765 * @param forward if true, then switch to the next enabled widget in the
766 * list, otherwise switch to the previous enabled widget in the list
768 public final void switchWidget(final boolean forward
) {
770 // Only switch if there are multiple enabled widgets
771 if ((children
.size() < 2) || (activeChild
== null)) {
775 int tabOrder
= activeChild
.tabOrder
;
784 // If at the end, pass the switch to my parent.
785 if ((!forward
) && (parent
!= this)) {
786 parent
.switchWidget(forward
);
790 tabOrder
= children
.size() - 1;
791 } else if (tabOrder
== children
.size()) {
792 // If at the end, pass the switch to my parent.
793 if ((forward
) && (parent
!= this)) {
794 parent
.switchWidget(forward
);
800 if (activeChild
.tabOrder
== tabOrder
) {
804 } while ((!children
.get(tabOrder
).enabled
)
805 && !(children
.get(tabOrder
) instanceof THScroller
)
806 && !(children
.get(tabOrder
) instanceof TVScroller
));
808 assert (children
.get(tabOrder
).enabled
);
810 activeChild
.active
= false;
811 children
.get(tabOrder
).active
= true;
812 activeChild
= children
.get(tabOrder
);
816 * Returns my active widget.
818 * @return widget that is active, or this if no children
820 public TWidget
getActiveChild() {
821 if ((this instanceof THScroller
)
822 || (this instanceof TVScroller
)
827 for (TWidget widget
: children
) {
829 return widget
.getActiveChild();
832 // No active children, return me
836 // ------------------------------------------------------------------------
837 // Event handlers ---------------------------------------------------------
838 // ------------------------------------------------------------------------
841 * Check if a mouse press/release event coordinate is contained in this
844 * @param mouse a mouse-based event
845 * @return whether or not a mouse click would be sent to this widget
847 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
853 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
854 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
855 && (mouse
.getAbsoluteY() >= getAbsoluteY())
856 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
864 * Method that subclasses can override to handle keystrokes.
866 * @param keypress keystroke event
868 public void onKeypress(final TKeypressEvent keypress
) {
870 if ((children
.size() == 0)
871 || (this instanceof TTreeView
)
872 || (this instanceof TText
)
876 // tab / shift-tab - switch to next/previous widget
877 // right-arrow or down-arrow: same as tab
878 // left-arrow or up-arrow: same as shift-tab
879 if ((keypress
.equals(kbTab
))
880 || (keypress
.equals(kbRight
))
881 || (keypress
.equals(kbDown
))
883 parent
.switchWidget(true);
885 } else if ((keypress
.equals(kbShiftTab
))
886 || (keypress
.equals(kbBackTab
))
887 || (keypress
.equals(kbLeft
))
888 || (keypress
.equals(kbUp
))
890 parent
.switchWidget(false);
895 // If I have any buttons on me AND this is an Alt-key that matches
896 // its mnemonic, send it an Enter keystroke
897 for (TWidget widget
: children
) {
898 if (widget
instanceof TButton
) {
899 TButton button
= (TButton
) widget
;
900 if (button
.isEnabled()
901 && !keypress
.getKey().isFnKey()
902 && keypress
.getKey().isAlt()
903 && !keypress
.getKey().isCtrl()
904 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
905 == Character
.toLowerCase(keypress
.getKey().getChar()))
908 widget
.handleEvent(new TKeypressEvent(kbEnter
));
914 // Dispatch the keypress to an active widget
915 for (TWidget widget
: children
) {
917 widget
.handleEvent(keypress
);
924 * Method that subclasses can override to handle mouse button presses.
926 * @param mouse mouse button event
928 public void onMouseDown(final TMouseEvent mouse
) {
929 // Default: do nothing, pass to children instead
930 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
931 TWidget widget
= children
.get(i
);
932 if (widget
.mouseWouldHit(mouse
)) {
933 // Dispatch to this child, also activate it
936 // Set x and y relative to the child's coordinates
937 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
938 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
939 widget
.handleEvent(mouse
);
946 * Method that subclasses can override to handle mouse button releases.
948 * @param mouse mouse button event
950 public void onMouseUp(final TMouseEvent mouse
) {
951 // Default: do nothing, pass to children instead
952 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
953 TWidget widget
= children
.get(i
);
954 if (widget
.mouseWouldHit(mouse
)) {
955 // Dispatch to this child, also activate it
958 // Set x and y relative to the child's coordinates
959 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
960 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
961 widget
.handleEvent(mouse
);
968 * Method that subclasses can override to handle mouse movements.
970 * @param mouse mouse motion event
972 public void onMouseMotion(final TMouseEvent mouse
) {
973 // Default: do nothing, pass it on to ALL of my children. This way
974 // the children can see the mouse "leaving" their area.
975 for (TWidget widget
: children
) {
976 // Set x and y relative to the child's coordinates
977 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
978 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
979 widget
.handleEvent(mouse
);
984 * Method that subclasses can override to handle mouse button
987 * @param mouse mouse button event
989 public void onMouseDoubleClick(final TMouseEvent mouse
) {
990 // Default: do nothing, pass to children instead
991 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
992 TWidget widget
= children
.get(i
);
993 if (widget
.mouseWouldHit(mouse
)) {
994 // Dispatch to this child, also activate it
997 // Set x and y relative to the child's coordinates
998 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
999 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
1000 widget
.handleEvent(mouse
);
1007 * Method that subclasses can override to handle window/screen resize
1010 * @param resize resize event
1012 public void onResize(final TResizeEvent resize
) {
1013 // Default: change my width/height.
1014 if (resize
.getType() == TResizeEvent
.Type
.WIDGET
) {
1015 width
= resize
.getWidth();
1016 height
= resize
.getHeight();
1018 // Let children see the screen resize
1019 for (TWidget widget
: children
) {
1020 widget
.onResize(resize
);
1026 * Method that subclasses can override to handle posted command events.
1028 * @param command command event
1030 public void onCommand(final TCommandEvent command
) {
1031 // Default: do nothing, pass to children instead
1032 for (TWidget widget
: children
) {
1033 widget
.onCommand(command
);
1038 * Method that subclasses can override to handle menu or posted menu
1041 * @param menu menu event
1043 public void onMenu(final TMenuEvent menu
) {
1044 // Default: do nothing, pass to children instead
1045 for (TWidget widget
: children
) {
1046 widget
.onMenu(menu
);
1051 * Method that subclasses can override to do processing when the UI is
1052 * idle. Note that repainting is NOT assumed. To get a refresh after
1053 * onIdle, call doRepaint().
1055 public void onIdle() {
1056 // Default: do nothing, pass to children instead
1057 for (TWidget widget
: children
) {
1063 * Consume event. Subclasses that want to intercept all events in one go
1064 * can override this method.
1066 * @param event keyboard, mouse, resize, command, or menu event
1068 public void handleEvent(final TInputEvent event
) {
1069 // System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
1074 // System.err.println(" -- discard --");
1078 if (event
instanceof TKeypressEvent
) {
1079 onKeypress((TKeypressEvent
) event
);
1080 } else if (event
instanceof TMouseEvent
) {
1082 TMouseEvent mouse
= (TMouseEvent
) event
;
1084 switch (mouse
.getType()) {
1095 onMouseMotion(mouse
);
1098 case MOUSE_DOUBLE_CLICK
:
1099 onMouseDoubleClick(mouse
);
1103 throw new IllegalArgumentException("Invalid mouse event type: "
1106 } else if (event
instanceof TResizeEvent
) {
1107 onResize((TResizeEvent
) event
);
1108 } else if (event
instanceof TCommandEvent
) {
1109 onCommand((TCommandEvent
) event
);
1110 } else if (event
instanceof TMenuEvent
) {
1111 onMenu((TMenuEvent
) event
);
1118 // ------------------------------------------------------------------------
1119 // Other TWidget constructors ---------------------------------------------
1120 // ------------------------------------------------------------------------
1123 * Convenience function to add a label to this container/window.
1126 * @param x column relative to parent
1127 * @param y row relative to parent
1128 * @return the new label
1130 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1131 return addLabel(text
, x
, y
, "tlabel");
1135 * Convenience function to add a label to this container/window.
1138 * @param x column relative to parent
1139 * @param y row relative to parent
1140 * @param colorKey ColorTheme key color to use for foreground text.
1141 * Default is "tlabel"
1142 * @return the new label
1144 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1145 final String colorKey
) {
1147 return new TLabel(this, text
, x
, y
, colorKey
);
1151 * Convenience function to add a button to this container/window.
1153 * @param text label on the button
1154 * @param x column relative to parent
1155 * @param y row relative to parent
1156 * @param action to call when button is pressed
1157 * @return the new button
1159 public final TButton
addButton(final String text
, final int x
, final int y
,
1160 final TAction action
) {
1162 return new TButton(this, text
, x
, y
, action
);
1166 * Convenience function to add a checkbox to this container/window.
1168 * @param x column relative to parent
1169 * @param y row relative to parent
1170 * @param label label to display next to (right of) the checkbox
1171 * @param checked initial check state
1172 * @return the new checkbox
1174 public final TCheckbox
addCheckbox(final int x
, final int y
,
1175 final String label
, final boolean checked
) {
1177 return new TCheckbox(this, x
, y
, label
, checked
);
1181 * Convenience function to add a progress bar to this container/window.
1183 * @param x column relative to parent
1184 * @param y row relative to parent
1185 * @param width width of progress bar
1186 * @param value initial value of percent complete
1187 * @return the new progress bar
1189 public final TProgressBar
addProgressBar(final int x
, final int y
,
1190 final int width
, final int value
) {
1192 return new TProgressBar(this, x
, y
, width
, value
);
1196 * Convenience function to add a radio button group to this
1199 * @param x column relative to parent
1200 * @param y row relative to parent
1201 * @param label label to display on the group box
1202 * @return the new radio button group
1204 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1205 final String label
) {
1207 return new TRadioGroup(this, x
, y
, label
);
1211 * Convenience function to add a text field to this container/window.
1213 * @param x column relative to parent
1214 * @param y row relative to parent
1215 * @param width visible text width
1216 * @param fixed if true, the text cannot exceed the display width
1217 * @return the new text field
1219 public final TField
addField(final int x
, final int y
,
1220 final int width
, final boolean fixed
) {
1222 return new TField(this, x
, y
, width
, fixed
);
1226 * Convenience function to add a text field to this container/window.
1228 * @param x column relative to parent
1229 * @param y row relative to parent
1230 * @param width visible text width
1231 * @param fixed if true, the text cannot exceed the display width
1232 * @param text initial text, default is empty string
1233 * @return the new text field
1235 public final TField
addField(final int x
, final int y
,
1236 final int width
, final boolean fixed
, final String text
) {
1238 return new TField(this, x
, y
, width
, fixed
, text
);
1242 * Convenience function to add a text field to this container/window.
1244 * @param x column relative to parent
1245 * @param y row relative to parent
1246 * @param width visible text width
1247 * @param fixed if true, the text cannot exceed the display width
1248 * @param text initial text, default is empty string
1249 * @param enterAction function to call when enter key is pressed
1250 * @param updateAction function to call when the text is updated
1251 * @return the new text field
1253 public final TField
addField(final int x
, final int y
,
1254 final int width
, final boolean fixed
, final String text
,
1255 final TAction enterAction
, final TAction updateAction
) {
1257 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1262 * Convenience function to add a scrollable text box to this
1265 * @param text text on the screen
1266 * @param x column relative to parent
1267 * @param y row relative to parent
1268 * @param width width of text area
1269 * @param height height of text area
1270 * @param colorKey ColorTheme key color to use for foreground text
1271 * @return the new text box
1273 public final TText
addText(final String text
, final int x
,
1274 final int y
, final int width
, final int height
, final String colorKey
) {
1276 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1280 * Convenience function to add a scrollable text box to this
1283 * @param text text on the screen
1284 * @param x column relative to parent
1285 * @param y row relative to parent
1286 * @param width width of text area
1287 * @param height height of text area
1288 * @return the new text box
1290 public final TText
addText(final String text
, final int x
, final int y
,
1291 final int width
, final int height
) {
1293 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1297 * Convenience function to add an editable text area box to this
1300 * @param text text on the screen
1301 * @param x column relative to parent
1302 * @param y row relative to parent
1303 * @param width width of text area
1304 * @param height height of text area
1305 * @return the new text box
1307 public final TEditorWidget
addEditor(final String text
, final int x
,
1308 final int y
, final int width
, final int height
) {
1310 return new TEditorWidget(this, text
, x
, y
, width
, height
);
1314 * Convenience function to spawn a message box.
1316 * @param title window title, will be centered along the top border
1317 * @param caption message to display. Use embedded newlines to get a
1319 * @return the new message box
1321 public final TMessageBox
messageBox(final String title
,
1322 final String caption
) {
1324 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
1328 * Convenience function to spawn a message box.
1330 * @param title window title, will be centered along the top border
1331 * @param caption message to display. Use embedded newlines to get a
1333 * @param type one of the TMessageBox.Type constants. Default is
1335 * @return the new message box
1337 public final TMessageBox
messageBox(final String title
,
1338 final String caption
, final TMessageBox
.Type type
) {
1340 return getApplication().messageBox(title
, caption
, type
);
1344 * Convenience function to spawn an input box.
1346 * @param title window title, will be centered along the top border
1347 * @param caption message to display. Use embedded newlines to get a
1349 * @return the new input box
1351 public final TInputBox
inputBox(final String title
, final String caption
) {
1353 return getApplication().inputBox(title
, caption
);
1357 * Convenience function to spawn an input box.
1359 * @param title window title, will be centered along the top border
1360 * @param caption message to display. Use embedded newlines to get a
1362 * @param text initial text to seed the field with
1363 * @return the new input box
1365 public final TInputBox
inputBox(final String title
, final String caption
,
1366 final String text
) {
1368 return getApplication().inputBox(title
, caption
, text
);
1372 * Convenience function to add a password text field to this
1375 * @param x column relative to parent
1376 * @param y row relative to parent
1377 * @param width visible text width
1378 * @param fixed if true, the text cannot exceed the display width
1379 * @return the new text field
1381 public final TPasswordField
addPasswordField(final int x
, final int y
,
1382 final int width
, final boolean fixed
) {
1384 return new TPasswordField(this, x
, y
, width
, fixed
);
1388 * Convenience function to add a password text field to this
1391 * @param x column relative to parent
1392 * @param y row relative to parent
1393 * @param width visible text width
1394 * @param fixed if true, the text cannot exceed the display width
1395 * @param text initial text, default is empty string
1396 * @return the new text field
1398 public final TPasswordField
addPasswordField(final int x
, final int y
,
1399 final int width
, final boolean fixed
, final String text
) {
1401 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
1405 * Convenience function to add a password text field to this
1408 * @param x column relative to parent
1409 * @param y row relative to parent
1410 * @param width visible text width
1411 * @param fixed if true, the text cannot exceed the display width
1412 * @param text initial text, default is empty string
1413 * @param enterAction function to call when enter key is pressed
1414 * @param updateAction function to call when the text is updated
1415 * @return the new text field
1417 public final TPasswordField
addPasswordField(final int x
, final int y
,
1418 final int width
, final boolean fixed
, final String text
,
1419 final TAction enterAction
, final TAction updateAction
) {
1421 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
1426 * Convenience function to add a tree view to this container/window.
1428 * @param x column relative to parent
1429 * @param y row relative to parent
1430 * @param width width of tree view
1431 * @param height height of tree view
1432 * @return the new tree view
1434 public final TTreeView
addTreeView(final int x
, final int y
,
1435 final int width
, final int height
) {
1437 return new TTreeView(this, x
, y
, width
, height
);
1441 * Convenience function to add a tree view to this container/window.
1443 * @param x column relative to parent
1444 * @param y row relative to parent
1445 * @param width width of tree view
1446 * @param height height of tree view
1447 * @param action action to perform when an item is selected
1448 * @return the new tree view
1450 public final TTreeView
addTreeView(final int x
, final int y
,
1451 final int width
, final int height
, final TAction action
) {
1453 return new TTreeView(this, x
, y
, width
, height
, action
);
1457 * Convenience function to spawn a file open box.
1459 * @param path path of selected file
1460 * @return the result of the new file open box
1461 * @throws IOException if a java.io operation throws
1463 public final String
fileOpenBox(final String path
) throws IOException
{
1464 return getApplication().fileOpenBox(path
);
1468 * Convenience function to spawn a file open box.
1470 * @param path path of selected file
1471 * @param type one of the Type constants
1472 * @return the result of the new file open box
1473 * @throws IOException if a java.io operation throws
1475 public final String
fileOpenBox(final String path
,
1476 final TFileOpenBox
.Type type
) throws IOException
{
1478 return getApplication().fileOpenBox(path
, type
);
1481 * Convenience function to add a directory list to this container/window.
1483 * @param path directory path, must be a directory
1484 * @param x column relative to parent
1485 * @param y row relative to parent
1486 * @param width width of text area
1487 * @param height height of text area
1488 * @return the new directory list
1490 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1491 final int y
, final int width
, final int height
) {
1493 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
1497 * Convenience function to add a directory list to this container/window.
1499 * @param path directory path, must be a directory
1500 * @param x column relative to parent
1501 * @param y row relative to parent
1502 * @param width width of text area
1503 * @param height height of text area
1504 * @param action action to perform when an item is selected
1505 * @return the new directory list
1507 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1508 final int y
, final int width
, final int height
, final TAction action
) {
1510 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
1514 * Convenience function to add a directory list to this container/window.
1516 * @param strings list of strings to show
1517 * @param x column relative to parent
1518 * @param y row relative to parent
1519 * @param width width of text area
1520 * @param height height of text area
1521 * @return the new directory list
1523 public final TList
addList(final List
<String
> strings
, final int x
,
1524 final int y
, final int width
, final int height
) {
1526 return new TList(this, strings
, x
, y
, width
, height
, null);
1530 * Convenience function to add a directory list to this container/window.
1532 * @param strings list of strings to show
1533 * @param x column relative to parent
1534 * @param y row relative to parent
1535 * @param width width of text area
1536 * @param height height of text area
1537 * @param enterAction action to perform when an item is selected
1538 * @return the new directory list
1540 public final TList
addList(final List
<String
> strings
, final int x
,
1541 final int y
, final int width
, final int height
,
1542 final TAction enterAction
) {
1544 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
1548 * Convenience function to add a directory list to this container/window.
1550 * @param strings list of strings to show
1551 * @param x column relative to parent
1552 * @param y row relative to parent
1553 * @param width width of text area
1554 * @param height height of text area
1555 * @param enterAction action to perform when an item is selected
1556 * @param moveAction action to perform when the user navigates to a new
1557 * item with arrow/page keys
1558 * @return the new directory list
1560 public final TList
addList(final List
<String
> strings
, final int x
,
1561 final int y
, final int width
, final int height
,
1562 final TAction enterAction
, final TAction moveAction
) {
1564 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,