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 this.window
= parent
.window
;
184 children
= new ArrayList
<TWidget
>();
186 // Do not add TStatusBars, they are drawn by TApplication.
187 if (this instanceof TStatusBar
) {
190 parent
.addChild(this);
195 * Protected constructor used by subclasses that are disabled by default.
197 * @param parent parent widget
198 * @param enabled if true assume enabled
199 * @param x column relative to parent
200 * @param y row relative to parent
201 * @param width width of widget
202 * @param height height of widget
204 protected TWidget(final TWidget parent
, final boolean enabled
,
205 final int x
, final int y
, final int width
, final int height
) {
208 throw new IllegalArgumentException("width cannot be negative");
211 throw new IllegalArgumentException("height cannot be negative");
214 this.enabled
= enabled
;
215 this.parent
= parent
;
216 this.window
= parent
.window
;
217 children
= new ArrayList
<TWidget
>();
219 // Do not add TStatusBars, they are drawn by TApplication.
220 if (this instanceof TStatusBar
) {
223 parent
.addChild(this);
229 this.height
= height
;
233 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
235 * @param window the top-level window
236 * @param x column relative to parent
237 * @param y row relative to parent
238 * @param width width of window
239 * @param height height of window
241 protected final void setupForTWindow(final TWindow window
,
242 final int x
, final int y
, final int width
, final int height
) {
245 throw new IllegalArgumentException("width cannot be negative");
248 throw new IllegalArgumentException("height cannot be negative");
251 this.parent
= window
;
252 this.window
= window
;
256 this.height
= height
;
259 // ------------------------------------------------------------------------
260 // Event handlers ---------------------------------------------------------
261 // ------------------------------------------------------------------------
264 * Subclasses should override this method to cleanup resources. This is
265 * called by TWindow.onClose().
267 protected void close() {
268 // Default: call close() on children.
269 for (TWidget w
: getChildren()) {
275 * Check if a mouse press/release event coordinate is contained in this
278 * @param mouse a mouse-based event
279 * @return whether or not a mouse click would be sent to this widget
281 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
287 if ((this instanceof TTreeItem
)
288 && ((y
< 0) || (y
> parent
.getHeight() - 1))
293 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
294 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
295 && (mouse
.getAbsoluteY() >= getAbsoluteY())
296 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
304 * Method that subclasses can override to handle keystrokes.
306 * @param keypress keystroke event
308 public void onKeypress(final TKeypressEvent keypress
) {
310 if ((children
.size() == 0)
311 || (this instanceof TTreeView
)
312 || (this instanceof TText
)
313 || (this instanceof TComboBox
)
317 // tab / shift-tab - switch to next/previous widget
318 // left-arrow or up-arrow: same as shift-tab
319 if ((keypress
.equals(kbTab
))
320 || (keypress
.equals(kbDown
) && !(this instanceof TComboBox
))
322 parent
.switchWidget(true);
324 } else if ((keypress
.equals(kbShiftTab
))
325 || (keypress
.equals(kbBackTab
))
326 || (keypress
.equals(kbUp
) && !(this instanceof TComboBox
))
328 parent
.switchWidget(false);
333 if ((children
.size() == 0)
334 && !(this instanceof TTreeView
)
338 // right-arrow or down-arrow: same as tab
339 if (keypress
.equals(kbRight
)) {
340 parent
.switchWidget(true);
342 } else if (keypress
.equals(kbLeft
)) {
343 parent
.switchWidget(false);
348 // If I have any buttons on me AND this is an Alt-key that matches
349 // its mnemonic, send it an Enter keystroke.
350 for (TWidget widget
: children
) {
351 if (widget
instanceof TButton
) {
352 TButton button
= (TButton
) widget
;
353 if (button
.isEnabled()
354 && !keypress
.getKey().isFnKey()
355 && keypress
.getKey().isAlt()
356 && !keypress
.getKey().isCtrl()
357 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
358 == Character
.toLowerCase(keypress
.getKey().getChar()))
361 widget
.onKeypress(new TKeypressEvent(kbEnter
));
367 // If I have any labels on me AND this is an Alt-key that matches
368 // its mnemonic, call its action.
369 for (TWidget widget
: children
) {
370 if (widget
instanceof TLabel
) {
371 TLabel label
= (TLabel
) widget
;
372 if (!keypress
.getKey().isFnKey()
373 && keypress
.getKey().isAlt()
374 && !keypress
.getKey().isCtrl()
375 && (Character
.toLowerCase(label
.getMnemonic().getShortcut())
376 == Character
.toLowerCase(keypress
.getKey().getChar()))
385 // If I have any radiobuttons on me AND this is an Alt-key that
386 // matches its mnemonic, select it and send a Space to it.
387 for (TWidget widget
: children
) {
388 if (widget
instanceof TRadioButton
) {
389 TRadioButton button
= (TRadioButton
) widget
;
390 if (button
.isEnabled()
391 && !keypress
.getKey().isFnKey()
392 && keypress
.getKey().isAlt()
393 && !keypress
.getKey().isCtrl()
394 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
395 == Character
.toLowerCase(keypress
.getKey().getChar()))
398 widget
.onKeypress(new TKeypressEvent(kbSpace
));
402 if (widget
instanceof TRadioGroup
) {
403 for (TWidget child
: widget
.getChildren()) {
404 if (child
instanceof TRadioButton
) {
405 TRadioButton button
= (TRadioButton
) child
;
406 if (button
.isEnabled()
407 && !keypress
.getKey().isFnKey()
408 && keypress
.getKey().isAlt()
409 && !keypress
.getKey().isCtrl()
410 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
411 == Character
.toLowerCase(keypress
.getKey().getChar()))
414 widget
.activate(child
);
415 child
.onKeypress(new TKeypressEvent(kbSpace
));
423 // If I have any checkboxes on me AND this is an Alt-key that matches
424 // its mnemonic, select it and set it to checked.
425 for (TWidget widget
: children
) {
426 if (widget
instanceof TCheckBox
) {
427 TCheckBox checkBox
= (TCheckBox
) widget
;
428 if (checkBox
.isEnabled()
429 && !keypress
.getKey().isFnKey()
430 && keypress
.getKey().isAlt()
431 && !keypress
.getKey().isCtrl()
432 && (Character
.toLowerCase(checkBox
.getMnemonic().getShortcut())
433 == Character
.toLowerCase(keypress
.getKey().getChar()))
436 checkBox
.setChecked(true);
442 // Dispatch the keypress to an active widget
443 for (TWidget widget
: children
) {
445 widget
.onKeypress(keypress
);
452 * Method that subclasses can override to handle mouse button presses.
454 * @param mouse mouse button event
456 public void onMouseDown(final TMouseEvent mouse
) {
457 // Default: do nothing, pass to children instead
458 if (activeChild
!= null) {
459 if (activeChild
.mouseWouldHit(mouse
)) {
460 // Dispatch to the active child
462 // Set x and y relative to the child's coordinates
463 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
464 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
465 activeChild
.onMouseDown(mouse
);
469 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
470 TWidget widget
= children
.get(i
);
471 if (widget
.mouseWouldHit(mouse
)) {
472 // Dispatch to this child, also activate it
475 // Set x and y relative to the child's coordinates
476 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
477 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
478 widget
.onMouseDown(mouse
);
485 * Method that subclasses can override to handle mouse button releases.
487 * @param mouse mouse button event
489 public void onMouseUp(final TMouseEvent mouse
) {
490 // Default: do nothing, pass to children instead
491 if (activeChild
!= null) {
492 if (activeChild
.mouseWouldHit(mouse
)) {
493 // Dispatch to the active child
495 // Set x and y relative to the child's coordinates
496 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
497 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
498 activeChild
.onMouseUp(mouse
);
502 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
503 TWidget widget
= children
.get(i
);
504 if (widget
.mouseWouldHit(mouse
)) {
505 // Dispatch to this child, also activate it
508 // Set x and y relative to the child's coordinates
509 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
510 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
511 widget
.onMouseUp(mouse
);
518 * Method that subclasses can override to handle mouse movements.
520 * @param mouse mouse motion event
522 public void onMouseMotion(final TMouseEvent mouse
) {
523 // Default: do nothing, pass it on to ALL of my children. This way
524 // the children can see the mouse "leaving" their area.
525 for (TWidget widget
: children
) {
526 // Set x and y relative to the child's coordinates
527 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
528 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
529 widget
.onMouseMotion(mouse
);
534 * Method that subclasses can override to handle mouse button
537 * @param mouse mouse button event
539 public void onMouseDoubleClick(final TMouseEvent mouse
) {
540 // Default: do nothing, pass to children instead
541 if (activeChild
!= null) {
542 if (activeChild
.mouseWouldHit(mouse
)) {
543 // Dispatch to the active child
545 // Set x and y relative to the child's coordinates
546 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
547 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
548 activeChild
.onMouseDoubleClick(mouse
);
552 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
553 TWidget widget
= children
.get(i
);
554 if (widget
.mouseWouldHit(mouse
)) {
555 // Dispatch to this child, also activate it
558 // Set x and y relative to the child's coordinates
559 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
560 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
561 widget
.onMouseDoubleClick(mouse
);
568 * Method that subclasses can override to handle window/screen resize
571 * @param resize resize event
573 public void onResize(final TResizeEvent resize
) {
574 // Default: change my width/height.
575 if (resize
.getType() == TResizeEvent
.Type
.WIDGET
) {
576 width
= resize
.getWidth();
577 height
= resize
.getHeight();
579 // Let children see the screen resize
580 for (TWidget widget
: children
) {
581 widget
.onResize(resize
);
587 * Method that subclasses can override to handle posted command events.
589 * @param command command event
591 public void onCommand(final TCommandEvent command
) {
592 // Default: do nothing, pass to children instead
593 for (TWidget widget
: children
) {
594 widget
.onCommand(command
);
599 * Method that subclasses can override to handle menu or posted menu
602 * @param menu menu event
604 public void onMenu(final TMenuEvent menu
) {
605 // Default: do nothing, pass to children instead
606 for (TWidget widget
: children
) {
612 * Method that subclasses can override to do processing when the UI is
613 * idle. Note that repainting is NOT assumed. To get a refresh after
614 * onIdle, call doRepaint().
616 public void onIdle() {
617 // Default: do nothing, pass to children instead
618 for (TWidget widget
: children
) {
624 * Consume event. Subclasses that want to intercept all events in one go
625 * can override this method.
627 * @param event keyboard, mouse, resize, command, or menu event
629 public void handleEvent(final TInputEvent event
) {
631 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
637 // System.err.println(" -- discard --");
641 if (event
instanceof TKeypressEvent
) {
642 onKeypress((TKeypressEvent
) event
);
643 } else if (event
instanceof TMouseEvent
) {
645 TMouseEvent mouse
= (TMouseEvent
) event
;
647 switch (mouse
.getType()) {
658 onMouseMotion(mouse
);
661 case MOUSE_DOUBLE_CLICK
:
662 onMouseDoubleClick(mouse
);
666 throw new IllegalArgumentException("Invalid mouse event type: "
669 } else if (event
instanceof TResizeEvent
) {
670 onResize((TResizeEvent
) event
);
671 } else if (event
instanceof TCommandEvent
) {
672 onCommand((TCommandEvent
) event
);
673 } else if (event
instanceof TMenuEvent
) {
674 onMenu((TMenuEvent
) event
);
681 // ------------------------------------------------------------------------
682 // TWidget ----------------------------------------------------------------
683 // ------------------------------------------------------------------------
688 * @return parent widget
690 public final TWidget
getParent() {
695 * Get the list of child widgets that this widget contains.
697 * @return the list of child widgets
699 public List
<TWidget
> getChildren() {
706 * @return if true, this widget will receive events
708 public final boolean isActive() {
715 * @param active if true, this widget will receive events
717 public final void setActive(final boolean active
) {
718 this.active
= active
;
722 * Get the window this widget is on.
726 public final TWindow
getWindow() {
733 * @return absolute X position of the top-left corner
735 public final int getX() {
742 * @param x absolute X position of the top-left corner
744 public final void setX(final int x
) {
751 * @return absolute Y position of the top-left corner
753 public final int getY() {
760 * @param y absolute Y position of the top-left corner
762 public final void setY(final int y
) {
769 * @return widget width
771 public final int getWidth() {
778 * @param width new widget width
780 public final void setWidth(final int width
) {
787 * @return widget height
789 public final int getHeight() {
796 * @param height new widget height
798 public final void setHeight(final int height
) {
799 this.height
= height
;
803 * Change the dimensions.
805 * @param x absolute X position of the top-left corner
806 * @param y absolute Y position of the top-left corner
807 * @param width new widget width
808 * @param height new widget height
810 public final void setDimensions(final int x
, final int y
, final int width
,
822 * @return if true, this widget can be tabbed to or receive events
824 public final boolean isEnabled() {
831 * @param enabled if true, this widget can be tabbed to or receive events
833 public final void setEnabled(final boolean enabled
) {
834 this.enabled
= enabled
;
837 // See if there are any active siblings to switch to
838 boolean foundSibling
= false;
839 if (parent
!= null) {
840 for (TWidget w
: parent
.children
) {
842 && !(this instanceof THScroller
)
843 && !(this instanceof TVScroller
)
851 parent
.activeChild
= null;
860 * @param visible if true, this widget will be drawn
862 public final void setVisible(final boolean visible
) {
863 this.visible
= visible
;
867 * See if this widget is visible.
869 * @return if true, this widget will be drawn
871 public final boolean isVisible() {
876 * Set visible cursor flag.
878 * @param cursorVisible if true, this widget has a cursor
880 public final void setCursorVisible(final boolean cursorVisible
) {
881 this.cursorVisible
= cursorVisible
;
885 * See if this widget has a visible cursor.
887 * @return if true, this widget has a visible cursor
889 public final boolean isCursorVisible() {
890 // If cursor is out of my bounds, it is not visible.
891 if ((cursorX
>= width
)
893 || (cursorY
>= height
)
899 // If cursor is out of my window's bounds, it is not visible.
900 if ((getCursorAbsoluteX() >= window
.getAbsoluteX()
901 + window
.getWidth() - 1)
902 || (getCursorAbsoluteX() < 0)
903 || (getCursorAbsoluteY() >= window
.getAbsoluteY()
904 + window
.getHeight() - 1)
905 || (getCursorAbsoluteY() < 0)
909 return cursorVisible
;
913 * Get cursor X value.
915 * @return cursor column position in relative coordinates
917 public final int getCursorX() {
922 * Set cursor X value.
924 * @param cursorX column position in relative coordinates
926 public final void setCursorX(final int cursorX
) {
927 this.cursorX
= cursorX
;
931 * Get cursor Y value.
933 * @return cursor row position in relative coordinates
935 public final int getCursorY() {
940 * Set cursor Y value.
942 * @param cursorY row position in relative coordinates
944 public final void setCursorY(final int cursorY
) {
945 this.cursorY
= cursorY
;
949 * Get this TWidget's parent TApplication.
951 * @return the parent TApplication
953 public TApplication
getApplication() {
954 return window
.getApplication();
962 public Screen
getScreen() {
963 return window
.getScreen();
967 * Comparison operator. For various subclasses it sorts on:
969 * <li>tabOrder for TWidgets</li>
970 * <li>z for TWindows</li>
971 * <li>text for TTreeItems</li>
974 * @param that another TWidget, TWindow, or TTreeItem instance
975 * @return difference between this.tabOrder and that.tabOrder, or
976 * difference between this.z and that.z, or String.compareTo(text)
978 public final int compareTo(final TWidget that
) {
979 if ((this instanceof TWindow
)
980 && (that
instanceof TWindow
)
982 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
984 if ((this instanceof TTreeItem
)
985 && (that
instanceof TTreeItem
)
987 return (((TTreeItem
) this).getText().compareTo(
988 ((TTreeItem
) that
).getText()));
990 return (this.tabOrder
- that
.tabOrder
);
994 * See if this widget should render with the active color.
996 * @return true if this widget is active and all of its parents are
999 public final boolean isAbsoluteActive() {
1000 if (parent
== this) {
1003 return (active
&& parent
.isAbsoluteActive());
1007 * Returns the cursor X position.
1009 * @return absolute screen column number for the cursor's X position
1011 public final int getCursorAbsoluteX() {
1012 return getAbsoluteX() + cursorX
;
1016 * Returns the cursor Y position.
1018 * @return absolute screen row number for the cursor's Y position
1020 public final int getCursorAbsoluteY() {
1021 return getAbsoluteY() + cursorY
;
1025 * Compute my absolute X position as the sum of my X plus all my parent's
1028 * @return absolute screen column number for my X position
1030 public final int getAbsoluteX() {
1031 assert (parent
!= null);
1032 if (parent
== this) {
1035 if ((parent
instanceof TWindow
)
1036 && !(parent
instanceof TMenu
)
1037 && !(parent
instanceof TDesktop
)
1039 // Widgets on a TWindow have (0,0) as their top-left, but this is
1040 // actually the TWindow's (1,1).
1041 return parent
.getAbsoluteX() + x
+ 1;
1043 return parent
.getAbsoluteX() + x
;
1047 * Compute my absolute Y position as the sum of my Y plus all my parent's
1050 * @return absolute screen row number for my Y position
1052 public final int getAbsoluteY() {
1053 assert (parent
!= null);
1054 if (parent
== this) {
1057 if ((parent
instanceof TWindow
)
1058 && !(parent
instanceof TMenu
)
1059 && !(parent
instanceof TDesktop
)
1061 // Widgets on a TWindow have (0,0) as their top-left, but this is
1062 // actually the TWindow's (1,1).
1063 return parent
.getAbsoluteY() + y
+ 1;
1065 return parent
.getAbsoluteY() + y
;
1069 * Get the global color theme.
1071 * @return the ColorTheme
1073 protected final ColorTheme
getTheme() {
1074 return window
.getApplication().getTheme();
1078 * Draw my specific widget. When called, the screen rectangle I draw
1079 * into is already setup (offset and clipping).
1081 public void draw() {
1082 // Default widget draws nothing.
1086 * Called by parent to render to TWindow. Note package private access.
1088 final void drawChildren() {
1089 // Set my clipping rectangle
1090 assert (window
!= null);
1091 assert (getScreen() != null);
1092 Screen screen
= getScreen();
1094 // Special case: TStatusBar is drawn by TApplication, not anything
1096 if (this instanceof TStatusBar
) {
1100 screen
.setClipRight(width
);
1101 screen
.setClipBottom(height
);
1103 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
1104 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
1105 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
1106 absoluteRightEdge
-= 1;
1108 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
1109 absoluteBottomEdge
-= 1;
1111 int myRightEdge
= getAbsoluteX() + width
;
1112 int myBottomEdge
= getAbsoluteY() + height
;
1113 if (getAbsoluteX() > absoluteRightEdge
) {
1115 screen
.setClipRight(0);
1116 } else if (myRightEdge
> absoluteRightEdge
) {
1117 screen
.setClipRight(screen
.getClipRight()
1118 - (myRightEdge
- absoluteRightEdge
));
1120 if (getAbsoluteY() > absoluteBottomEdge
) {
1122 screen
.setClipBottom(0);
1123 } else if (myBottomEdge
> absoluteBottomEdge
) {
1124 screen
.setClipBottom(screen
.getClipBottom()
1125 - (myBottomEdge
- absoluteBottomEdge
));
1129 screen
.setOffsetX(getAbsoluteX());
1130 screen
.setOffsetY(getAbsoluteY());
1134 assert (visible
== true);
1136 // Continue down the chain. Draw the active child last so that it
1138 for (TWidget widget
: children
) {
1139 if (widget
.isVisible() && (widget
!= activeChild
)) {
1140 widget
.drawChildren();
1143 if (activeChild
!= null) {
1144 activeChild
.drawChildren();
1149 * Repaint the screen on the next update.
1151 protected final void doRepaint() {
1152 window
.getApplication().doRepaint();
1156 * Add a child widget to my list of children. We set its tabOrder to 0
1157 * and increment the tabOrder of all other children.
1159 * @param child TWidget to add
1161 private void addChild(final TWidget child
) {
1162 children
.add(child
);
1165 && !(child
instanceof THScroller
)
1166 && !(child
instanceof TVScroller
)
1168 for (TWidget widget
: children
) {
1169 widget
.active
= false;
1171 child
.active
= true;
1172 activeChild
= child
;
1174 for (int i
= 0; i
< children
.size(); i
++) {
1175 children
.get(i
).tabOrder
= i
;
1180 * Reset the tab order of children to match their position in the list.
1181 * Available so that subclasses can re-order their widgets if needed.
1183 protected void resetTabOrder() {
1184 for (int i
= 0; i
< children
.size(); i
++) {
1185 children
.get(i
).tabOrder
= i
;
1190 * Switch the active child.
1192 * @param child TWidget to activate
1194 public final void activate(final TWidget child
) {
1195 assert (child
.enabled
);
1196 if ((child
instanceof THScroller
)
1197 || (child
instanceof TVScroller
)
1202 if (children
.size() == 1) {
1203 if (children
.get(0).enabled
== true) {
1204 child
.active
= true;
1205 activeChild
= child
;
1208 if (child
!= activeChild
) {
1209 if (activeChild
!= null) {
1210 activeChild
.active
= false;
1212 child
.active
= true;
1213 activeChild
= child
;
1219 * Switch the active child.
1221 * @param tabOrder tabOrder of the child to activate. If that child
1222 * isn't enabled, then the next enabled child will be activated.
1224 public final void activate(final int tabOrder
) {
1225 if (children
.size() == 1) {
1226 if (children
.get(0).enabled
== true) {
1227 children
.get(0).active
= true;
1228 activeChild
= children
.get(0);
1233 TWidget child
= null;
1234 for (TWidget widget
: children
) {
1235 if ((widget
.enabled
)
1236 && !(widget
instanceof THScroller
)
1237 && !(widget
instanceof TVScroller
)
1238 && (widget
.tabOrder
>= tabOrder
)
1244 if ((child
!= null) && (child
!= activeChild
)) {
1245 if (activeChild
!= null) {
1246 activeChild
.active
= false;
1248 assert (child
.enabled
);
1249 child
.active
= true;
1250 activeChild
= child
;
1255 * Switch the active widget with the next in the tab order.
1257 * @param forward if true, then switch to the next enabled widget in the
1258 * list, otherwise switch to the previous enabled widget in the list
1260 public final void switchWidget(final boolean forward
) {
1262 // No children: do nothing.
1263 if (children
.size() == 0) {
1267 // If there is only one child, make it active if it is enabled.
1268 if (children
.size() == 1) {
1269 if (children
.get(0).enabled
== true) {
1270 activeChild
= children
.get(0);
1271 activeChild
.active
= true;
1273 children
.get(0).active
= false;
1279 // Two or more children: go forward or backward to the next enabled
1282 if (activeChild
!= null) {
1283 tabOrder
= activeChild
.tabOrder
;
1293 // If at the end, pass the switch to my parent.
1294 if ((!forward
) && (parent
!= this)) {
1295 parent
.switchWidget(forward
);
1299 tabOrder
= children
.size() - 1;
1300 } else if (tabOrder
== children
.size()) {
1301 // If at the end, pass the switch to my parent.
1302 if ((forward
) && (parent
!= this)) {
1303 parent
.switchWidget(forward
);
1309 if (activeChild
== null) {
1310 if (tabOrder
== 0) {
1311 // We wrapped around
1314 } else if (activeChild
.tabOrder
== tabOrder
) {
1315 // We wrapped around
1318 } while ((!children
.get(tabOrder
).enabled
)
1319 && !(children
.get(tabOrder
) instanceof THScroller
)
1320 && !(children
.get(tabOrder
) instanceof TVScroller
));
1322 if (activeChild
!= null) {
1323 assert (children
.get(tabOrder
).enabled
);
1325 activeChild
.active
= false;
1327 if (children
.get(tabOrder
).enabled
== true) {
1328 children
.get(tabOrder
).active
= true;
1329 activeChild
= children
.get(tabOrder
);
1334 * Returns my active widget.
1336 * @return widget that is active, or this if no children
1338 public TWidget
getActiveChild() {
1339 if ((this instanceof THScroller
)
1340 || (this instanceof TVScroller
)
1345 for (TWidget widget
: children
) {
1346 if (widget
.active
) {
1347 return widget
.getActiveChild();
1350 // No active children, return me
1354 // ------------------------------------------------------------------------
1355 // Passthru for Screen functions ------------------------------------------
1356 // ------------------------------------------------------------------------
1359 * Get the attributes at one location.
1361 * @param x column coordinate. 0 is the left-most column.
1362 * @param y row coordinate. 0 is the top-most row.
1363 * @return attributes at (x, y)
1365 protected final CellAttributes
getAttrXY(final int x
, final int y
) {
1366 return getScreen().getAttrXY(x
, y
);
1370 * Set the attributes at one location.
1372 * @param x column coordinate. 0 is the left-most column.
1373 * @param y row coordinate. 0 is the top-most row.
1374 * @param attr attributes to use (bold, foreColor, backColor)
1376 protected final void putAttrXY(final int x
, final int y
,
1377 final CellAttributes attr
) {
1379 getScreen().putAttrXY(x
, y
, attr
);
1383 * Set the attributes at one location.
1385 * @param x column coordinate. 0 is the left-most column.
1386 * @param y row coordinate. 0 is the top-most row.
1387 * @param attr attributes to use (bold, foreColor, backColor)
1388 * @param clip if true, honor clipping/offset
1390 protected final void putAttrXY(final int x
, final int y
,
1391 final CellAttributes attr
, final boolean clip
) {
1393 getScreen().putAttrXY(x
, y
, attr
, clip
);
1397 * Fill the entire screen with one character with attributes.
1399 * @param ch character to draw
1400 * @param attr attributes to use (bold, foreColor, backColor)
1402 protected final void putAll(final char ch
, final CellAttributes attr
) {
1403 getScreen().putAll(ch
, attr
);
1407 * Render one character with attributes.
1409 * @param x column coordinate. 0 is the left-most column.
1410 * @param y row coordinate. 0 is the top-most row.
1411 * @param ch character + attributes to draw
1413 protected final void putCharXY(final int x
, final int y
, final Cell ch
) {
1414 getScreen().putCharXY(x
, y
, ch
);
1418 * Render one character with attributes.
1420 * @param x column coordinate. 0 is the left-most column.
1421 * @param y row coordinate. 0 is the top-most row.
1422 * @param ch character to draw
1423 * @param attr attributes to use (bold, foreColor, backColor)
1425 protected final void putCharXY(final int x
, final int y
, final char ch
,
1426 final CellAttributes attr
) {
1428 getScreen().putCharXY(x
, y
, ch
, attr
);
1432 * Render one character without changing the underlying attributes.
1434 * @param x column coordinate. 0 is the left-most column.
1435 * @param y row coordinate. 0 is the top-most row.
1436 * @param ch character to draw
1438 protected final void putCharXY(final int x
, final int y
, final char ch
) {
1439 getScreen().putCharXY(x
, y
, ch
);
1443 * Render a string. Does not wrap if the string exceeds the line.
1445 * @param x column coordinate. 0 is the left-most column.
1446 * @param y row coordinate. 0 is the top-most row.
1447 * @param str string to draw
1448 * @param attr attributes to use (bold, foreColor, backColor)
1450 protected final void putStringXY(final int x
, final int y
, final String str
,
1451 final CellAttributes attr
) {
1453 getScreen().putStringXY(x
, y
, str
, attr
);
1457 * Render a string without changing the underlying attribute. Does not
1458 * wrap if the string exceeds the line.
1460 * @param x column coordinate. 0 is the left-most column.
1461 * @param y row coordinate. 0 is the top-most row.
1462 * @param str string to draw
1464 protected final void putStringXY(final int x
, final int y
, final String str
) {
1465 getScreen().putStringXY(x
, y
, str
);
1469 * Draw a vertical line from (x, y) to (x, y + n).
1471 * @param x column coordinate. 0 is the left-most column.
1472 * @param y row coordinate. 0 is the top-most row.
1473 * @param n number of characters to draw
1474 * @param ch character to draw
1475 * @param attr attributes to use (bold, foreColor, backColor)
1477 protected final void vLineXY(final int x
, final int y
, final int n
,
1478 final char ch
, final CellAttributes attr
) {
1480 getScreen().vLineXY(x
, y
, n
, ch
, attr
);
1484 * Draw a horizontal line from (x, y) to (x + n, y).
1486 * @param x column coordinate. 0 is the left-most column.
1487 * @param y row coordinate. 0 is the top-most row.
1488 * @param n number of characters to draw
1489 * @param ch character to draw
1490 * @param attr attributes to use (bold, foreColor, backColor)
1492 protected final void hLineXY(final int x
, final int y
, final int n
,
1493 final char ch
, final CellAttributes attr
) {
1495 getScreen().hLineXY(x
, y
, n
, ch
, attr
);
1499 * Draw a box with a border and empty background.
1501 * @param left left column of box. 0 is the left-most row.
1502 * @param top top row of the box. 0 is the top-most row.
1503 * @param right right column of box
1504 * @param bottom bottom row of the box
1505 * @param border attributes to use for the border
1506 * @param background attributes to use for the background
1508 protected final void drawBox(final int left
, final int top
,
1509 final int right
, final int bottom
,
1510 final CellAttributes border
, final CellAttributes background
) {
1512 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
);
1516 * Draw a box with a border and empty background.
1518 * @param left left column of box. 0 is the left-most row.
1519 * @param top top row of the box. 0 is the top-most row.
1520 * @param right right column of box
1521 * @param bottom bottom row of the box
1522 * @param border attributes to use for the border
1523 * @param background attributes to use for the background
1524 * @param borderType if 1, draw a single-line border; if 2, draw a
1525 * double-line border; if 3, draw double-line top/bottom edges and
1526 * single-line left/right edges (like Qmodem)
1527 * @param shadow if true, draw a "shadow" on the box
1529 protected final void drawBox(final int left
, final int top
,
1530 final int right
, final int bottom
,
1531 final CellAttributes border
, final CellAttributes background
,
1532 final int borderType
, final boolean shadow
) {
1534 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
,
1535 borderType
, shadow
);
1539 * Draw a box shadow.
1541 * @param left left column of box. 0 is the left-most row.
1542 * @param top top row of the box. 0 is the top-most row.
1543 * @param right right column of box
1544 * @param bottom bottom row of the box
1546 protected final void drawBoxShadow(final int left
, final int top
,
1547 final int right
, final int bottom
) {
1549 getScreen().drawBoxShadow(left
, top
, right
, bottom
);
1552 // ------------------------------------------------------------------------
1553 // Other TWidget constructors ---------------------------------------------
1554 // ------------------------------------------------------------------------
1557 * Convenience function to add a label to this container/window.
1560 * @param x column relative to parent
1561 * @param y row relative to parent
1562 * @return the new label
1564 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1565 return addLabel(text
, x
, y
, "tlabel");
1569 * Convenience function to add a label to this container/window.
1572 * @param x column relative to parent
1573 * @param y row relative to parent
1574 * @param action to call when shortcut is pressed
1575 * @return the new label
1577 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1578 final TAction action
) {
1580 return addLabel(text
, x
, y
, "tlabel", action
);
1584 * Convenience function to add a label to this container/window.
1587 * @param x column relative to parent
1588 * @param y row relative to parent
1589 * @param colorKey ColorTheme key color to use for foreground text.
1590 * Default is "tlabel"
1591 * @return the new label
1593 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1594 final String colorKey
) {
1596 return new TLabel(this, text
, x
, y
, colorKey
);
1600 * Convenience function to add a label to this container/window.
1603 * @param x column relative to parent
1604 * @param y row relative to parent
1605 * @param colorKey ColorTheme key color to use for foreground text.
1606 * Default is "tlabel"
1607 * @param action to call when shortcut is pressed
1608 * @return the new label
1610 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1611 final String colorKey
, final TAction action
) {
1613 return new TLabel(this, text
, x
, y
, colorKey
, action
);
1617 * Convenience function to add a label to this container/window.
1620 * @param x column relative to parent
1621 * @param y row relative to parent
1622 * @param colorKey ColorTheme key color to use for foreground text.
1623 * Default is "tlabel"
1624 * @param useWindowBackground if true, use the window's background color
1625 * @return the new label
1627 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1628 final String colorKey
, final boolean useWindowBackground
) {
1630 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
);
1634 * Convenience function to add a label to this container/window.
1637 * @param x column relative to parent
1638 * @param y row relative to parent
1639 * @param colorKey ColorTheme key color to use for foreground text.
1640 * Default is "tlabel"
1641 * @param useWindowBackground if true, use the window's background color
1642 * @param action to call when shortcut is pressed
1643 * @return the new label
1645 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1646 final String colorKey
, final boolean useWindowBackground
,
1647 final TAction action
) {
1649 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
,
1654 * Convenience function to add a button to this container/window.
1656 * @param text label on the button
1657 * @param x column relative to parent
1658 * @param y row relative to parent
1659 * @param action action to call when button is pressed
1660 * @return the new button
1662 public final TButton
addButton(final String text
, final int x
, final int y
,
1663 final TAction action
) {
1665 return new TButton(this, text
, x
, y
, action
);
1669 * Convenience function to add a checkbox to this container/window.
1671 * @param x column relative to parent
1672 * @param y row relative to parent
1673 * @param label label to display next to (right of) the checkbox
1674 * @param checked initial check state
1675 * @return the new checkbox
1677 public final TCheckBox
addCheckBox(final int x
, final int y
,
1678 final String label
, final boolean checked
) {
1680 return new TCheckBox(this, x
, y
, label
, checked
);
1684 * Convenience function to add a combobox to this container/window.
1686 * @param x column relative to parent
1687 * @param y row relative to parent
1688 * @param width visible combobox width, including the down-arrow
1689 * @param values the possible values for the box, shown in the drop-down
1690 * @param valuesIndex the initial index in values, or -1 for no default
1692 * @param valuesHeight the height of the values drop-down when it is
1694 * @param updateAction action to call when a new value is selected from
1695 * the list or enter is pressed in the edit field
1696 * @return the new combobox
1698 public final TComboBox
addComboBox(final int x
, final int y
,
1699 final int width
, final List
<String
> values
, final int valuesIndex
,
1700 final int valuesHeight
, final TAction updateAction
) {
1702 return new TComboBox(this, x
, y
, width
, values
, valuesIndex
,
1703 valuesHeight
, updateAction
);
1707 * Convenience function to add a spinner to this container/window.
1709 * @param x column relative to parent
1710 * @param y row relative to parent
1711 * @param upAction action to call when the up arrow is clicked or pressed
1712 * @param downAction action to call when the down arrow is clicked or
1714 * @return the new spinner
1716 public final TSpinner
addSpinner(final int x
, final int y
,
1717 final TAction upAction
, final TAction downAction
) {
1719 return new TSpinner(this, x
, y
, upAction
, downAction
);
1723 * Convenience function to add a calendar to this container/window.
1725 * @param x column relative to parent
1726 * @param y row relative to parent
1727 * @param updateAction action to call when the user changes the value of
1729 * @return the new calendar
1731 public final TCalendar
addCalendar(final int x
, final int y
,
1732 final TAction updateAction
) {
1734 return new TCalendar(this, x
, y
, updateAction
);
1738 * Convenience function to add a progress bar to this container/window.
1740 * @param x column relative to parent
1741 * @param y row relative to parent
1742 * @param width width of progress bar
1743 * @param value initial value of percent complete
1744 * @return the new progress bar
1746 public final TProgressBar
addProgressBar(final int x
, final int y
,
1747 final int width
, final int value
) {
1749 return new TProgressBar(this, x
, y
, width
, value
);
1753 * Convenience function to add a radio button group to this
1756 * @param x column relative to parent
1757 * @param y row relative to parent
1758 * @param label label to display on the group box
1759 * @return the new radio button group
1761 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1762 final String label
) {
1764 return new TRadioGroup(this, x
, y
, label
);
1768 * Convenience function to add a text field to this container/window.
1770 * @param x column relative to parent
1771 * @param y row relative to parent
1772 * @param width visible text width
1773 * @param fixed if true, the text cannot exceed the display width
1774 * @return the new text field
1776 public final TField
addField(final int x
, final int y
,
1777 final int width
, final boolean fixed
) {
1779 return new TField(this, x
, y
, width
, fixed
);
1783 * Convenience function to add a text field to this container/window.
1785 * @param x column relative to parent
1786 * @param y row relative to parent
1787 * @param width visible text width
1788 * @param fixed if true, the text cannot exceed the display width
1789 * @param text initial text, default is empty string
1790 * @return the new text field
1792 public final TField
addField(final int x
, final int y
,
1793 final int width
, final boolean fixed
, final String text
) {
1795 return new TField(this, x
, y
, width
, fixed
, text
);
1799 * Convenience function to add a text field to this container/window.
1801 * @param x column relative to parent
1802 * @param y row relative to parent
1803 * @param width visible text width
1804 * @param fixed if true, the text cannot exceed the display width
1805 * @param text initial text, default is empty string
1806 * @param enterAction function to call when enter key is pressed
1807 * @param updateAction function to call when the text is updated
1808 * @return the new text field
1810 public final TField
addField(final int x
, final int y
,
1811 final int width
, final boolean fixed
, final String text
,
1812 final TAction enterAction
, final TAction updateAction
) {
1814 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1819 * Convenience function to add a scrollable text box to this
1822 * @param text text on the screen
1823 * @param x column relative to parent
1824 * @param y row relative to parent
1825 * @param width width of text area
1826 * @param height height of text area
1827 * @param colorKey ColorTheme key color to use for foreground text
1828 * @return the new text box
1830 public final TText
addText(final String text
, final int x
,
1831 final int y
, final int width
, final int height
, final String colorKey
) {
1833 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1837 * Convenience function to add a scrollable text box to this
1840 * @param text text on the screen
1841 * @param x column relative to parent
1842 * @param y row relative to parent
1843 * @param width width of text area
1844 * @param height height of text area
1845 * @return the new text box
1847 public final TText
addText(final String text
, final int x
, final int y
,
1848 final int width
, final int height
) {
1850 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1854 * Convenience function to add an editable text area box to this
1857 * @param text text on the screen
1858 * @param x column relative to parent
1859 * @param y row relative to parent
1860 * @param width width of text area
1861 * @param height height of text area
1862 * @return the new text box
1864 public final TEditorWidget
addEditor(final String text
, final int x
,
1865 final int y
, final int width
, final int height
) {
1867 return new TEditorWidget(this, text
, x
, y
, width
, height
);
1871 * Convenience function to spawn a message box.
1873 * @param title window title, will be centered along the top border
1874 * @param caption message to display. Use embedded newlines to get a
1876 * @return the new message box
1878 public final TMessageBox
messageBox(final String title
,
1879 final String caption
) {
1881 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
1885 * Convenience function to spawn a message box.
1887 * @param title window title, will be centered along the top border
1888 * @param caption message to display. Use embedded newlines to get a
1890 * @param type one of the TMessageBox.Type constants. Default is
1892 * @return the new message box
1894 public final TMessageBox
messageBox(final String title
,
1895 final String caption
, final TMessageBox
.Type type
) {
1897 return getApplication().messageBox(title
, caption
, type
);
1901 * Convenience function to spawn an input box.
1903 * @param title window title, will be centered along the top border
1904 * @param caption message to display. Use embedded newlines to get a
1906 * @return the new input box
1908 public final TInputBox
inputBox(final String title
, final String caption
) {
1910 return getApplication().inputBox(title
, caption
);
1914 * Convenience function to spawn an input box.
1916 * @param title window title, will be centered along the top border
1917 * @param caption message to display. Use embedded newlines to get a
1919 * @param text initial text to seed the field with
1920 * @return the new input box
1922 public final TInputBox
inputBox(final String title
, final String caption
,
1923 final String text
) {
1925 return getApplication().inputBox(title
, caption
, text
);
1929 * Convenience function to spawn an input box.
1931 * @param title window title, will be centered along the top border
1932 * @param caption message to display. Use embedded newlines to get a
1934 * @param text initial text to seed the field with
1935 * @param type one of the Type constants. Default is Type.OK.
1936 * @return the new input box
1938 public final TInputBox
inputBox(final String title
, final String caption
,
1939 final String text
, final TInputBox
.Type type
) {
1941 return getApplication().inputBox(title
, caption
, text
, type
);
1945 * Convenience function to add a password text field to this
1948 * @param x column relative to parent
1949 * @param y row relative to parent
1950 * @param width visible text width
1951 * @param fixed if true, the text cannot exceed the display width
1952 * @return the new text field
1954 public final TPasswordField
addPasswordField(final int x
, final int y
,
1955 final int width
, final boolean fixed
) {
1957 return new TPasswordField(this, x
, y
, width
, fixed
);
1961 * Convenience function to add a password text field to this
1964 * @param x column relative to parent
1965 * @param y row relative to parent
1966 * @param width visible text width
1967 * @param fixed if true, the text cannot exceed the display width
1968 * @param text initial text, default is empty string
1969 * @return the new text field
1971 public final TPasswordField
addPasswordField(final int x
, final int y
,
1972 final int width
, final boolean fixed
, final String text
) {
1974 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
1978 * Convenience function to add a password text field to this
1981 * @param x column relative to parent
1982 * @param y row relative to parent
1983 * @param width visible text width
1984 * @param fixed if true, the text cannot exceed the display width
1985 * @param text initial text, default is empty string
1986 * @param enterAction function to call when enter key is pressed
1987 * @param updateAction function to call when the text is updated
1988 * @return the new text field
1990 public final TPasswordField
addPasswordField(final int x
, final int y
,
1991 final int width
, final boolean fixed
, final String text
,
1992 final TAction enterAction
, final TAction updateAction
) {
1994 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
1999 * Convenience function to add a scrollable tree view to this
2002 * @param x column relative to parent
2003 * @param y row relative to parent
2004 * @param width width of tree view
2005 * @param height height of tree view
2006 * @return the new tree view
2008 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
2009 final int width
, final int height
) {
2011 return new TTreeViewWidget(this, x
, y
, width
, height
);
2015 * Convenience function to add a scrollable tree view to this
2018 * @param x column relative to parent
2019 * @param y row relative to parent
2020 * @param width width of tree view
2021 * @param height height of tree view
2022 * @param action action to perform when an item is selected
2023 * @return the new tree view
2025 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
2026 final int width
, final int height
, final TAction action
) {
2028 return new TTreeViewWidget(this, x
, y
, width
, height
, action
);
2032 * Convenience function to spawn a file open box.
2034 * @param path path of selected file
2035 * @return the result of the new file open box
2036 * @throws IOException if a java.io operation throws
2038 public final String
fileOpenBox(final String path
) throws IOException
{
2039 return getApplication().fileOpenBox(path
);
2043 * Convenience function to spawn a file save box.
2045 * @param path path of selected file
2046 * @return the result of the new file open box
2047 * @throws IOException if a java.io operation throws
2049 public final String
fileSaveBox(final String path
) throws IOException
{
2050 return getApplication().fileOpenBox(path
, TFileOpenBox
.Type
.SAVE
);
2054 * Convenience function to spawn a file open box.
2056 * @param path path of selected file
2057 * @param type one of the Type constants
2058 * @return the result of the new file open box
2059 * @throws IOException if a java.io operation throws
2061 public final String
fileOpenBox(final String path
,
2062 final TFileOpenBox
.Type type
) throws IOException
{
2064 return getApplication().fileOpenBox(path
, type
);
2068 * Convenience function to spawn a file open box.
2070 * @param path path of selected file
2071 * @param type one of the Type constants
2072 * @param filter a string that files must match to be displayed
2073 * @return the result of the new file open box
2074 * @throws IOException of a java.io operation throws
2076 public final String
fileOpenBox(final String path
,
2077 final TFileOpenBox
.Type type
, final String filter
) throws IOException
{
2079 ArrayList
<String
> filters
= new ArrayList
<String
>();
2080 filters
.add(filter
);
2082 return getApplication().fileOpenBox(path
, type
, filters
);
2086 * Convenience function to spawn a file open box.
2088 * @param path path of selected file
2089 * @param type one of the Type constants
2090 * @param filters a list of strings that files must match to be displayed
2091 * @return the result of the new file open box
2092 * @throws IOException of a java.io operation throws
2094 public final String
fileOpenBox(final String path
,
2095 final TFileOpenBox
.Type type
,
2096 final List
<String
> filters
) throws IOException
{
2098 return getApplication().fileOpenBox(path
, type
, filters
);
2102 * Convenience function to add a directory list to this container/window.
2104 * @param path directory path, must be a directory
2105 * @param x column relative to parent
2106 * @param y row relative to parent
2107 * @param width width of text area
2108 * @param height height of text area
2109 * @return the new directory list
2111 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2112 final int y
, final int width
, final int height
) {
2114 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
2118 * Convenience function to add a directory list to this container/window.
2120 * @param path directory path, must be a directory
2121 * @param x column relative to parent
2122 * @param y row relative to parent
2123 * @param width width of text area
2124 * @param height height of text area
2125 * @param action action to perform when an item is selected (enter or
2127 * @return the new directory list
2129 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2130 final int y
, final int width
, final int height
, final TAction action
) {
2132 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
2136 * Convenience function to add a directory list to this container/window.
2138 * @param path directory path, must be a directory
2139 * @param x column relative to parent
2140 * @param y row relative to parent
2141 * @param width width of text area
2142 * @param height height of text area
2143 * @param action action to perform when an item is selected (enter or
2145 * @param singleClickAction action to perform when an item is selected
2147 * @return the new directory list
2149 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2150 final int y
, final int width
, final int height
, final TAction action
,
2151 final TAction singleClickAction
) {
2153 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2158 * Convenience function to add a directory list to this container/window.
2160 * @param path directory path, must be a directory
2161 * @param x column relative to parent
2162 * @param y row relative to parent
2163 * @param width width of text area
2164 * @param height height of text area
2165 * @param action action to perform when an item is selected (enter or
2167 * @param singleClickAction action to perform when an item is selected
2169 * @param filters a list of strings that files must match to be displayed
2170 * @return the new directory list
2172 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2173 final int y
, final int width
, final int height
, final TAction action
,
2174 final TAction singleClickAction
, final List
<String
> filters
) {
2176 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2177 singleClickAction
, filters
);
2181 * Convenience function to add a list to this container/window.
2183 * @param strings list of strings to show
2184 * @param x column relative to parent
2185 * @param y row relative to parent
2186 * @param width width of text area
2187 * @param height height of text area
2188 * @return the new directory list
2190 public final TList
addList(final List
<String
> strings
, final int x
,
2191 final int y
, final int width
, final int height
) {
2193 return new TList(this, strings
, x
, y
, width
, height
, null);
2197 * Convenience function to add a list to this container/window.
2199 * @param strings list of strings to show
2200 * @param x column relative to parent
2201 * @param y row relative to parent
2202 * @param width width of text area
2203 * @param height height of text area
2204 * @param enterAction action to perform when an item is selected
2205 * @return the new directory list
2207 public final TList
addList(final List
<String
> strings
, final int x
,
2208 final int y
, final int width
, final int height
,
2209 final TAction enterAction
) {
2211 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
2215 * Convenience function to add a list to this container/window.
2217 * @param strings list of strings to show
2218 * @param x column relative to parent
2219 * @param y row relative to parent
2220 * @param width width of text area
2221 * @param height height of text area
2222 * @param enterAction action to perform when an item is selected
2223 * @param moveAction action to perform when the user navigates to a new
2224 * item with arrow/page keys
2225 * @return the new directory list
2227 public final TList
addList(final List
<String
> strings
, final int x
,
2228 final int y
, final int width
, final int height
,
2229 final TAction enterAction
, final TAction moveAction
) {
2231 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,
2236 * Convenience function to add an image to this container/window.
2238 * @param x column relative to parent
2239 * @param y row relative to parent
2240 * @param width number of text cells for width of the image
2241 * @param height number of text cells for height of the image
2242 * @param image the image to display
2243 * @param left left column of the image. 0 is the left-most column.
2244 * @param top top row of the image. 0 is the top-most row.
2246 public final TImage
addImage(final int x
, final int y
,
2247 final int width
, final int height
,
2248 final BufferedImage image
, final int left
, final int top
) {
2250 return new TImage(this, x
, y
, width
, height
, image
, left
, top
);
2254 * Convenience function to add an image to this container/window.
2256 * @param x column relative to parent
2257 * @param y row relative to parent
2258 * @param width number of text cells for width of the image
2259 * @param height number of text cells for height of the image
2260 * @param image the image to display
2261 * @param left left column of the image. 0 is the left-most column.
2262 * @param top top row of the image. 0 is the top-most row.
2263 * @param clickAction function to call when mouse is pressed
2265 public final TImage
addImage(final int x
, final int y
,
2266 final int width
, final int height
,
2267 final BufferedImage image
, final int left
, final int top
,
2268 final TAction clickAction
) {
2270 return new TImage(this, x
, y
, width
, height
, image
, left
, top
,
2275 * Convenience function to add an editable 2D data table to this
2278 * @param x column relative to parent
2279 * @param y row relative to parent
2280 * @param width width of widget
2281 * @param height height of widget
2283 public TTableWidget
addTable(final int x
, final int y
, final int width
,
2286 return new TTableWidget(this, x
, y
, width
, height
);
2290 * Convenience function to add an editable 2D data table to this
2293 * @param x column relative to parent
2294 * @param y row relative to parent
2295 * @param width width of widget
2296 * @param height height of widget
2297 * @param gridColumns number of columns in grid
2298 * @param gridRows number of rows in grid
2300 public TTableWidget
addTable(final int x
, final int y
, final int width
,
2301 final int height
, final int gridColumns
, final int gridRows
) {
2303 return new TTableWidget(this, x
, y
, width
, height
, gridColumns
,