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
.awt
.image
.BufferedImage
;
32 import java
.io
.IOException
;
33 import java
.util
.List
;
34 import java
.util
.ArrayList
;
36 import jexer
.backend
.Screen
;
37 import jexer
.bits
.Cell
;
38 import jexer
.bits
.CellAttributes
;
39 import jexer
.bits
.ColorTheme
;
40 import jexer
.event
.TCommandEvent
;
41 import jexer
.event
.TInputEvent
;
42 import jexer
.event
.TKeypressEvent
;
43 import jexer
.event
.TMenuEvent
;
44 import jexer
.event
.TMouseEvent
;
45 import jexer
.event
.TResizeEvent
;
46 import jexer
.menu
.TMenu
;
47 import jexer
.ttree
.TTreeItem
;
48 import jexer
.ttree
.TTreeView
;
49 import jexer
.ttree
.TTreeViewWidget
;
50 import static jexer
.TKeypress
.*;
53 * TWidget is the base class of all objects that can be drawn on screen or
54 * handle user input events.
56 public abstract class TWidget
implements Comparable
<TWidget
> {
58 // ------------------------------------------------------------------------
59 // Variables --------------------------------------------------------------
60 // ------------------------------------------------------------------------
63 * Every widget has a parent widget that it may be "contained" in. For
64 * example, a TWindow might contain several TFields, or a TComboBox may
65 * contain a TList that itself contains a TVScroller.
67 private TWidget parent
= null;
70 * Child widgets that this widget contains.
72 private List
<TWidget
> children
;
75 * The currently active child widget that will receive keypress events.
77 private TWidget activeChild
= null;
80 * If true, this widget will receive events.
82 private boolean active
= false;
85 * The window that this widget draws to.
87 private TWindow window
= null;
90 * Absolute X position of the top-left corner.
95 * Absolute Y position of the top-left corner.
102 private int width
= 0;
107 private int height
= 0;
110 * My tab order inside a window or containing widget.
112 private int tabOrder
= 0;
115 * If true, this widget can be tabbed to or receive events.
117 private boolean enabled
= true;
120 * If true, this widget will be rendered.
122 private boolean visible
= true;
125 * If true, this widget has a cursor.
127 private boolean cursorVisible
= false;
130 * Cursor column position in relative coordinates.
132 private int cursorX
= 0;
135 * Cursor row position in relative coordinates.
137 private int cursorY
= 0;
139 // ------------------------------------------------------------------------
140 // Constructors -----------------------------------------------------------
141 // ------------------------------------------------------------------------
144 * Default constructor for subclasses.
146 protected TWidget() {
147 children
= new ArrayList
<TWidget
>();
151 * Protected constructor.
153 * @param parent parent widget
155 protected TWidget(final TWidget parent
) {
160 * Protected constructor.
162 * @param parent parent widget
163 * @param x column relative to parent
164 * @param y row relative to parent
165 * @param width width of widget
166 * @param height height of widget
168 protected TWidget(final TWidget parent
, final int x
, final int y
,
169 final int width
, final int height
) {
171 this(parent
, true, x
, y
, width
, height
);
175 * Protected constructor used by subclasses that are disabled by default.
177 * @param parent parent widget
178 * @param enabled if true assume enabled
180 protected TWidget(final TWidget parent
, final boolean enabled
) {
181 this.enabled
= enabled
;
182 this.parent
= parent
;
183 children
= new ArrayList
<TWidget
>();
185 if (parent
!= null) {
186 this.window
= parent
.window
;
187 parent
.addChild(this);
192 * Protected constructor used by subclasses that are disabled by default.
194 * @param parent parent widget
195 * @param enabled if true assume enabled
196 * @param x column relative to parent
197 * @param y row relative to parent
198 * @param width width of widget
199 * @param height height of widget
201 protected TWidget(final TWidget parent
, final boolean enabled
,
202 final int x
, final int y
, final int width
, final int height
) {
205 throw new IllegalArgumentException("width cannot be negative");
208 throw new IllegalArgumentException("height cannot be negative");
211 this.enabled
= enabled
;
212 this.parent
= parent
;
213 children
= new ArrayList
<TWidget
>();
215 if (parent
!= null) {
216 this.window
= parent
.window
;
217 parent
.addChild(this);
223 this.height
= height
;
227 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
229 * @param window the top-level window
230 * @param x column relative to parent
231 * @param y row relative to parent
232 * @param width width of window
233 * @param height height of window
235 protected final void setupForTWindow(final TWindow window
,
236 final int x
, final int y
, final int width
, final int height
) {
239 throw new IllegalArgumentException("width cannot be negative");
242 throw new IllegalArgumentException("height cannot be negative");
245 this.parent
= window
;
246 this.window
= window
;
250 this.height
= height
;
253 // ------------------------------------------------------------------------
254 // Event handlers ---------------------------------------------------------
255 // ------------------------------------------------------------------------
258 * Subclasses should override this method to cleanup resources. This is
259 * called by TWindow.onClose().
261 protected void close() {
262 // Default: call close() on children.
263 for (TWidget w
: getChildren()) {
269 * Check if a mouse press/release event coordinate is contained in this
272 * @param mouse a mouse-based event
273 * @return whether or not a mouse click would be sent to this widget
275 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
281 if ((this instanceof TTreeItem
)
282 && ((y
< 0) || (y
> parent
.getHeight() - 1))
287 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
288 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
289 && (mouse
.getAbsoluteY() >= getAbsoluteY())
290 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
298 * Method that subclasses can override to handle keystrokes.
300 * @param keypress keystroke event
302 public void onKeypress(final TKeypressEvent keypress
) {
303 assert (parent
!= null);
305 if ((children
.size() == 0)
306 || (this instanceof TTreeView
)
307 || (this instanceof TText
)
308 || (this instanceof TComboBox
)
312 // tab / shift-tab - switch to next/previous widget
313 // left-arrow or up-arrow: same as shift-tab
314 if ((keypress
.equals(kbTab
))
315 || (keypress
.equals(kbDown
) && !(this instanceof TComboBox
))
317 parent
.switchWidget(true);
319 } else if ((keypress
.equals(kbShiftTab
))
320 || (keypress
.equals(kbBackTab
))
321 || (keypress
.equals(kbUp
) && !(this instanceof TComboBox
))
323 parent
.switchWidget(false);
328 if ((children
.size() == 0)
329 && !(this instanceof TTreeView
)
333 // right-arrow or down-arrow: same as tab
334 if (keypress
.equals(kbRight
)) {
335 parent
.switchWidget(true);
337 } else if (keypress
.equals(kbLeft
)) {
338 parent
.switchWidget(false);
343 // If I have any buttons on me AND this is an Alt-key that matches
344 // its mnemonic, send it an Enter keystroke.
345 for (TWidget widget
: children
) {
346 if (widget
instanceof TButton
) {
347 TButton button
= (TButton
) widget
;
348 if (button
.isEnabled()
349 && !keypress
.getKey().isFnKey()
350 && keypress
.getKey().isAlt()
351 && !keypress
.getKey().isCtrl()
352 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
353 == Character
.toLowerCase(keypress
.getKey().getChar()))
356 widget
.onKeypress(new TKeypressEvent(kbEnter
));
362 // If I have any labels on me AND this is an Alt-key that matches
363 // its mnemonic, call its action.
364 for (TWidget widget
: children
) {
365 if (widget
instanceof TLabel
) {
366 TLabel label
= (TLabel
) widget
;
367 if (!keypress
.getKey().isFnKey()
368 && keypress
.getKey().isAlt()
369 && !keypress
.getKey().isCtrl()
370 && (Character
.toLowerCase(label
.getMnemonic().getShortcut())
371 == Character
.toLowerCase(keypress
.getKey().getChar()))
380 // If I have any radiobuttons on me AND this is an Alt-key that
381 // matches its mnemonic, select it and send a Space to it.
382 for (TWidget widget
: children
) {
383 if (widget
instanceof TRadioButton
) {
384 TRadioButton button
= (TRadioButton
) widget
;
385 if (button
.isEnabled()
386 && !keypress
.getKey().isFnKey()
387 && keypress
.getKey().isAlt()
388 && !keypress
.getKey().isCtrl()
389 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
390 == Character
.toLowerCase(keypress
.getKey().getChar()))
393 widget
.onKeypress(new TKeypressEvent(kbSpace
));
397 if (widget
instanceof TRadioGroup
) {
398 for (TWidget child
: widget
.getChildren()) {
399 if (child
instanceof TRadioButton
) {
400 TRadioButton button
= (TRadioButton
) child
;
401 if (button
.isEnabled()
402 && !keypress
.getKey().isFnKey()
403 && keypress
.getKey().isAlt()
404 && !keypress
.getKey().isCtrl()
405 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
406 == Character
.toLowerCase(keypress
.getKey().getChar()))
409 widget
.activate(child
);
410 child
.onKeypress(new TKeypressEvent(kbSpace
));
418 // If I have any checkboxes on me AND this is an Alt-key that matches
419 // its mnemonic, select it and set it to checked.
420 for (TWidget widget
: children
) {
421 if (widget
instanceof TCheckBox
) {
422 TCheckBox checkBox
= (TCheckBox
) widget
;
423 if (checkBox
.isEnabled()
424 && !keypress
.getKey().isFnKey()
425 && keypress
.getKey().isAlt()
426 && !keypress
.getKey().isCtrl()
427 && (Character
.toLowerCase(checkBox
.getMnemonic().getShortcut())
428 == Character
.toLowerCase(keypress
.getKey().getChar()))
431 checkBox
.setChecked(true);
437 // Dispatch the keypress to an active widget
438 for (TWidget widget
: children
) {
440 widget
.onKeypress(keypress
);
447 * Method that subclasses can override to handle mouse button presses.
449 * @param mouse mouse button event
451 public void onMouseDown(final TMouseEvent mouse
) {
452 // Default: do nothing, pass to children instead
453 if (activeChild
!= null) {
454 if (activeChild
.mouseWouldHit(mouse
)) {
455 // Dispatch to the active child
457 // Set x and y relative to the child's coordinates
458 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
459 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
460 activeChild
.onMouseDown(mouse
);
464 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
465 TWidget widget
= children
.get(i
);
466 if (widget
.mouseWouldHit(mouse
)) {
467 // Dispatch to this child, also activate it
470 // Set x and y relative to the child's coordinates
471 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
472 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
473 widget
.onMouseDown(mouse
);
480 * Method that subclasses can override to handle mouse button releases.
482 * @param mouse mouse button event
484 public void onMouseUp(final TMouseEvent mouse
) {
485 // Default: do nothing, pass to children instead
486 if (activeChild
!= null) {
487 if (activeChild
.mouseWouldHit(mouse
)) {
488 // Dispatch to the active child
490 // Set x and y relative to the child's coordinates
491 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
492 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
493 activeChild
.onMouseUp(mouse
);
497 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
498 TWidget widget
= children
.get(i
);
499 if (widget
.mouseWouldHit(mouse
)) {
500 // Dispatch to this child, also activate it
503 // Set x and y relative to the child's coordinates
504 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
505 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
506 widget
.onMouseUp(mouse
);
513 * Method that subclasses can override to handle mouse movements.
515 * @param mouse mouse motion event
517 public void onMouseMotion(final TMouseEvent mouse
) {
518 // Default: do nothing, pass it on to ALL of my children. This way
519 // the children can see the mouse "leaving" their area.
520 for (TWidget widget
: children
) {
521 // Set x and y relative to the child's coordinates
522 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
523 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
524 widget
.onMouseMotion(mouse
);
529 * Method that subclasses can override to handle mouse button
532 * @param mouse mouse button event
534 public void onMouseDoubleClick(final TMouseEvent mouse
) {
535 // Default: do nothing, pass to children instead
536 if (activeChild
!= null) {
537 if (activeChild
.mouseWouldHit(mouse
)) {
538 // Dispatch to the active child
540 // Set x and y relative to the child's coordinates
541 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
542 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
543 activeChild
.onMouseDoubleClick(mouse
);
547 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
548 TWidget widget
= children
.get(i
);
549 if (widget
.mouseWouldHit(mouse
)) {
550 // Dispatch to this child, also activate it
553 // Set x and y relative to the child's coordinates
554 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
555 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
556 widget
.onMouseDoubleClick(mouse
);
563 * Method that subclasses can override to handle window/screen resize
566 * @param resize resize event
568 public void onResize(final TResizeEvent resize
) {
569 // Default: change my width/height.
570 if (resize
.getType() == TResizeEvent
.Type
.WIDGET
) {
571 width
= resize
.getWidth();
572 height
= resize
.getHeight();
574 // Let children see the screen resize
575 for (TWidget widget
: children
) {
576 widget
.onResize(resize
);
582 * Method that subclasses can override to handle posted command events.
584 * @param command command event
586 public void onCommand(final TCommandEvent command
) {
587 // Default: do nothing, pass to children instead
588 for (TWidget widget
: children
) {
589 widget
.onCommand(command
);
594 * Method that subclasses can override to handle menu or posted menu
597 * @param menu menu event
599 public void onMenu(final TMenuEvent menu
) {
600 // Default: do nothing, pass to children instead
601 for (TWidget widget
: children
) {
607 * Method that subclasses can override to do processing when the UI is
608 * idle. Note that repainting is NOT assumed. To get a refresh after
609 * onIdle, call doRepaint().
611 public void onIdle() {
612 // Default: do nothing, pass to children instead
613 for (TWidget widget
: children
) {
619 * Consume event. Subclasses that want to intercept all events in one go
620 * can override this method.
622 * @param event keyboard, mouse, resize, command, or menu event
624 public void handleEvent(final TInputEvent event
) {
626 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
632 // System.err.println(" -- discard --");
636 if (event
instanceof TKeypressEvent
) {
637 onKeypress((TKeypressEvent
) event
);
638 } else if (event
instanceof TMouseEvent
) {
640 TMouseEvent mouse
= (TMouseEvent
) event
;
642 switch (mouse
.getType()) {
653 onMouseMotion(mouse
);
656 case MOUSE_DOUBLE_CLICK
:
657 onMouseDoubleClick(mouse
);
661 throw new IllegalArgumentException("Invalid mouse event type: "
664 } else if (event
instanceof TResizeEvent
) {
665 onResize((TResizeEvent
) event
);
666 } else if (event
instanceof TCommandEvent
) {
667 onCommand((TCommandEvent
) event
);
668 } else if (event
instanceof TMenuEvent
) {
669 onMenu((TMenuEvent
) event
);
676 // ------------------------------------------------------------------------
677 // TWidget ----------------------------------------------------------------
678 // ------------------------------------------------------------------------
683 * @return parent widget
685 public final TWidget
getParent() {
690 * Get the list of child widgets that this widget contains.
692 * @return the list of child widgets
694 public List
<TWidget
> getChildren() {
699 * Remove this widget from its parent container. close() will be called
700 * before it is removed.
702 public final void remove() {
707 * Remove this widget from its parent container.
709 * @param doClose if true, call the close() method before removing the
712 public final void remove(final boolean doClose
) {
713 if (parent
!= null) {
714 parent
.remove(this, doClose
);
719 * Remove a child widget from this container.
721 * @param child the child widget to remove
722 * @param doClose if true, call the close() method before removing the
725 public final void remove(final TWidget child
, final boolean doClose
) {
726 if (!children
.contains(child
)) {
727 throw new IndexOutOfBoundsException("child widget is not in " +
728 "list of children of this parent");
733 children
.remove(child
);
738 * Set this widget's parent to a different widget.
740 * @param newParent new parent widget
741 * @param doClose if true, call the close() method before removing the
742 * child from its existing parent widget
744 public final void setParent(final TWidget newParent
,
745 final boolean doClose
) {
747 if (parent
!= null) {
748 parent
.remove(this, doClose
);
750 assert (parent
== null);
751 window
= newParent
.window
;
752 newParent
.addChild(this);
756 * Set this widget's window to a specific window. Parent must already be
757 * null. Having a null parent with a specified window is only used
758 * within Jexer by TStatusBar because TApplication routes events directly
759 * to it and calls its draw() method. Any other non-parented widgets
760 * will require similar special case functionality to receive events or
761 * be drawn to screen.
763 * @param window the window to use
765 public final void setWindow(final TWindow window
) {
767 if (parent
!= null) {
768 throw new IllegalArgumentException("Cannot have different " +
769 "windows for parent and child");
771 this.window
= window
;
775 * Remove a child widget from this container, and all of its children
776 * recursively from their parent containers.
778 * @param child the child widget to remove
779 * @param doClose if true, call the close() method before removing each
782 public final void removeAll(final TWidget child
, final boolean doClose
) {
783 remove(child
, doClose
);
784 for (TWidget w
: child
.children
) {
785 child
.removeAll(w
, doClose
);
792 * @return if true, this widget will receive events
794 public final boolean isActive() {
801 * @param active if true, this widget will receive events
803 public final void setActive(final boolean active
) {
804 this.active
= active
;
808 * Get the window this widget is on.
812 public final TWindow
getWindow() {
819 * @return absolute X position of the top-left corner
821 public final int getX() {
828 * @param x absolute X position of the top-left corner
830 public final void setX(final int x
) {
837 * @return absolute Y position of the top-left corner
839 public final int getY() {
846 * @param y absolute Y position of the top-left corner
848 public final void setY(final int y
) {
855 * @return widget width
857 public final int getWidth() {
864 * @param width new widget width
866 public final void setWidth(final int width
) {
873 * @return widget height
875 public final int getHeight() {
882 * @param height new widget height
884 public final void setHeight(final int height
) {
885 this.height
= height
;
889 * Change the dimensions.
891 * @param x absolute X position of the top-left corner
892 * @param y absolute Y position of the top-left corner
893 * @param width new widget width
894 * @param height new widget height
896 public final void setDimensions(final int x
, final int y
, final int width
,
908 * @return if true, this widget can be tabbed to or receive events
910 public final boolean isEnabled() {
917 * @param enabled if true, this widget can be tabbed to or receive events
919 public final void setEnabled(final boolean enabled
) {
920 this.enabled
= enabled
;
923 // See if there are any active siblings to switch to
924 boolean foundSibling
= false;
925 if (parent
!= null) {
926 for (TWidget w
: parent
.children
) {
928 && !(this instanceof THScroller
)
929 && !(this instanceof TVScroller
)
937 parent
.activeChild
= null;
946 * @param visible if true, this widget will be drawn
948 public final void setVisible(final boolean visible
) {
949 this.visible
= visible
;
953 * See if this widget is visible.
955 * @return if true, this widget will be drawn
957 public final boolean isVisible() {
962 * Set visible cursor flag.
964 * @param cursorVisible if true, this widget has a cursor
966 public final void setCursorVisible(final boolean cursorVisible
) {
967 this.cursorVisible
= cursorVisible
;
971 * See if this widget has a visible cursor.
973 * @return if true, this widget has a visible cursor
975 public final boolean isCursorVisible() {
976 // If cursor is out of my bounds, it is not visible.
977 if ((cursorX
>= width
)
979 || (cursorY
>= height
)
985 assert (window
!= null);
987 // If cursor is out of my window's bounds, it is not visible.
988 if ((getCursorAbsoluteX() >= window
.getAbsoluteX()
989 + window
.getWidth() - 1)
990 || (getCursorAbsoluteX() < 0)
991 || (getCursorAbsoluteY() >= window
.getAbsoluteY()
992 + window
.getHeight() - 1)
993 || (getCursorAbsoluteY() < 0)
997 return cursorVisible
;
1001 * Get cursor X value.
1003 * @return cursor column position in relative coordinates
1005 public final int getCursorX() {
1010 * Set cursor X value.
1012 * @param cursorX column position in relative coordinates
1014 public final void setCursorX(final int cursorX
) {
1015 this.cursorX
= cursorX
;
1019 * Get cursor Y value.
1021 * @return cursor row position in relative coordinates
1023 public final int getCursorY() {
1028 * Set cursor Y value.
1030 * @param cursorY row position in relative coordinates
1032 public final void setCursorY(final int cursorY
) {
1033 this.cursorY
= cursorY
;
1037 * Get this TWidget's parent TApplication.
1039 * @return the parent TApplication
1041 public TApplication
getApplication() {
1042 return window
.getApplication();
1048 * @return the Screen
1050 public Screen
getScreen() {
1051 return window
.getScreen();
1055 * Comparison operator. For various subclasses it sorts on:
1057 * <li>tabOrder for TWidgets</li>
1058 * <li>z for TWindows</li>
1059 * <li>text for TTreeItems</li>
1062 * @param that another TWidget, TWindow, or TTreeItem instance
1063 * @return difference between this.tabOrder and that.tabOrder, or
1064 * difference between this.z and that.z, or String.compareTo(text)
1066 public final int compareTo(final TWidget that
) {
1067 if ((this instanceof TWindow
)
1068 && (that
instanceof TWindow
)
1070 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
1072 if ((this instanceof TTreeItem
)
1073 && (that
instanceof TTreeItem
)
1075 return (((TTreeItem
) this).getText().compareTo(
1076 ((TTreeItem
) that
).getText()));
1078 return (this.tabOrder
- that
.tabOrder
);
1082 * See if this widget should render with the active color.
1084 * @return true if this widget is active and all of its parents are
1087 public final boolean isAbsoluteActive() {
1088 if (parent
== this) {
1091 return (active
&& (parent
== null ?
true : parent
.isAbsoluteActive()));
1095 * Returns the cursor X position.
1097 * @return absolute screen column number for the cursor's X position
1099 public final int getCursorAbsoluteX() {
1100 return getAbsoluteX() + cursorX
;
1104 * Returns the cursor Y position.
1106 * @return absolute screen row number for the cursor's Y position
1108 public final int getCursorAbsoluteY() {
1109 return getAbsoluteY() + cursorY
;
1113 * Compute my absolute X position as the sum of my X plus all my parent's
1116 * @return absolute screen column number for my X position
1118 public final int getAbsoluteX() {
1119 assert (parent
!= null);
1120 if (parent
== this) {
1123 if ((parent
instanceof TWindow
)
1124 && !(parent
instanceof TMenu
)
1125 && !(parent
instanceof TDesktop
)
1127 // Widgets on a TWindow have (0,0) as their top-left, but this is
1128 // actually the TWindow's (1,1).
1129 return parent
.getAbsoluteX() + x
+ 1;
1131 return parent
.getAbsoluteX() + x
;
1135 * Compute my absolute Y position as the sum of my Y plus all my parent's
1138 * @return absolute screen row number for my Y position
1140 public final int getAbsoluteY() {
1141 assert (parent
!= null);
1142 if (parent
== this) {
1145 if ((parent
instanceof TWindow
)
1146 && !(parent
instanceof TMenu
)
1147 && !(parent
instanceof TDesktop
)
1149 // Widgets on a TWindow have (0,0) as their top-left, but this is
1150 // actually the TWindow's (1,1).
1151 return parent
.getAbsoluteY() + y
+ 1;
1153 return parent
.getAbsoluteY() + y
;
1157 * Get the global color theme.
1159 * @return the ColorTheme
1161 protected final ColorTheme
getTheme() {
1162 return window
.getApplication().getTheme();
1166 * Draw my specific widget. When called, the screen rectangle I draw
1167 * into is already setup (offset and clipping).
1169 public void draw() {
1170 // Default widget draws nothing.
1174 * Called by parent to render to TWindow. Note package private access.
1176 final void drawChildren() {
1177 // Set my clipping rectangle
1178 assert (window
!= null);
1179 assert (getScreen() != null);
1180 Screen screen
= getScreen();
1182 // Special case: TStatusBar is drawn by TApplication, not anything
1184 if (this instanceof TStatusBar
) {
1188 screen
.setClipRight(width
);
1189 screen
.setClipBottom(height
);
1191 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
1192 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
1193 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
1194 absoluteRightEdge
-= 1;
1196 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
1197 absoluteBottomEdge
-= 1;
1199 int myRightEdge
= getAbsoluteX() + width
;
1200 int myBottomEdge
= getAbsoluteY() + height
;
1201 if (getAbsoluteX() > absoluteRightEdge
) {
1203 screen
.setClipRight(0);
1204 } else if (myRightEdge
> absoluteRightEdge
) {
1205 screen
.setClipRight(screen
.getClipRight()
1206 - (myRightEdge
- absoluteRightEdge
));
1208 if (getAbsoluteY() > absoluteBottomEdge
) {
1210 screen
.setClipBottom(0);
1211 } else if (myBottomEdge
> absoluteBottomEdge
) {
1212 screen
.setClipBottom(screen
.getClipBottom()
1213 - (myBottomEdge
- absoluteBottomEdge
));
1217 screen
.setOffsetX(getAbsoluteX());
1218 screen
.setOffsetY(getAbsoluteY());
1222 assert (visible
== true);
1224 // Continue down the chain. Draw the active child last so that it
1226 for (TWidget widget
: children
) {
1227 if (widget
.isVisible() && (widget
!= activeChild
)) {
1228 widget
.drawChildren();
1231 if (activeChild
!= null) {
1232 activeChild
.drawChildren();
1237 * Repaint the screen on the next update.
1239 protected final void doRepaint() {
1240 window
.getApplication().doRepaint();
1244 * Add a child widget to my list of children. We set its tabOrder to 0
1245 * and increment the tabOrder of all other children.
1247 * @param child TWidget to add
1249 private void addChild(final TWidget child
) {
1250 children
.add(child
);
1253 && !(child
instanceof THScroller
)
1254 && !(child
instanceof TVScroller
)
1256 for (TWidget widget
: children
) {
1257 widget
.active
= false;
1259 child
.active
= true;
1260 activeChild
= child
;
1262 for (int i
= 0; i
< children
.size(); i
++) {
1263 children
.get(i
).tabOrder
= i
;
1268 * Reset the tab order of children to match their position in the list.
1269 * Available so that subclasses can re-order their widgets if needed.
1271 protected void resetTabOrder() {
1272 for (int i
= 0; i
< children
.size(); i
++) {
1273 children
.get(i
).tabOrder
= i
;
1278 * Switch the active child.
1280 * @param child TWidget to activate
1282 public final void activate(final TWidget child
) {
1283 assert (child
.enabled
);
1284 if ((child
instanceof THScroller
)
1285 || (child
instanceof TVScroller
)
1290 if (children
.size() == 1) {
1291 if (children
.get(0).enabled
== true) {
1292 child
.active
= true;
1293 activeChild
= child
;
1296 if (child
!= activeChild
) {
1297 if (activeChild
!= null) {
1298 activeChild
.active
= false;
1300 child
.active
= true;
1301 activeChild
= child
;
1307 * Switch the active child.
1309 * @param tabOrder tabOrder of the child to activate. If that child
1310 * isn't enabled, then the next enabled child will be activated.
1312 public final void activate(final int tabOrder
) {
1313 if (children
.size() == 1) {
1314 if (children
.get(0).enabled
== true) {
1315 children
.get(0).active
= true;
1316 activeChild
= children
.get(0);
1321 TWidget child
= null;
1322 for (TWidget widget
: children
) {
1323 if ((widget
.enabled
)
1324 && !(widget
instanceof THScroller
)
1325 && !(widget
instanceof TVScroller
)
1326 && (widget
.tabOrder
>= tabOrder
)
1332 if ((child
!= null) && (child
!= activeChild
)) {
1333 if (activeChild
!= null) {
1334 activeChild
.active
= false;
1336 assert (child
.enabled
);
1337 child
.active
= true;
1338 activeChild
= child
;
1343 * Make this widget the active child of its parent. Note that this is
1344 * not final since TWindow overrides activate().
1346 public void activate() {
1348 if (parent
!= null) {
1349 parent
.activate(this);
1355 * Switch the active widget with the next in the tab order.
1357 * @param forward if true, then switch to the next enabled widget in the
1358 * list, otherwise switch to the previous enabled widget in the list
1360 public final void switchWidget(final boolean forward
) {
1362 // No children: do nothing.
1363 if (children
.size() == 0) {
1367 assert (parent
!= null);
1369 // If there is only one child, make it active if it is enabled.
1370 if (children
.size() == 1) {
1371 if (children
.get(0).enabled
== true) {
1372 activeChild
= children
.get(0);
1373 activeChild
.active
= true;
1375 children
.get(0).active
= false;
1381 // Two or more children: go forward or backward to the next enabled
1384 if (activeChild
!= null) {
1385 tabOrder
= activeChild
.tabOrder
;
1395 // If at the end, pass the switch to my parent.
1396 if ((!forward
) && (parent
!= this)) {
1397 parent
.switchWidget(forward
);
1401 tabOrder
= children
.size() - 1;
1402 } else if (tabOrder
== children
.size()) {
1403 // If at the end, pass the switch to my parent.
1404 if ((forward
) && (parent
!= this)) {
1405 parent
.switchWidget(forward
);
1411 if (activeChild
== null) {
1412 if (tabOrder
== 0) {
1413 // We wrapped around
1416 } else if (activeChild
.tabOrder
== tabOrder
) {
1417 // We wrapped around
1420 } while ((!children
.get(tabOrder
).enabled
)
1421 && !(children
.get(tabOrder
) instanceof THScroller
)
1422 && !(children
.get(tabOrder
) instanceof TVScroller
));
1424 if (activeChild
!= null) {
1425 assert (children
.get(tabOrder
).enabled
);
1427 activeChild
.active
= false;
1429 if (children
.get(tabOrder
).enabled
== true) {
1430 children
.get(tabOrder
).active
= true;
1431 activeChild
= children
.get(tabOrder
);
1436 * Returns my active widget.
1438 * @return widget that is active, or this if no children
1440 public TWidget
getActiveChild() {
1441 if ((this instanceof THScroller
)
1442 || (this instanceof TVScroller
)
1447 for (TWidget widget
: children
) {
1448 if (widget
.active
) {
1449 return widget
.getActiveChild();
1452 // No active children, return me
1456 // ------------------------------------------------------------------------
1457 // Passthru for Screen functions ------------------------------------------
1458 // ------------------------------------------------------------------------
1461 * Get the attributes at one location.
1463 * @param x column coordinate. 0 is the left-most column.
1464 * @param y row coordinate. 0 is the top-most row.
1465 * @return attributes at (x, y)
1467 protected final CellAttributes
getAttrXY(final int x
, final int y
) {
1468 return getScreen().getAttrXY(x
, y
);
1472 * Set the attributes at one location.
1474 * @param x column coordinate. 0 is the left-most column.
1475 * @param y row coordinate. 0 is the top-most row.
1476 * @param attr attributes to use (bold, foreColor, backColor)
1478 protected final void putAttrXY(final int x
, final int y
,
1479 final CellAttributes attr
) {
1481 getScreen().putAttrXY(x
, y
, attr
);
1485 * Set the attributes at one location.
1487 * @param x column coordinate. 0 is the left-most column.
1488 * @param y row coordinate. 0 is the top-most row.
1489 * @param attr attributes to use (bold, foreColor, backColor)
1490 * @param clip if true, honor clipping/offset
1492 protected final void putAttrXY(final int x
, final int y
,
1493 final CellAttributes attr
, final boolean clip
) {
1495 getScreen().putAttrXY(x
, y
, attr
, clip
);
1499 * Fill the entire screen with one character with attributes.
1501 * @param ch character to draw
1502 * @param attr attributes to use (bold, foreColor, backColor)
1504 protected final void putAll(final char ch
, final CellAttributes attr
) {
1505 getScreen().putAll(ch
, attr
);
1509 * Render one character with attributes.
1511 * @param x column coordinate. 0 is the left-most column.
1512 * @param y row coordinate. 0 is the top-most row.
1513 * @param ch character + attributes to draw
1515 protected final void putCharXY(final int x
, final int y
, final Cell ch
) {
1516 getScreen().putCharXY(x
, y
, ch
);
1520 * Render one character with attributes.
1522 * @param x column coordinate. 0 is the left-most column.
1523 * @param y row coordinate. 0 is the top-most row.
1524 * @param ch character to draw
1525 * @param attr attributes to use (bold, foreColor, backColor)
1527 protected final void putCharXY(final int x
, final int y
, final char ch
,
1528 final CellAttributes attr
) {
1530 getScreen().putCharXY(x
, y
, ch
, attr
);
1534 * Render one character without changing the underlying attributes.
1536 * @param x column coordinate. 0 is the left-most column.
1537 * @param y row coordinate. 0 is the top-most row.
1538 * @param ch character to draw
1540 protected final void putCharXY(final int x
, final int y
, final char ch
) {
1541 getScreen().putCharXY(x
, y
, ch
);
1545 * Render a string. Does not wrap if the string exceeds the line.
1547 * @param x column coordinate. 0 is the left-most column.
1548 * @param y row coordinate. 0 is the top-most row.
1549 * @param str string to draw
1550 * @param attr attributes to use (bold, foreColor, backColor)
1552 protected final void putStringXY(final int x
, final int y
, final String str
,
1553 final CellAttributes attr
) {
1555 getScreen().putStringXY(x
, y
, str
, attr
);
1559 * Render a string without changing the underlying attribute. Does not
1560 * wrap if the string exceeds the line.
1562 * @param x column coordinate. 0 is the left-most column.
1563 * @param y row coordinate. 0 is the top-most row.
1564 * @param str string to draw
1566 protected final void putStringXY(final int x
, final int y
, final String str
) {
1567 getScreen().putStringXY(x
, y
, str
);
1571 * Draw a vertical line from (x, y) to (x, y + n).
1573 * @param x column coordinate. 0 is the left-most column.
1574 * @param y row coordinate. 0 is the top-most row.
1575 * @param n number of characters to draw
1576 * @param ch character to draw
1577 * @param attr attributes to use (bold, foreColor, backColor)
1579 protected final void vLineXY(final int x
, final int y
, final int n
,
1580 final char ch
, final CellAttributes attr
) {
1582 getScreen().vLineXY(x
, y
, n
, ch
, attr
);
1586 * Draw a horizontal line from (x, y) to (x + n, y).
1588 * @param x column coordinate. 0 is the left-most column.
1589 * @param y row coordinate. 0 is the top-most row.
1590 * @param n number of characters to draw
1591 * @param ch character to draw
1592 * @param attr attributes to use (bold, foreColor, backColor)
1594 protected final void hLineXY(final int x
, final int y
, final int n
,
1595 final char ch
, final CellAttributes attr
) {
1597 getScreen().hLineXY(x
, y
, n
, ch
, attr
);
1601 * Draw a box with a border and empty background.
1603 * @param left left column of box. 0 is the left-most row.
1604 * @param top top row of the box. 0 is the top-most row.
1605 * @param right right column of box
1606 * @param bottom bottom row of the box
1607 * @param border attributes to use for the border
1608 * @param background attributes to use for the background
1610 protected final void drawBox(final int left
, final int top
,
1611 final int right
, final int bottom
,
1612 final CellAttributes border
, final CellAttributes background
) {
1614 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
);
1618 * Draw a box with a border and empty background.
1620 * @param left left column of box. 0 is the left-most row.
1621 * @param top top row of the box. 0 is the top-most row.
1622 * @param right right column of box
1623 * @param bottom bottom row of the box
1624 * @param border attributes to use for the border
1625 * @param background attributes to use for the background
1626 * @param borderType if 1, draw a single-line border; if 2, draw a
1627 * double-line border; if 3, draw double-line top/bottom edges and
1628 * single-line left/right edges (like Qmodem)
1629 * @param shadow if true, draw a "shadow" on the box
1631 protected final void drawBox(final int left
, final int top
,
1632 final int right
, final int bottom
,
1633 final CellAttributes border
, final CellAttributes background
,
1634 final int borderType
, final boolean shadow
) {
1636 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
,
1637 borderType
, shadow
);
1641 * Draw a box shadow.
1643 * @param left left column of box. 0 is the left-most row.
1644 * @param top top row of the box. 0 is the top-most row.
1645 * @param right right column of box
1646 * @param bottom bottom row of the box
1648 protected final void drawBoxShadow(final int left
, final int top
,
1649 final int right
, final int bottom
) {
1651 getScreen().drawBoxShadow(left
, top
, right
, bottom
);
1654 // ------------------------------------------------------------------------
1655 // Other TWidget constructors ---------------------------------------------
1656 // ------------------------------------------------------------------------
1659 * Convenience function to add a label to this container/window.
1662 * @param x column relative to parent
1663 * @param y row relative to parent
1664 * @return the new label
1666 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1667 return addLabel(text
, x
, y
, "tlabel");
1671 * Convenience function to add a label to this container/window.
1674 * @param x column relative to parent
1675 * @param y row relative to parent
1676 * @param action to call when shortcut is pressed
1677 * @return the new label
1679 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1680 final TAction action
) {
1682 return addLabel(text
, x
, y
, "tlabel", action
);
1686 * Convenience function to add a label to this container/window.
1689 * @param x column relative to parent
1690 * @param y row relative to parent
1691 * @param colorKey ColorTheme key color to use for foreground text.
1692 * Default is "tlabel"
1693 * @return the new label
1695 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1696 final String colorKey
) {
1698 return new TLabel(this, text
, x
, y
, colorKey
);
1702 * Convenience function to add a label to this container/window.
1705 * @param x column relative to parent
1706 * @param y row relative to parent
1707 * @param colorKey ColorTheme key color to use for foreground text.
1708 * Default is "tlabel"
1709 * @param action to call when shortcut is pressed
1710 * @return the new label
1712 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1713 final String colorKey
, final TAction action
) {
1715 return new TLabel(this, text
, x
, y
, colorKey
, action
);
1719 * Convenience function to add a label to this container/window.
1722 * @param x column relative to parent
1723 * @param y row relative to parent
1724 * @param colorKey ColorTheme key color to use for foreground text.
1725 * Default is "tlabel"
1726 * @param useWindowBackground if true, use the window's background color
1727 * @return the new label
1729 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1730 final String colorKey
, final boolean useWindowBackground
) {
1732 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
);
1736 * Convenience function to add a label to this container/window.
1739 * @param x column relative to parent
1740 * @param y row relative to parent
1741 * @param colorKey ColorTheme key color to use for foreground text.
1742 * Default is "tlabel"
1743 * @param useWindowBackground if true, use the window's background color
1744 * @param action to call when shortcut is pressed
1745 * @return the new label
1747 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1748 final String colorKey
, final boolean useWindowBackground
,
1749 final TAction action
) {
1751 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
,
1756 * Convenience function to add a button to this container/window.
1758 * @param text label on the button
1759 * @param x column relative to parent
1760 * @param y row relative to parent
1761 * @param action action to call when button is pressed
1762 * @return the new button
1764 public final TButton
addButton(final String text
, final int x
, final int y
,
1765 final TAction action
) {
1767 return new TButton(this, text
, x
, y
, action
);
1771 * Convenience function to add a checkbox to this container/window.
1773 * @param x column relative to parent
1774 * @param y row relative to parent
1775 * @param label label to display next to (right of) the checkbox
1776 * @param checked initial check state
1777 * @return the new checkbox
1779 public final TCheckBox
addCheckBox(final int x
, final int y
,
1780 final String label
, final boolean checked
) {
1782 return new TCheckBox(this, x
, y
, label
, checked
);
1786 * Convenience function to add a combobox to this container/window.
1788 * @param x column relative to parent
1789 * @param y row relative to parent
1790 * @param width visible combobox width, including the down-arrow
1791 * @param values the possible values for the box, shown in the drop-down
1792 * @param valuesIndex the initial index in values, or -1 for no default
1794 * @param valuesHeight the height of the values drop-down when it is
1796 * @param updateAction action to call when a new value is selected from
1797 * the list or enter is pressed in the edit field
1798 * @return the new combobox
1800 public final TComboBox
addComboBox(final int x
, final int y
,
1801 final int width
, final List
<String
> values
, final int valuesIndex
,
1802 final int valuesHeight
, final TAction updateAction
) {
1804 return new TComboBox(this, x
, y
, width
, values
, valuesIndex
,
1805 valuesHeight
, updateAction
);
1809 * Convenience function to add a spinner to this container/window.
1811 * @param x column relative to parent
1812 * @param y row relative to parent
1813 * @param upAction action to call when the up arrow is clicked or pressed
1814 * @param downAction action to call when the down arrow is clicked or
1816 * @return the new spinner
1818 public final TSpinner
addSpinner(final int x
, final int y
,
1819 final TAction upAction
, final TAction downAction
) {
1821 return new TSpinner(this, x
, y
, upAction
, downAction
);
1825 * Convenience function to add a calendar to this container/window.
1827 * @param x column relative to parent
1828 * @param y row relative to parent
1829 * @param updateAction action to call when the user changes the value of
1831 * @return the new calendar
1833 public final TCalendar
addCalendar(final int x
, final int y
,
1834 final TAction updateAction
) {
1836 return new TCalendar(this, x
, y
, updateAction
);
1840 * Convenience function to add a progress bar to this container/window.
1842 * @param x column relative to parent
1843 * @param y row relative to parent
1844 * @param width width of progress bar
1845 * @param value initial value of percent complete
1846 * @return the new progress bar
1848 public final TProgressBar
addProgressBar(final int x
, final int y
,
1849 final int width
, final int value
) {
1851 return new TProgressBar(this, x
, y
, width
, value
);
1855 * Convenience function to add a radio button group to this
1858 * @param x column relative to parent
1859 * @param y row relative to parent
1860 * @param label label to display on the group box
1861 * @return the new radio button group
1863 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1864 final String label
) {
1866 return new TRadioGroup(this, x
, y
, label
);
1870 * Convenience function to add a text field to this container/window.
1872 * @param x column relative to parent
1873 * @param y row relative to parent
1874 * @param width visible text width
1875 * @param fixed if true, the text cannot exceed the display width
1876 * @return the new text field
1878 public final TField
addField(final int x
, final int y
,
1879 final int width
, final boolean fixed
) {
1881 return new TField(this, x
, y
, width
, fixed
);
1885 * Convenience function to add a text field to this container/window.
1887 * @param x column relative to parent
1888 * @param y row relative to parent
1889 * @param width visible text width
1890 * @param fixed if true, the text cannot exceed the display width
1891 * @param text initial text, default is empty string
1892 * @return the new text field
1894 public final TField
addField(final int x
, final int y
,
1895 final int width
, final boolean fixed
, final String text
) {
1897 return new TField(this, x
, y
, width
, fixed
, text
);
1901 * Convenience function to add a text field to this container/window.
1903 * @param x column relative to parent
1904 * @param y row relative to parent
1905 * @param width visible text width
1906 * @param fixed if true, the text cannot exceed the display width
1907 * @param text initial text, default is empty string
1908 * @param enterAction function to call when enter key is pressed
1909 * @param updateAction function to call when the text is updated
1910 * @return the new text field
1912 public final TField
addField(final int x
, final int y
,
1913 final int width
, final boolean fixed
, final String text
,
1914 final TAction enterAction
, final TAction updateAction
) {
1916 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1921 * Convenience function to add a scrollable text box to this
1924 * @param text text on the screen
1925 * @param x column relative to parent
1926 * @param y row relative to parent
1927 * @param width width of text area
1928 * @param height height of text area
1929 * @param colorKey ColorTheme key color to use for foreground text
1930 * @return the new text box
1932 public final TText
addText(final String text
, final int x
,
1933 final int y
, final int width
, final int height
, final String colorKey
) {
1935 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1939 * Convenience function to add a scrollable text box to this
1942 * @param text text on the screen
1943 * @param x column relative to parent
1944 * @param y row relative to parent
1945 * @param width width of text area
1946 * @param height height of text area
1947 * @return the new text box
1949 public final TText
addText(final String text
, final int x
, final int y
,
1950 final int width
, final int height
) {
1952 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1956 * Convenience function to add an editable text area box to this
1959 * @param text text on the screen
1960 * @param x column relative to parent
1961 * @param y row relative to parent
1962 * @param width width of text area
1963 * @param height height of text area
1964 * @return the new text box
1966 public final TEditorWidget
addEditor(final String text
, final int x
,
1967 final int y
, final int width
, final int height
) {
1969 return new TEditorWidget(this, text
, x
, y
, width
, height
);
1973 * Convenience function to spawn a message box.
1975 * @param title window title, will be centered along the top border
1976 * @param caption message to display. Use embedded newlines to get a
1978 * @return the new message box
1980 public final TMessageBox
messageBox(final String title
,
1981 final String caption
) {
1983 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
1987 * Convenience function to spawn a message box.
1989 * @param title window title, will be centered along the top border
1990 * @param caption message to display. Use embedded newlines to get a
1992 * @param type one of the TMessageBox.Type constants. Default is
1994 * @return the new message box
1996 public final TMessageBox
messageBox(final String title
,
1997 final String caption
, final TMessageBox
.Type type
) {
1999 return getApplication().messageBox(title
, caption
, type
);
2003 * Convenience function to spawn an input box.
2005 * @param title window title, will be centered along the top border
2006 * @param caption message to display. Use embedded newlines to get a
2008 * @return the new input box
2010 public final TInputBox
inputBox(final String title
, final String caption
) {
2012 return getApplication().inputBox(title
, caption
);
2016 * Convenience function to spawn an input box.
2018 * @param title window title, will be centered along the top border
2019 * @param caption message to display. Use embedded newlines to get a
2021 * @param text initial text to seed the field with
2022 * @return the new input box
2024 public final TInputBox
inputBox(final String title
, final String caption
,
2025 final String text
) {
2027 return getApplication().inputBox(title
, caption
, text
);
2031 * Convenience function to spawn an input box.
2033 * @param title window title, will be centered along the top border
2034 * @param caption message to display. Use embedded newlines to get a
2036 * @param text initial text to seed the field with
2037 * @param type one of the Type constants. Default is Type.OK.
2038 * @return the new input box
2040 public final TInputBox
inputBox(final String title
, final String caption
,
2041 final String text
, final TInputBox
.Type type
) {
2043 return getApplication().inputBox(title
, caption
, text
, type
);
2047 * Convenience function to add a password text field to this
2050 * @param x column relative to parent
2051 * @param y row relative to parent
2052 * @param width visible text width
2053 * @param fixed if true, the text cannot exceed the display width
2054 * @return the new text field
2056 public final TPasswordField
addPasswordField(final int x
, final int y
,
2057 final int width
, final boolean fixed
) {
2059 return new TPasswordField(this, x
, y
, width
, fixed
);
2063 * Convenience function to add a password text field to this
2066 * @param x column relative to parent
2067 * @param y row relative to parent
2068 * @param width visible text width
2069 * @param fixed if true, the text cannot exceed the display width
2070 * @param text initial text, default is empty string
2071 * @return the new text field
2073 public final TPasswordField
addPasswordField(final int x
, final int y
,
2074 final int width
, final boolean fixed
, final String text
) {
2076 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
2080 * Convenience function to add a password text field to this
2083 * @param x column relative to parent
2084 * @param y row relative to parent
2085 * @param width visible text width
2086 * @param fixed if true, the text cannot exceed the display width
2087 * @param text initial text, default is empty string
2088 * @param enterAction function to call when enter key is pressed
2089 * @param updateAction function to call when the text is updated
2090 * @return the new text field
2092 public final TPasswordField
addPasswordField(final int x
, final int y
,
2093 final int width
, final boolean fixed
, final String text
,
2094 final TAction enterAction
, final TAction updateAction
) {
2096 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
2101 * Convenience function to add a scrollable tree view to this
2104 * @param x column relative to parent
2105 * @param y row relative to parent
2106 * @param width width of tree view
2107 * @param height height of tree view
2108 * @return the new tree view
2110 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
2111 final int width
, final int height
) {
2113 return new TTreeViewWidget(this, x
, y
, width
, height
);
2117 * Convenience function to add a scrollable tree view to this
2120 * @param x column relative to parent
2121 * @param y row relative to parent
2122 * @param width width of tree view
2123 * @param height height of tree view
2124 * @param action action to perform when an item is selected
2125 * @return the new tree view
2127 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
2128 final int width
, final int height
, final TAction action
) {
2130 return new TTreeViewWidget(this, x
, y
, width
, height
, action
);
2134 * Convenience function to spawn a file open box.
2136 * @param path path of selected file
2137 * @return the result of the new file open box
2138 * @throws IOException if a java.io operation throws
2140 public final String
fileOpenBox(final String path
) throws IOException
{
2141 return getApplication().fileOpenBox(path
);
2145 * Convenience function to spawn a file save box.
2147 * @param path path of selected file
2148 * @return the result of the new file open box
2149 * @throws IOException if a java.io operation throws
2151 public final String
fileSaveBox(final String path
) throws IOException
{
2152 return getApplication().fileOpenBox(path
, TFileOpenBox
.Type
.SAVE
);
2156 * Convenience function to spawn a file open box.
2158 * @param path path of selected file
2159 * @param type one of the Type constants
2160 * @return the result of the new file open box
2161 * @throws IOException if a java.io operation throws
2163 public final String
fileOpenBox(final String path
,
2164 final TFileOpenBox
.Type type
) throws IOException
{
2166 return getApplication().fileOpenBox(path
, type
);
2170 * Convenience function to spawn a file open box.
2172 * @param path path of selected file
2173 * @param type one of the Type constants
2174 * @param filter a string that files must match to be displayed
2175 * @return the result of the new file open box
2176 * @throws IOException of a java.io operation throws
2178 public final String
fileOpenBox(final String path
,
2179 final TFileOpenBox
.Type type
, final String filter
) throws IOException
{
2181 ArrayList
<String
> filters
= new ArrayList
<String
>();
2182 filters
.add(filter
);
2184 return getApplication().fileOpenBox(path
, type
, filters
);
2188 * Convenience function to spawn a file open box.
2190 * @param path path of selected file
2191 * @param type one of the Type constants
2192 * @param filters a list of strings that files must match to be displayed
2193 * @return the result of the new file open box
2194 * @throws IOException of a java.io operation throws
2196 public final String
fileOpenBox(final String path
,
2197 final TFileOpenBox
.Type type
,
2198 final List
<String
> filters
) throws IOException
{
2200 return getApplication().fileOpenBox(path
, type
, filters
);
2204 * Convenience function to add a directory list to this container/window.
2206 * @param path directory path, must be a directory
2207 * @param x column relative to parent
2208 * @param y row relative to parent
2209 * @param width width of text area
2210 * @param height height of text area
2211 * @return the new directory list
2213 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2214 final int y
, final int width
, final int height
) {
2216 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
2220 * Convenience function to add a directory list to this container/window.
2222 * @param path directory path, must be a directory
2223 * @param x column relative to parent
2224 * @param y row relative to parent
2225 * @param width width of text area
2226 * @param height height of text area
2227 * @param action action to perform when an item is selected (enter or
2229 * @return the new directory list
2231 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2232 final int y
, final int width
, final int height
, final TAction action
) {
2234 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
2238 * Convenience function to add a directory list to this container/window.
2240 * @param path directory path, must be a directory
2241 * @param x column relative to parent
2242 * @param y row relative to parent
2243 * @param width width of text area
2244 * @param height height of text area
2245 * @param action action to perform when an item is selected (enter or
2247 * @param singleClickAction action to perform when an item is selected
2249 * @return the new directory list
2251 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2252 final int y
, final int width
, final int height
, final TAction action
,
2253 final TAction singleClickAction
) {
2255 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2260 * Convenience function to add a directory list to this container/window.
2262 * @param path directory path, must be a directory
2263 * @param x column relative to parent
2264 * @param y row relative to parent
2265 * @param width width of text area
2266 * @param height height of text area
2267 * @param action action to perform when an item is selected (enter or
2269 * @param singleClickAction action to perform when an item is selected
2271 * @param filters a list of strings that files must match to be displayed
2272 * @return the new directory list
2274 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2275 final int y
, final int width
, final int height
, final TAction action
,
2276 final TAction singleClickAction
, final List
<String
> filters
) {
2278 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2279 singleClickAction
, filters
);
2283 * Convenience function to add a list to this container/window.
2285 * @param strings list of strings to show
2286 * @param x column relative to parent
2287 * @param y row relative to parent
2288 * @param width width of text area
2289 * @param height height of text area
2290 * @return the new directory list
2292 public final TList
addList(final List
<String
> strings
, final int x
,
2293 final int y
, final int width
, final int height
) {
2295 return new TList(this, strings
, x
, y
, width
, height
, null);
2299 * Convenience function to add a list to this container/window.
2301 * @param strings list of strings to show
2302 * @param x column relative to parent
2303 * @param y row relative to parent
2304 * @param width width of text area
2305 * @param height height of text area
2306 * @param enterAction action to perform when an item is selected
2307 * @return the new directory list
2309 public final TList
addList(final List
<String
> strings
, final int x
,
2310 final int y
, final int width
, final int height
,
2311 final TAction enterAction
) {
2313 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
2317 * Convenience function to add a list to this container/window.
2319 * @param strings list of strings to show
2320 * @param x column relative to parent
2321 * @param y row relative to parent
2322 * @param width width of text area
2323 * @param height height of text area
2324 * @param enterAction action to perform when an item is selected
2325 * @param moveAction action to perform when the user navigates to a new
2326 * item with arrow/page keys
2327 * @return the new directory list
2329 public final TList
addList(final List
<String
> strings
, final int x
,
2330 final int y
, final int width
, final int height
,
2331 final TAction enterAction
, final TAction moveAction
) {
2333 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,
2338 * Convenience function to add a list to this container/window.
2340 * @param strings list of strings to show. This is allowed to be null
2341 * and set later with setList() or by subclasses.
2342 * @param x column relative to parent
2343 * @param y row relative to parent
2344 * @param width width of text area
2345 * @param height height of text area
2346 * @param enterAction action to perform when an item is selected
2347 * @param moveAction action to perform when the user navigates to a new
2348 * item with arrow/page keys
2349 * @param singleClickAction action to perform when the user clicks on an
2352 public TList
addList(final List
<String
> strings
, final int x
,
2353 final int y
, final int width
, final int height
,
2354 final TAction enterAction
, final TAction moveAction
,
2355 final TAction singleClickAction
) {
2357 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,
2358 moveAction
, singleClickAction
);
2363 * Convenience function to add an image to this container/window.
2365 * @param x column relative to parent
2366 * @param y row relative to parent
2367 * @param width number of text cells for width of the image
2368 * @param height number of text cells for height of the image
2369 * @param image the image to display
2370 * @param left left column of the image. 0 is the left-most column.
2371 * @param top top row of the image. 0 is the top-most row.
2373 public final TImage
addImage(final int x
, final int y
,
2374 final int width
, final int height
,
2375 final BufferedImage image
, final int left
, final int top
) {
2377 return new TImage(this, x
, y
, width
, height
, image
, left
, top
);
2381 * Convenience function to add an image to this container/window.
2383 * @param x column relative to parent
2384 * @param y row relative to parent
2385 * @param width number of text cells for width of the image
2386 * @param height number of text cells for height of the image
2387 * @param image the image to display
2388 * @param left left column of the image. 0 is the left-most column.
2389 * @param top top row of the image. 0 is the top-most row.
2390 * @param clickAction function to call when mouse is pressed
2392 public final TImage
addImage(final int x
, final int y
,
2393 final int width
, final int height
,
2394 final BufferedImage image
, final int left
, final int top
,
2395 final TAction clickAction
) {
2397 return new TImage(this, x
, y
, width
, height
, image
, left
, top
,
2402 * Convenience function to add an editable 2D data table to this
2405 * @param x column relative to parent
2406 * @param y row relative to parent
2407 * @param width width of widget
2408 * @param height height of widget
2410 public TTableWidget
addTable(final int x
, final int y
, final int width
,
2413 return new TTableWidget(this, x
, y
, width
, height
);
2417 * Convenience function to add an editable 2D data table to this
2420 * @param x column relative to parent
2421 * @param y row relative to parent
2422 * @param width width of widget
2423 * @param height height of widget
2424 * @param gridColumns number of columns in grid
2425 * @param gridRows number of rows in grid
2427 public TTableWidget
addTable(final int x
, final int y
, final int width
,
2428 final int height
, final int gridColumns
, final int gridRows
) {
2430 return new TTableWidget(this, x
, y
, width
, height
, gridColumns
,