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
.bits
.ColorTheme
;
36 import jexer
.event
.TCommandEvent
;
37 import jexer
.event
.TInputEvent
;
38 import jexer
.event
.TKeypressEvent
;
39 import jexer
.event
.TMenuEvent
;
40 import jexer
.event
.TMouseEvent
;
41 import jexer
.event
.TResizeEvent
;
42 import jexer
.io
.Screen
;
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 return cursorVisible
;
309 * Cursor column position in relative coordinates.
311 private int cursorX
= 0;
314 * Get cursor X value.
316 * @return cursor column position in relative coordinates
318 public final int getCursorX() {
323 * Set cursor X value.
325 * @param cursorX column position in relative coordinates
327 public final void setCursorX(final int cursorX
) {
328 this.cursorX
= cursorX
;
332 * Cursor row position in relative coordinates.
334 private int cursorY
= 0;
337 * Get cursor Y value.
339 * @return cursor row position in relative coordinates
341 public final int getCursorY() {
346 * Set cursor Y value.
348 * @param cursorY row position in relative coordinates
350 public final void setCursorY(final int cursorY
) {
351 this.cursorY
= cursorY
;
354 // ------------------------------------------------------------------------
355 // TApplication integration -----------------------------------------------
356 // ------------------------------------------------------------------------
359 * Get this TWidget's parent TApplication.
361 * @return the parent TApplication
363 public TApplication
getApplication() {
364 return window
.getApplication();
372 public Screen
getScreen() {
373 return window
.getScreen();
377 * Comparison operator. For various subclasses it sorts on:
379 * <li>tabOrder for TWidgets</li>
380 * <li>z for TWindows</li>
381 * <li>text for TTreeItems</li>
384 * @param that another TWidget, TWindow, or TTreeItem instance
385 * @return difference between this.tabOrder and that.tabOrder, or
386 * difference between this.z and that.z, or String.compareTo(text)
388 public final int compareTo(final TWidget that
) {
389 if ((this instanceof TWindow
)
390 && (that
instanceof TWindow
)
392 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
394 if ((this instanceof TTreeItem
)
395 && (that
instanceof TTreeItem
)
397 return (((TTreeItem
) this).getText().compareTo(
398 ((TTreeItem
) that
).getText()));
400 return (this.tabOrder
- that
.tabOrder
);
404 * See if this widget should render with the active color.
406 * @return true if this widget is active and all of its parents are
409 public final boolean isAbsoluteActive() {
410 if (parent
== this) {
413 return (active
&& parent
.isAbsoluteActive());
417 * Returns the cursor X position.
419 * @return absolute screen column number for the cursor's X position
421 public final int getCursorAbsoluteX() {
422 assert (cursorVisible
);
423 return getAbsoluteX() + cursorX
;
427 * Returns the cursor Y position.
429 * @return absolute screen row number for the cursor's Y position
431 public final int getCursorAbsoluteY() {
432 assert (cursorVisible
);
433 return getAbsoluteY() + cursorY
;
437 * Compute my absolute X position as the sum of my X plus all my parent's
440 * @return absolute screen column number for my X position
442 public final int getAbsoluteX() {
443 assert (parent
!= null);
444 if (parent
== this) {
447 if ((parent
instanceof TWindow
)
448 && !(parent
instanceof TMenu
)
449 && !(parent
instanceof TDesktop
)
451 // Widgets on a TWindow have (0,0) as their top-left, but this is
452 // actually the TWindow's (1,1).
453 return parent
.getAbsoluteX() + x
+ 1;
455 return parent
.getAbsoluteX() + x
;
459 * Compute my absolute Y position as the sum of my Y plus all my parent's
462 * @return absolute screen row number for my Y position
464 public final int getAbsoluteY() {
465 assert (parent
!= null);
466 if (parent
== this) {
469 if ((parent
instanceof TWindow
)
470 && !(parent
instanceof TMenu
)
471 && !(parent
instanceof TDesktop
)
473 // Widgets on a TWindow have (0,0) as their top-left, but this is
474 // actually the TWindow's (1,1).
475 return parent
.getAbsoluteY() + y
+ 1;
477 return parent
.getAbsoluteY() + y
;
481 * Get the global color theme.
483 * @return the ColorTheme
485 public final ColorTheme
getTheme() {
486 return window
.getApplication().getTheme();
490 * Draw my specific widget. When called, the screen rectangle I draw
491 * into is already setup (offset and clipping).
494 // Default widget draws nothing.
498 * Called by parent to render to TWindow.
500 public final void drawChildren() {
501 // Set my clipping rectangle
502 assert (window
!= null);
503 assert (getScreen() != null);
504 Screen screen
= getScreen();
506 // Special case: TStatusBar is drawn by TApplication, not anything
508 if (this instanceof TStatusBar
) {
512 screen
.setClipRight(width
);
513 screen
.setClipBottom(height
);
515 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
516 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
517 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
518 absoluteRightEdge
-= 1;
520 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
521 absoluteBottomEdge
-= 1;
523 int myRightEdge
= getAbsoluteX() + width
;
524 int myBottomEdge
= getAbsoluteY() + height
;
525 if (getAbsoluteX() > absoluteRightEdge
) {
527 screen
.setClipRight(0);
528 } else if (myRightEdge
> absoluteRightEdge
) {
529 screen
.setClipRight(screen
.getClipRight()
530 - (myRightEdge
- absoluteRightEdge
));
532 if (getAbsoluteY() > absoluteBottomEdge
) {
534 screen
.setClipBottom(0);
535 } else if (myBottomEdge
> absoluteBottomEdge
) {
536 screen
.setClipBottom(screen
.getClipBottom()
537 - (myBottomEdge
- absoluteBottomEdge
));
541 screen
.setOffsetX(getAbsoluteX());
542 screen
.setOffsetY(getAbsoluteY());
547 // Continue down the chain
548 for (TWidget widget
: children
) {
549 widget
.drawChildren();
553 // ------------------------------------------------------------------------
554 // Constructors -----------------------------------------------------------
555 // ------------------------------------------------------------------------
558 * Default constructor for subclasses.
560 protected TWidget() {
561 children
= new ArrayList
<TWidget
>();
565 * Protected constructor.
567 * @param parent parent widget
569 protected TWidget(final TWidget parent
) {
574 * Protected constructor.
576 * @param parent parent widget
577 * @param x column relative to parent
578 * @param y row relative to parent
579 * @param width width of widget
580 * @param height height of widget
582 protected TWidget(final TWidget parent
, final int x
, final int y
,
583 final int width
, final int height
) {
585 this(parent
, true, x
, y
, width
, height
);
589 * Protected constructor used by subclasses that are disabled by default.
591 * @param parent parent widget
592 * @param enabled if true assume enabled
594 protected TWidget(final TWidget parent
, final boolean enabled
) {
595 this.enabled
= enabled
;
596 this.parent
= parent
;
597 this.window
= parent
.window
;
598 children
= new ArrayList
<TWidget
>();
599 parent
.addChild(this);
603 * Protected constructor used by subclasses that are disabled by default.
605 * @param parent parent widget
606 * @param enabled if true assume enabled
607 * @param x column relative to parent
608 * @param y row relative to parent
609 * @param width width of widget
610 * @param height height of widget
612 protected TWidget(final TWidget parent
, final boolean enabled
,
613 final int x
, final int y
, final int width
, final int height
) {
615 this.enabled
= enabled
;
616 this.parent
= parent
;
617 this.window
= parent
.window
;
618 children
= new ArrayList
<TWidget
>();
619 parent
.addChild(this);
624 this.height
= height
;
628 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
630 * @param window the top-level window
631 * @param x column relative to parent
632 * @param y row relative to parent
633 * @param width width of window
634 * @param height height of window
636 protected final void setupForTWindow(final TWindow window
,
637 final int x
, final int y
, final int width
, final int height
) {
639 this.parent
= window
;
640 this.window
= window
;
644 this.height
= height
;
647 // ------------------------------------------------------------------------
648 // General behavior -------------------------------------------------------
649 // ------------------------------------------------------------------------
652 * Add a child widget to my list of children. We set its tabOrder to 0
653 * and increment the tabOrder of all other children.
655 * @param child TWidget to add
657 private void addChild(final TWidget child
) {
661 && !(child
instanceof THScroller
)
662 && !(child
instanceof TVScroller
)
664 for (TWidget widget
: children
) {
665 widget
.active
= false;
670 for (int i
= 0; i
< children
.size(); i
++) {
671 children
.get(i
).tabOrder
= i
;
676 * Switch the active child.
678 * @param child TWidget to activate
680 public final void activate(final TWidget child
) {
681 assert (child
.enabled
);
682 if ((child
instanceof THScroller
)
683 || (child
instanceof TVScroller
)
688 if (child
!= activeChild
) {
689 if (activeChild
!= null) {
690 activeChild
.active
= false;
698 * Switch the active child.
700 * @param tabOrder tabOrder of the child to activate. If that child
701 * isn't enabled, then the next enabled child will be activated.
703 public final void activate(final int tabOrder
) {
704 if (activeChild
== null) {
707 TWidget child
= null;
708 for (TWidget widget
: children
) {
710 && !(widget
instanceof THScroller
)
711 && !(widget
instanceof TVScroller
)
712 && (widget
.tabOrder
>= tabOrder
)
718 if ((child
!= null) && (child
!= activeChild
)) {
719 activeChild
.active
= false;
720 assert (child
.enabled
);
727 * Switch the active widget with the next in the tab order.
729 * @param forward if true, then switch to the next enabled widget in the
730 * list, otherwise switch to the previous enabled widget in the list
732 public final void switchWidget(final boolean forward
) {
734 // Only switch if there are multiple enabled widgets
735 if ((children
.size() < 2) || (activeChild
== null)) {
739 int tabOrder
= activeChild
.tabOrder
;
748 // If at the end, pass the switch to my parent.
749 if ((!forward
) && (parent
!= this)) {
750 parent
.switchWidget(forward
);
754 tabOrder
= children
.size() - 1;
755 } else if (tabOrder
== children
.size()) {
756 // If at the end, pass the switch to my parent.
757 if ((forward
) && (parent
!= this)) {
758 parent
.switchWidget(forward
);
764 if (activeChild
.tabOrder
== tabOrder
) {
768 } while ((!children
.get(tabOrder
).enabled
)
769 && !(children
.get(tabOrder
) instanceof THScroller
)
770 && !(children
.get(tabOrder
) instanceof TVScroller
));
772 assert (children
.get(tabOrder
).enabled
);
774 activeChild
.active
= false;
775 children
.get(tabOrder
).active
= true;
776 activeChild
= children
.get(tabOrder
);
780 * Returns my active widget.
782 * @return widget that is active, or this if no children
784 public TWidget
getActiveChild() {
785 if ((this instanceof THScroller
)
786 || (this instanceof TVScroller
)
791 for (TWidget widget
: children
) {
793 return widget
.getActiveChild();
796 // No active children, return me
800 // ------------------------------------------------------------------------
801 // Event handlers ---------------------------------------------------------
802 // ------------------------------------------------------------------------
805 * Check if a mouse press/release event coordinate is contained in this
808 * @param mouse a mouse-based event
809 * @return whether or not a mouse click would be sent to this widget
811 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
817 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
818 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
819 && (mouse
.getAbsoluteY() >= getAbsoluteY())
820 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
828 * Method that subclasses can override to handle keystrokes.
830 * @param keypress keystroke event
832 public void onKeypress(final TKeypressEvent keypress
) {
834 if ((children
.size() == 0)
835 || (this instanceof TTreeView
)
836 || (this instanceof TText
)
840 // tab / shift-tab - switch to next/previous widget
841 // right-arrow or down-arrow: same as tab
842 // left-arrow or up-arrow: same as shift-tab
843 if ((keypress
.equals(kbTab
))
844 || (keypress
.equals(kbRight
))
845 || (keypress
.equals(kbDown
))
847 parent
.switchWidget(true);
849 } else if ((keypress
.equals(kbShiftTab
))
850 || (keypress
.equals(kbBackTab
))
851 || (keypress
.equals(kbLeft
))
852 || (keypress
.equals(kbUp
))
854 parent
.switchWidget(false);
859 // If I have any buttons on me AND this is an Alt-key that matches
860 // its mnemonic, send it an Enter keystroke
861 for (TWidget widget
: children
) {
862 if (widget
instanceof TButton
) {
863 TButton button
= (TButton
) widget
;
864 if (button
.isEnabled()
865 && !keypress
.getKey().isFnKey()
866 && keypress
.getKey().isAlt()
867 && !keypress
.getKey().isCtrl()
868 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
869 == Character
.toLowerCase(keypress
.getKey().getChar()))
872 widget
.handleEvent(new TKeypressEvent(kbEnter
));
878 // Dispatch the keypress to an active widget
879 for (TWidget widget
: children
) {
881 widget
.handleEvent(keypress
);
888 * Method that subclasses can override to handle mouse button presses.
890 * @param mouse mouse button event
892 public void onMouseDown(final TMouseEvent mouse
) {
893 // Default: do nothing, pass to children instead
894 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
895 TWidget widget
= children
.get(i
);
896 if (widget
.mouseWouldHit(mouse
)) {
897 // Dispatch to this child, also activate it
900 // Set x and y relative to the child's coordinates
901 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
902 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
903 widget
.handleEvent(mouse
);
910 * Method that subclasses can override to handle mouse button releases.
912 * @param mouse mouse button event
914 public void onMouseUp(final TMouseEvent mouse
) {
915 // Default: do nothing, pass to children instead
916 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
917 TWidget widget
= children
.get(i
);
918 if (widget
.mouseWouldHit(mouse
)) {
919 // Dispatch to this child, also activate it
922 // Set x and y relative to the child's coordinates
923 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
924 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
925 widget
.handleEvent(mouse
);
932 * Method that subclasses can override to handle mouse movements.
934 * @param mouse mouse motion event
936 public void onMouseMotion(final TMouseEvent mouse
) {
937 // Default: do nothing, pass it on to ALL of my children. This way
938 // the children can see the mouse "leaving" their area.
939 for (TWidget widget
: children
) {
940 // Set x and y relative to the child's coordinates
941 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
942 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
943 widget
.handleEvent(mouse
);
948 * Method that subclasses can override to handle window/screen resize
951 * @param resize resize event
953 public void onResize(final TResizeEvent resize
) {
954 // Default: do nothing, pass to children instead
955 for (TWidget widget
: children
) {
956 widget
.onResize(resize
);
961 * Method that subclasses can override to handle posted command events.
963 * @param command command event
965 public void onCommand(final TCommandEvent command
) {
966 // Default: do nothing, pass to children instead
967 for (TWidget widget
: children
) {
968 widget
.onCommand(command
);
973 * Method that subclasses can override to handle menu or posted menu
976 * @param menu menu event
978 public void onMenu(final TMenuEvent menu
) {
979 // Default: do nothing, pass to children instead
980 for (TWidget widget
: children
) {
986 * Method that subclasses can override to do processing when the UI is
989 public void onIdle() {
990 // Default: do nothing, pass to children instead
991 for (TWidget widget
: children
) {
997 * Consume event. Subclasses that want to intercept all events in one go
998 * can override this method.
1000 * @param event keyboard, mouse, resize, command, or menu event
1002 public void handleEvent(final TInputEvent event
) {
1003 // System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
1008 // System.err.println(" -- discard --");
1012 if (event
instanceof TKeypressEvent
) {
1013 onKeypress((TKeypressEvent
) event
);
1014 } else if (event
instanceof TMouseEvent
) {
1016 TMouseEvent mouse
= (TMouseEvent
) event
;
1018 switch (mouse
.getType()) {
1029 onMouseMotion(mouse
);
1033 throw new IllegalArgumentException("Invalid mouse event type: "
1036 } else if (event
instanceof TResizeEvent
) {
1037 onResize((TResizeEvent
) event
);
1038 } else if (event
instanceof TCommandEvent
) {
1039 onCommand((TCommandEvent
) event
);
1040 } else if (event
instanceof TMenuEvent
) {
1041 onMenu((TMenuEvent
) event
);
1048 // ------------------------------------------------------------------------
1049 // Other TWidget constructors ---------------------------------------------
1050 // ------------------------------------------------------------------------
1053 * Convenience function to add a label to this container/window.
1056 * @param x column relative to parent
1057 * @param y row relative to parent
1058 * @return the new label
1060 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1061 return addLabel(text
, x
, y
, "tlabel");
1065 * Convenience function to add a label to this container/window.
1068 * @param x column relative to parent
1069 * @param y row relative to parent
1070 * @param colorKey ColorTheme key color to use for foreground text.
1071 * Default is "tlabel"
1072 * @return the new label
1074 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1075 final String colorKey
) {
1077 return new TLabel(this, text
, x
, y
, colorKey
);
1081 * Convenience function to add a button to this container/window.
1083 * @param text label on the button
1084 * @param x column relative to parent
1085 * @param y row relative to parent
1086 * @param action to call when button is pressed
1087 * @return the new button
1089 public final TButton
addButton(final String text
, final int x
, final int y
,
1090 final TAction action
) {
1092 return new TButton(this, text
, x
, y
, action
);
1096 * Convenience function to add a checkbox to this container/window.
1098 * @param x column relative to parent
1099 * @param y row relative to parent
1100 * @param label label to display next to (right of) the checkbox
1101 * @param checked initial check state
1102 * @return the new checkbox
1104 public final TCheckbox
addCheckbox(final int x
, final int y
,
1105 final String label
, final boolean checked
) {
1107 return new TCheckbox(this, x
, y
, label
, checked
);
1111 * Convenience function to add a progress bar to this container/window.
1113 * @param x column relative to parent
1114 * @param y row relative to parent
1115 * @param width width of progress bar
1116 * @param value initial value of percent complete
1117 * @return the new progress bar
1119 public final TProgressBar
addProgressBar(final int x
, final int y
,
1120 final int width
, final int value
) {
1122 return new TProgressBar(this, x
, y
, width
, value
);
1126 * Convenience function to add a radio button group to this
1129 * @param x column relative to parent
1130 * @param y row relative to parent
1131 * @param label label to display on the group box
1132 * @return the new radio button group
1134 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1135 final String label
) {
1137 return new TRadioGroup(this, x
, y
, label
);
1141 * Convenience function to add a text field to this container/window.
1143 * @param x column relative to parent
1144 * @param y row relative to parent
1145 * @param width visible text width
1146 * @param fixed if true, the text cannot exceed the display width
1147 * @return the new text field
1149 public final TField
addField(final int x
, final int y
,
1150 final int width
, final boolean fixed
) {
1152 return new TField(this, x
, y
, width
, fixed
);
1156 * Convenience function to add a text field to this container/window.
1158 * @param x column relative to parent
1159 * @param y row relative to parent
1160 * @param width visible text width
1161 * @param fixed if true, the text cannot exceed the display width
1162 * @param text initial text, default is empty string
1163 * @return the new text field
1165 public final TField
addField(final int x
, final int y
,
1166 final int width
, final boolean fixed
, final String text
) {
1168 return new TField(this, x
, y
, width
, fixed
, text
);
1172 * Convenience function to add a text field to this container/window.
1174 * @param x column relative to parent
1175 * @param y row relative to parent
1176 * @param width visible text width
1177 * @param fixed if true, the text cannot exceed the display width
1178 * @param text initial text, default is empty string
1179 * @param enterAction function to call when enter key is pressed
1180 * @param updateAction function to call when the text is updated
1181 * @return the new text field
1183 public final TField
addField(final int x
, final int y
,
1184 final int width
, final boolean fixed
, final String text
,
1185 final TAction enterAction
, final TAction updateAction
) {
1187 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1192 * Convenience function to add a scrollable text box to this
1195 * @param text text on the screen
1196 * @param x column relative to parent
1197 * @param y row relative to parent
1198 * @param width width of text area
1199 * @param height height of text area
1200 * @param colorKey ColorTheme key color to use for foreground text
1201 * @return the new text box
1203 public final TText
addText(final String text
, final int x
,
1204 final int y
, final int width
, final int height
, final String colorKey
) {
1206 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1210 * Convenience function to add a scrollable text box to this
1213 * @param text text on the screen
1214 * @param x column relative to parent
1215 * @param y row relative to parent
1216 * @param width width of text area
1217 * @param height height of text area
1218 * @return the new text box
1220 public final TText
addText(final String text
, final int x
, final int y
,
1221 final int width
, final int height
) {
1223 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1227 * Convenience function to spawn a message box.
1229 * @param title window title, will be centered along the top border
1230 * @param caption message to display. Use embedded newlines to get a
1232 * @return the new message box
1234 public final TMessageBox
messageBox(final String title
,
1235 final String caption
) {
1237 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
1241 * Convenience function to spawn a message box.
1243 * @param title window title, will be centered along the top border
1244 * @param caption message to display. Use embedded newlines to get a
1246 * @param type one of the TMessageBox.Type constants. Default is
1248 * @return the new message box
1250 public final TMessageBox
messageBox(final String title
,
1251 final String caption
, final TMessageBox
.Type type
) {
1253 return getApplication().messageBox(title
, caption
, type
);
1257 * Convenience function to spawn an input box.
1259 * @param title window title, will be centered along the top border
1260 * @param caption message to display. Use embedded newlines to get a
1262 * @return the new input box
1264 public final TInputBox
inputBox(final String title
, final String caption
) {
1266 return getApplication().inputBox(title
, caption
);
1270 * Convenience function to spawn an input box.
1272 * @param title window title, will be centered along the top border
1273 * @param caption message to display. Use embedded newlines to get a
1275 * @param text initial text to seed the field with
1276 * @return the new input box
1278 public final TInputBox
inputBox(final String title
, final String caption
,
1279 final String text
) {
1281 return getApplication().inputBox(title
, caption
, text
);
1285 * Convenience function to add a password text field to this
1288 * @param x column relative to parent
1289 * @param y row relative to parent
1290 * @param width visible text width
1291 * @param fixed if true, the text cannot exceed the display width
1292 * @return the new text field
1294 public final TPasswordField
addPasswordField(final int x
, final int y
,
1295 final int width
, final boolean fixed
) {
1297 return new TPasswordField(this, x
, y
, width
, fixed
);
1301 * Convenience function to add a password text field to this
1304 * @param x column relative to parent
1305 * @param y row relative to parent
1306 * @param width visible text width
1307 * @param fixed if true, the text cannot exceed the display width
1308 * @param text initial text, default is empty string
1309 * @return the new text field
1311 public final TPasswordField
addPasswordField(final int x
, final int y
,
1312 final int width
, final boolean fixed
, final String text
) {
1314 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
1318 * Convenience function to add a password text field to this
1321 * @param x column relative to parent
1322 * @param y row relative to parent
1323 * @param width visible text width
1324 * @param fixed if true, the text cannot exceed the display width
1325 * @param text initial text, default is empty string
1326 * @param enterAction function to call when enter key is pressed
1327 * @param updateAction function to call when the text is updated
1328 * @return the new text field
1330 public final TPasswordField
addPasswordField(final int x
, final int y
,
1331 final int width
, final boolean fixed
, final String text
,
1332 final TAction enterAction
, final TAction updateAction
) {
1334 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
1339 * Convenience function to add a tree view to this container/window.
1341 * @param x column relative to parent
1342 * @param y row relative to parent
1343 * @param width width of tree view
1344 * @param height height of tree view
1345 * @return the new tree view
1347 public final TTreeView
addTreeView(final int x
, final int y
,
1348 final int width
, final int height
) {
1350 return new TTreeView(this, x
, y
, width
, height
);
1354 * Convenience function to add a tree view to this container/window.
1356 * @param x column relative to parent
1357 * @param y row relative to parent
1358 * @param width width of tree view
1359 * @param height height of tree view
1360 * @param action action to perform when an item is selected
1361 * @return the new tree view
1363 public final TTreeView
addTreeView(final int x
, final int y
,
1364 final int width
, final int height
, final TAction action
) {
1366 return new TTreeView(this, x
, y
, width
, height
, action
);
1370 * Convenience function to spawn a file open box.
1372 * @param path path of selected file
1373 * @return the result of the new file open box
1374 * @throws IOException if a java.io operation throws
1376 public final String
fileOpenBox(final String path
) throws IOException
{
1377 return getApplication().fileOpenBox(path
);
1381 * Convenience function to spawn a file open box.
1383 * @param path path of selected file
1384 * @param type one of the Type constants
1385 * @return the result of the new file open box
1386 * @throws IOException if a java.io operation throws
1388 public final String
fileOpenBox(final String path
,
1389 final TFileOpenBox
.Type type
) throws IOException
{
1391 return getApplication().fileOpenBox(path
, type
);
1394 * Convenience function to add a directory list to this container/window.
1396 * @param path directory path, must be a directory
1397 * @param x column relative to parent
1398 * @param y row relative to parent
1399 * @param width width of text area
1400 * @param height height of text area
1401 * @return the new directory list
1403 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1404 final int y
, final int width
, final int height
) {
1406 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
1410 * Convenience function to add a directory list to this container/window.
1412 * @param path directory path, must be a directory
1413 * @param x column relative to parent
1414 * @param y row relative to parent
1415 * @param width width of text area
1416 * @param height height of text area
1417 * @param action action to perform when an item is selected
1418 * @return the new directory list
1420 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
1421 final int y
, final int width
, final int height
, final TAction action
) {
1423 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
1427 * Convenience function to add a directory list to this container/window.
1429 * @param strings list of strings to show
1430 * @param x column relative to parent
1431 * @param y row relative to parent
1432 * @param width width of text area
1433 * @param height height of text area
1434 * @return the new directory list
1436 public final TList
addList(final List
<String
> strings
, final int x
,
1437 final int y
, final int width
, final int height
) {
1439 return new TList(this, strings
, x
, y
, width
, height
, null);
1443 * Convenience function to add a directory list to this container/window.
1445 * @param strings list of strings to show
1446 * @param x column relative to parent
1447 * @param y row relative to parent
1448 * @param width width of text area
1449 * @param height height of text area
1450 * @param enterAction action to perform when an item is selected
1451 * @return the new directory list
1453 public final TList
addList(final List
<String
> strings
, final int x
,
1454 final int y
, final int width
, final int height
,
1455 final TAction enterAction
) {
1457 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
1461 * Convenience function to add a directory list to this container/window.
1463 * @param strings list of strings to show
1464 * @param x column relative to parent
1465 * @param y row relative to parent
1466 * @param width width of text area
1467 * @param height height of text area
1468 * @param enterAction action to perform when an item is selected
1469 * @param moveAction action to perform when the user navigates to a new
1470 * item with arrow/page keys
1471 * @return the new directory list
1473 public final TList
addList(final List
<String
> strings
, final int x
,
1474 final int y
, final int width
, final int height
,
1475 final TAction enterAction
, final TAction moveAction
) {
1477 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,