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
) {
207 this.enabled
= enabled
;
208 this.parent
= parent
;
209 this.window
= parent
.window
;
210 children
= new ArrayList
<TWidget
>();
212 // Do not add TStatusBars, they are drawn by TApplication.
213 if (this instanceof TStatusBar
) {
216 parent
.addChild(this);
222 this.height
= height
;
226 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
228 * @param window the top-level window
229 * @param x column relative to parent
230 * @param y row relative to parent
231 * @param width width of window
232 * @param height height of window
234 protected final void setupForTWindow(final TWindow window
,
235 final int x
, final int y
, final int width
, final int height
) {
237 this.parent
= window
;
238 this.window
= window
;
242 this.height
= height
;
245 // ------------------------------------------------------------------------
246 // Event handlers ---------------------------------------------------------
247 // ------------------------------------------------------------------------
250 * Subclasses should override this method to cleanup resources. This is
251 * called by TWindow.onClose().
253 protected void close() {
254 // Default: call close() on children.
255 for (TWidget w
: getChildren()) {
261 * Check if a mouse press/release event coordinate is contained in this
264 * @param mouse a mouse-based event
265 * @return whether or not a mouse click would be sent to this widget
267 public final boolean mouseWouldHit(final TMouseEvent mouse
) {
273 if ((this instanceof TTreeItem
)
274 && ((y
< 0) || (y
> parent
.getHeight() - 1))
279 if ((mouse
.getAbsoluteX() >= getAbsoluteX())
280 && (mouse
.getAbsoluteX() < getAbsoluteX() + width
)
281 && (mouse
.getAbsoluteY() >= getAbsoluteY())
282 && (mouse
.getAbsoluteY() < getAbsoluteY() + height
)
290 * Method that subclasses can override to handle keystrokes.
292 * @param keypress keystroke event
294 public void onKeypress(final TKeypressEvent keypress
) {
296 if ((children
.size() == 0)
297 || (this instanceof TTreeView
)
298 || (this instanceof TText
)
299 || (this instanceof TComboBox
)
303 // tab / shift-tab - switch to next/previous widget
304 // left-arrow or up-arrow: same as shift-tab
305 if ((keypress
.equals(kbTab
))
306 || (keypress
.equals(kbDown
) && !(this instanceof TComboBox
))
308 parent
.switchWidget(true);
310 } else if ((keypress
.equals(kbShiftTab
))
311 || (keypress
.equals(kbBackTab
))
312 || (keypress
.equals(kbUp
) && !(this instanceof TComboBox
))
314 parent
.switchWidget(false);
319 if ((children
.size() == 0)
320 && !(this instanceof TTreeView
)
324 // right-arrow or down-arrow: same as tab
325 if (keypress
.equals(kbRight
)) {
326 parent
.switchWidget(true);
328 } else if (keypress
.equals(kbLeft
)) {
329 parent
.switchWidget(false);
334 // If I have any buttons on me AND this is an Alt-key that matches
335 // its mnemonic, send it an Enter keystroke.
336 for (TWidget widget
: children
) {
337 if (widget
instanceof TButton
) {
338 TButton button
= (TButton
) widget
;
339 if (button
.isEnabled()
340 && !keypress
.getKey().isFnKey()
341 && keypress
.getKey().isAlt()
342 && !keypress
.getKey().isCtrl()
343 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
344 == Character
.toLowerCase(keypress
.getKey().getChar()))
347 widget
.onKeypress(new TKeypressEvent(kbEnter
));
353 // If I have any labels on me AND this is an Alt-key that matches
354 // its mnemonic, call its action.
355 for (TWidget widget
: children
) {
356 if (widget
instanceof TLabel
) {
357 TLabel label
= (TLabel
) widget
;
358 if (!keypress
.getKey().isFnKey()
359 && keypress
.getKey().isAlt()
360 && !keypress
.getKey().isCtrl()
361 && (Character
.toLowerCase(label
.getMnemonic().getShortcut())
362 == Character
.toLowerCase(keypress
.getKey().getChar()))
371 // If I have any radiobuttons on me AND this is an Alt-key that
372 // matches its mnemonic, select it and send a Space to it.
373 for (TWidget widget
: children
) {
374 if (widget
instanceof TRadioButton
) {
375 TRadioButton button
= (TRadioButton
) widget
;
376 if (button
.isEnabled()
377 && !keypress
.getKey().isFnKey()
378 && keypress
.getKey().isAlt()
379 && !keypress
.getKey().isCtrl()
380 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
381 == Character
.toLowerCase(keypress
.getKey().getChar()))
384 widget
.onKeypress(new TKeypressEvent(kbSpace
));
388 if (widget
instanceof TRadioGroup
) {
389 for (TWidget child
: widget
.getChildren()) {
390 if (child
instanceof TRadioButton
) {
391 TRadioButton button
= (TRadioButton
) child
;
392 if (button
.isEnabled()
393 && !keypress
.getKey().isFnKey()
394 && keypress
.getKey().isAlt()
395 && !keypress
.getKey().isCtrl()
396 && (Character
.toLowerCase(button
.getMnemonic().getShortcut())
397 == Character
.toLowerCase(keypress
.getKey().getChar()))
400 widget
.activate(child
);
401 child
.onKeypress(new TKeypressEvent(kbSpace
));
409 // If I have any checkboxes on me AND this is an Alt-key that matches
410 // its mnemonic, select it and set it to checked.
411 for (TWidget widget
: children
) {
412 if (widget
instanceof TCheckBox
) {
413 TCheckBox checkBox
= (TCheckBox
) widget
;
414 if (checkBox
.isEnabled()
415 && !keypress
.getKey().isFnKey()
416 && keypress
.getKey().isAlt()
417 && !keypress
.getKey().isCtrl()
418 && (Character
.toLowerCase(checkBox
.getMnemonic().getShortcut())
419 == Character
.toLowerCase(keypress
.getKey().getChar()))
422 checkBox
.setChecked(true);
428 // Dispatch the keypress to an active widget
429 for (TWidget widget
: children
) {
431 widget
.onKeypress(keypress
);
438 * Method that subclasses can override to handle mouse button presses.
440 * @param mouse mouse button event
442 public void onMouseDown(final TMouseEvent mouse
) {
443 // Default: do nothing, pass to children instead
444 if (activeChild
!= null) {
445 if (activeChild
.mouseWouldHit(mouse
)) {
446 // Dispatch to the active child
448 // Set x and y relative to the child's coordinates
449 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
450 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
451 activeChild
.onMouseDown(mouse
);
455 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
456 TWidget widget
= children
.get(i
);
457 if (widget
.mouseWouldHit(mouse
)) {
458 // Dispatch to this child, also activate it
461 // Set x and y relative to the child's coordinates
462 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
463 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
464 widget
.onMouseDown(mouse
);
471 * Method that subclasses can override to handle mouse button releases.
473 * @param mouse mouse button event
475 public void onMouseUp(final TMouseEvent mouse
) {
476 // Default: do nothing, pass to children instead
477 if (activeChild
!= null) {
478 if (activeChild
.mouseWouldHit(mouse
)) {
479 // Dispatch to the active child
481 // Set x and y relative to the child's coordinates
482 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
483 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
484 activeChild
.onMouseUp(mouse
);
488 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
489 TWidget widget
= children
.get(i
);
490 if (widget
.mouseWouldHit(mouse
)) {
491 // Dispatch to this child, also activate it
494 // Set x and y relative to the child's coordinates
495 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
496 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
497 widget
.onMouseUp(mouse
);
504 * Method that subclasses can override to handle mouse movements.
506 * @param mouse mouse motion event
508 public void onMouseMotion(final TMouseEvent mouse
) {
509 // Default: do nothing, pass it on to ALL of my children. This way
510 // the children can see the mouse "leaving" their area.
511 for (TWidget widget
: children
) {
512 // Set x and y relative to the child's coordinates
513 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
514 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
515 widget
.onMouseMotion(mouse
);
520 * Method that subclasses can override to handle mouse button
523 * @param mouse mouse button event
525 public void onMouseDoubleClick(final TMouseEvent mouse
) {
526 // Default: do nothing, pass to children instead
527 if (activeChild
!= null) {
528 if (activeChild
.mouseWouldHit(mouse
)) {
529 // Dispatch to the active child
531 // Set x and y relative to the child's coordinates
532 mouse
.setX(mouse
.getAbsoluteX() - activeChild
.getAbsoluteX());
533 mouse
.setY(mouse
.getAbsoluteY() - activeChild
.getAbsoluteY());
534 activeChild
.onMouseDoubleClick(mouse
);
538 for (int i
= children
.size() - 1 ; i
>= 0 ; i
--) {
539 TWidget widget
= children
.get(i
);
540 if (widget
.mouseWouldHit(mouse
)) {
541 // Dispatch to this child, also activate it
544 // Set x and y relative to the child's coordinates
545 mouse
.setX(mouse
.getAbsoluteX() - widget
.getAbsoluteX());
546 mouse
.setY(mouse
.getAbsoluteY() - widget
.getAbsoluteY());
547 widget
.onMouseDoubleClick(mouse
);
554 * Method that subclasses can override to handle window/screen resize
557 * @param resize resize event
559 public void onResize(final TResizeEvent resize
) {
560 // Default: change my width/height.
561 if (resize
.getType() == TResizeEvent
.Type
.WIDGET
) {
562 width
= resize
.getWidth();
563 height
= resize
.getHeight();
565 // Let children see the screen resize
566 for (TWidget widget
: children
) {
567 widget
.onResize(resize
);
573 * Method that subclasses can override to handle posted command events.
575 * @param command command event
577 public void onCommand(final TCommandEvent command
) {
578 // Default: do nothing, pass to children instead
579 for (TWidget widget
: children
) {
580 widget
.onCommand(command
);
585 * Method that subclasses can override to handle menu or posted menu
588 * @param menu menu event
590 public void onMenu(final TMenuEvent menu
) {
591 // Default: do nothing, pass to children instead
592 for (TWidget widget
: children
) {
598 * Method that subclasses can override to do processing when the UI is
599 * idle. Note that repainting is NOT assumed. To get a refresh after
600 * onIdle, call doRepaint().
602 public void onIdle() {
603 // Default: do nothing, pass to children instead
604 for (TWidget widget
: children
) {
610 * Consume event. Subclasses that want to intercept all events in one go
611 * can override this method.
613 * @param event keyboard, mouse, resize, command, or menu event
615 public void handleEvent(final TInputEvent event
) {
617 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
623 // System.err.println(" -- discard --");
627 if (event
instanceof TKeypressEvent
) {
628 onKeypress((TKeypressEvent
) event
);
629 } else if (event
instanceof TMouseEvent
) {
631 TMouseEvent mouse
= (TMouseEvent
) event
;
633 switch (mouse
.getType()) {
644 onMouseMotion(mouse
);
647 case MOUSE_DOUBLE_CLICK
:
648 onMouseDoubleClick(mouse
);
652 throw new IllegalArgumentException("Invalid mouse event type: "
655 } else if (event
instanceof TResizeEvent
) {
656 onResize((TResizeEvent
) event
);
657 } else if (event
instanceof TCommandEvent
) {
658 onCommand((TCommandEvent
) event
);
659 } else if (event
instanceof TMenuEvent
) {
660 onMenu((TMenuEvent
) event
);
667 // ------------------------------------------------------------------------
668 // TWidget ----------------------------------------------------------------
669 // ------------------------------------------------------------------------
674 * @return parent widget
676 public final TWidget
getParent() {
681 * Get the list of child widgets that this widget contains.
683 * @return the list of child widgets
685 public List
<TWidget
> getChildren() {
692 * @return if true, this widget will receive events
694 public final boolean isActive() {
701 * @param active if true, this widget will receive events
703 public final void setActive(final boolean active
) {
704 this.active
= active
;
708 * Get the window this widget is on.
712 public final TWindow
getWindow() {
719 * @return absolute X position of the top-left corner
721 public final int getX() {
728 * @param x absolute X position of the top-left corner
730 public final void setX(final int x
) {
737 * @return absolute Y position of the top-left corner
739 public final int getY() {
746 * @param y absolute Y position of the top-left corner
748 public final void setY(final int y
) {
755 * @return widget width
757 public final int getWidth() {
764 * @param width new widget width
766 public final void setWidth(final int width
) {
773 * @return widget height
775 public final int getHeight() {
782 * @param height new widget height
784 public final void setHeight(final int height
) {
785 this.height
= height
;
789 * Change the dimensions.
791 * @param x absolute X position of the top-left corner
792 * @param y absolute Y position of the top-left corner
793 * @param width new widget width
794 * @param height new widget height
796 public final void setDimensions(final int x
, final int y
, final int width
,
808 * @return if true, this widget can be tabbed to or receive events
810 public final boolean isEnabled() {
817 * @param enabled if true, this widget can be tabbed to or receive events
819 public final void setEnabled(final boolean enabled
) {
820 this.enabled
= enabled
;
823 // See if there are any active siblings to switch to
824 boolean foundSibling
= false;
825 if (parent
!= null) {
826 for (TWidget w
: parent
.children
) {
828 && !(this instanceof THScroller
)
829 && !(this instanceof TVScroller
)
837 parent
.activeChild
= null;
846 * @param visible if true, this widget will be drawn
848 public final void setVisible(final boolean visible
) {
849 this.visible
= visible
;
853 * See if this widget is visible.
855 * @return if true, this widget will be drawn
857 public final boolean isVisible() {
862 * Set visible cursor flag.
864 * @param cursorVisible if true, this widget has a cursor
866 public final void setCursorVisible(final boolean cursorVisible
) {
867 this.cursorVisible
= cursorVisible
;
871 * See if this widget has a visible cursor.
873 * @return if true, this widget has a visible cursor
875 public final boolean isCursorVisible() {
876 // If cursor is out of my bounds, it is not visible.
877 if ((cursorX
>= width
)
879 || (cursorY
>= height
)
885 // If cursor is out of my window's bounds, it is not visible.
886 if ((getCursorAbsoluteX() >= window
.getAbsoluteX()
887 + window
.getWidth() - 1)
888 || (getCursorAbsoluteX() < 0)
889 || (getCursorAbsoluteY() >= window
.getAbsoluteY()
890 + window
.getHeight() - 1)
891 || (getCursorAbsoluteY() < 0)
895 return cursorVisible
;
899 * Get cursor X value.
901 * @return cursor column position in relative coordinates
903 public final int getCursorX() {
908 * Set cursor X value.
910 * @param cursorX column position in relative coordinates
912 public final void setCursorX(final int cursorX
) {
913 this.cursorX
= cursorX
;
917 * Get cursor Y value.
919 * @return cursor row position in relative coordinates
921 public final int getCursorY() {
926 * Set cursor Y value.
928 * @param cursorY row position in relative coordinates
930 public final void setCursorY(final int cursorY
) {
931 this.cursorY
= cursorY
;
935 * Get this TWidget's parent TApplication.
937 * @return the parent TApplication
939 public TApplication
getApplication() {
940 return window
.getApplication();
948 public Screen
getScreen() {
949 return window
.getScreen();
953 * Comparison operator. For various subclasses it sorts on:
955 * <li>tabOrder for TWidgets</li>
956 * <li>z for TWindows</li>
957 * <li>text for TTreeItems</li>
960 * @param that another TWidget, TWindow, or TTreeItem instance
961 * @return difference between this.tabOrder and that.tabOrder, or
962 * difference between this.z and that.z, or String.compareTo(text)
964 public final int compareTo(final TWidget that
) {
965 if ((this instanceof TWindow
)
966 && (that
instanceof TWindow
)
968 return (((TWindow
) this).getZ() - ((TWindow
) that
).getZ());
970 if ((this instanceof TTreeItem
)
971 && (that
instanceof TTreeItem
)
973 return (((TTreeItem
) this).getText().compareTo(
974 ((TTreeItem
) that
).getText()));
976 return (this.tabOrder
- that
.tabOrder
);
980 * See if this widget should render with the active color.
982 * @return true if this widget is active and all of its parents are
985 public final boolean isAbsoluteActive() {
986 if (parent
== this) {
989 return (active
&& parent
.isAbsoluteActive());
993 * Returns the cursor X position.
995 * @return absolute screen column number for the cursor's X position
997 public final int getCursorAbsoluteX() {
998 return getAbsoluteX() + cursorX
;
1002 * Returns the cursor Y position.
1004 * @return absolute screen row number for the cursor's Y position
1006 public final int getCursorAbsoluteY() {
1007 return getAbsoluteY() + cursorY
;
1011 * Compute my absolute X position as the sum of my X plus all my parent's
1014 * @return absolute screen column number for my X position
1016 public final int getAbsoluteX() {
1017 assert (parent
!= null);
1018 if (parent
== this) {
1021 if ((parent
instanceof TWindow
)
1022 && !(parent
instanceof TMenu
)
1023 && !(parent
instanceof TDesktop
)
1025 // Widgets on a TWindow have (0,0) as their top-left, but this is
1026 // actually the TWindow's (1,1).
1027 return parent
.getAbsoluteX() + x
+ 1;
1029 return parent
.getAbsoluteX() + x
;
1033 * Compute my absolute Y position as the sum of my Y plus all my parent's
1036 * @return absolute screen row number for my Y position
1038 public final int getAbsoluteY() {
1039 assert (parent
!= null);
1040 if (parent
== this) {
1043 if ((parent
instanceof TWindow
)
1044 && !(parent
instanceof TMenu
)
1045 && !(parent
instanceof TDesktop
)
1047 // Widgets on a TWindow have (0,0) as their top-left, but this is
1048 // actually the TWindow's (1,1).
1049 return parent
.getAbsoluteY() + y
+ 1;
1051 return parent
.getAbsoluteY() + y
;
1055 * Get the global color theme.
1057 * @return the ColorTheme
1059 protected final ColorTheme
getTheme() {
1060 return window
.getApplication().getTheme();
1064 * Draw my specific widget. When called, the screen rectangle I draw
1065 * into is already setup (offset and clipping).
1067 public void draw() {
1068 // Default widget draws nothing.
1072 * Called by parent to render to TWindow. Note package private access.
1074 final void drawChildren() {
1075 // Set my clipping rectangle
1076 assert (window
!= null);
1077 assert (getScreen() != null);
1078 Screen screen
= getScreen();
1080 // Special case: TStatusBar is drawn by TApplication, not anything
1082 if (this instanceof TStatusBar
) {
1086 screen
.setClipRight(width
);
1087 screen
.setClipBottom(height
);
1089 int absoluteRightEdge
= window
.getAbsoluteX() + window
.getWidth();
1090 int absoluteBottomEdge
= window
.getAbsoluteY() + window
.getHeight();
1091 if (!(this instanceof TWindow
) && !(this instanceof TVScroller
)) {
1092 absoluteRightEdge
-= 1;
1094 if (!(this instanceof TWindow
) && !(this instanceof THScroller
)) {
1095 absoluteBottomEdge
-= 1;
1097 int myRightEdge
= getAbsoluteX() + width
;
1098 int myBottomEdge
= getAbsoluteY() + height
;
1099 if (getAbsoluteX() > absoluteRightEdge
) {
1101 screen
.setClipRight(0);
1102 } else if (myRightEdge
> absoluteRightEdge
) {
1103 screen
.setClipRight(screen
.getClipRight()
1104 - (myRightEdge
- absoluteRightEdge
));
1106 if (getAbsoluteY() > absoluteBottomEdge
) {
1108 screen
.setClipBottom(0);
1109 } else if (myBottomEdge
> absoluteBottomEdge
) {
1110 screen
.setClipBottom(screen
.getClipBottom()
1111 - (myBottomEdge
- absoluteBottomEdge
));
1115 screen
.setOffsetX(getAbsoluteX());
1116 screen
.setOffsetY(getAbsoluteY());
1120 assert (visible
== true);
1122 // Continue down the chain. Draw the active child last so that it
1124 for (TWidget widget
: children
) {
1125 if (widget
.isVisible() && (widget
!= activeChild
)) {
1126 widget
.drawChildren();
1129 if (activeChild
!= null) {
1130 activeChild
.drawChildren();
1135 * Repaint the screen on the next update.
1137 protected final void doRepaint() {
1138 window
.getApplication().doRepaint();
1142 * Add a child widget to my list of children. We set its tabOrder to 0
1143 * and increment the tabOrder of all other children.
1145 * @param child TWidget to add
1147 private void addChild(final TWidget child
) {
1148 children
.add(child
);
1151 && !(child
instanceof THScroller
)
1152 && !(child
instanceof TVScroller
)
1154 for (TWidget widget
: children
) {
1155 widget
.active
= false;
1157 child
.active
= true;
1158 activeChild
= child
;
1160 for (int i
= 0; i
< children
.size(); i
++) {
1161 children
.get(i
).tabOrder
= i
;
1166 * Reset the tab order of children to match their position in the list.
1167 * Available so that subclasses can re-order their widgets if needed.
1169 protected void resetTabOrder() {
1170 for (int i
= 0; i
< children
.size(); i
++) {
1171 children
.get(i
).tabOrder
= i
;
1176 * Switch the active child.
1178 * @param child TWidget to activate
1180 public final void activate(final TWidget child
) {
1181 assert (child
.enabled
);
1182 if ((child
instanceof THScroller
)
1183 || (child
instanceof TVScroller
)
1188 if (children
.size() == 1) {
1189 if (children
.get(0).enabled
== true) {
1190 child
.active
= true;
1191 activeChild
= child
;
1194 if (child
!= activeChild
) {
1195 if (activeChild
!= null) {
1196 activeChild
.active
= false;
1198 child
.active
= true;
1199 activeChild
= child
;
1205 * Switch the active child.
1207 * @param tabOrder tabOrder of the child to activate. If that child
1208 * isn't enabled, then the next enabled child will be activated.
1210 public final void activate(final int tabOrder
) {
1211 if (children
.size() == 1) {
1212 if (children
.get(0).enabled
== true) {
1213 children
.get(0).active
= true;
1214 activeChild
= children
.get(0);
1219 TWidget child
= null;
1220 for (TWidget widget
: children
) {
1221 if ((widget
.enabled
)
1222 && !(widget
instanceof THScroller
)
1223 && !(widget
instanceof TVScroller
)
1224 && (widget
.tabOrder
>= tabOrder
)
1230 if ((child
!= null) && (child
!= activeChild
)) {
1231 if (activeChild
!= null) {
1232 activeChild
.active
= false;
1234 assert (child
.enabled
);
1235 child
.active
= true;
1236 activeChild
= child
;
1241 * Switch the active widget with the next in the tab order.
1243 * @param forward if true, then switch to the next enabled widget in the
1244 * list, otherwise switch to the previous enabled widget in the list
1246 public final void switchWidget(final boolean forward
) {
1248 // No children: do nothing.
1249 if (children
.size() == 0) {
1253 // If there is only one child, make it active if it is enabled.
1254 if (children
.size() == 1) {
1255 if (children
.get(0).enabled
== true) {
1256 activeChild
= children
.get(0);
1257 activeChild
.active
= true;
1259 children
.get(0).active
= false;
1265 // Two or more children: go forward or backward to the next enabled
1268 if (activeChild
!= null) {
1269 tabOrder
= activeChild
.tabOrder
;
1279 // If at the end, pass the switch to my parent.
1280 if ((!forward
) && (parent
!= this)) {
1281 parent
.switchWidget(forward
);
1285 tabOrder
= children
.size() - 1;
1286 } else if (tabOrder
== children
.size()) {
1287 // If at the end, pass the switch to my parent.
1288 if ((forward
) && (parent
!= this)) {
1289 parent
.switchWidget(forward
);
1295 if (activeChild
== null) {
1296 if (tabOrder
== 0) {
1297 // We wrapped around
1300 } else if (activeChild
.tabOrder
== tabOrder
) {
1301 // We wrapped around
1304 } while ((!children
.get(tabOrder
).enabled
)
1305 && !(children
.get(tabOrder
) instanceof THScroller
)
1306 && !(children
.get(tabOrder
) instanceof TVScroller
));
1308 if (activeChild
!= null) {
1309 assert (children
.get(tabOrder
).enabled
);
1311 activeChild
.active
= false;
1313 if (children
.get(tabOrder
).enabled
== true) {
1314 children
.get(tabOrder
).active
= true;
1315 activeChild
= children
.get(tabOrder
);
1320 * Returns my active widget.
1322 * @return widget that is active, or this if no children
1324 public TWidget
getActiveChild() {
1325 if ((this instanceof THScroller
)
1326 || (this instanceof TVScroller
)
1331 for (TWidget widget
: children
) {
1332 if (widget
.active
) {
1333 return widget
.getActiveChild();
1336 // No active children, return me
1340 // ------------------------------------------------------------------------
1341 // Passthru for Screen functions ------------------------------------------
1342 // ------------------------------------------------------------------------
1345 * Get the attributes at one location.
1347 * @param x column coordinate. 0 is the left-most column.
1348 * @param y row coordinate. 0 is the top-most row.
1349 * @return attributes at (x, y)
1351 protected final CellAttributes
getAttrXY(final int x
, final int y
) {
1352 return getScreen().getAttrXY(x
, y
);
1356 * Set the attributes at one location.
1358 * @param x column coordinate. 0 is the left-most column.
1359 * @param y row coordinate. 0 is the top-most row.
1360 * @param attr attributes to use (bold, foreColor, backColor)
1362 protected final void putAttrXY(final int x
, final int y
,
1363 final CellAttributes attr
) {
1365 getScreen().putAttrXY(x
, y
, attr
);
1369 * Set the attributes at one location.
1371 * @param x column coordinate. 0 is the left-most column.
1372 * @param y row coordinate. 0 is the top-most row.
1373 * @param attr attributes to use (bold, foreColor, backColor)
1374 * @param clip if true, honor clipping/offset
1376 protected final void putAttrXY(final int x
, final int y
,
1377 final CellAttributes attr
, final boolean clip
) {
1379 getScreen().putAttrXY(x
, y
, attr
, clip
);
1383 * Fill the entire screen with one character with attributes.
1385 * @param ch character to draw
1386 * @param attr attributes to use (bold, foreColor, backColor)
1388 protected final void putAll(final char ch
, final CellAttributes attr
) {
1389 getScreen().putAll(ch
, attr
);
1393 * Render one character with attributes.
1395 * @param x column coordinate. 0 is the left-most column.
1396 * @param y row coordinate. 0 is the top-most row.
1397 * @param ch character + attributes to draw
1399 protected final void putCharXY(final int x
, final int y
, final Cell ch
) {
1400 getScreen().putCharXY(x
, y
, ch
);
1404 * Render one character with attributes.
1406 * @param x column coordinate. 0 is the left-most column.
1407 * @param y row coordinate. 0 is the top-most row.
1408 * @param ch character to draw
1409 * @param attr attributes to use (bold, foreColor, backColor)
1411 protected final void putCharXY(final int x
, final int y
, final char ch
,
1412 final CellAttributes attr
) {
1414 getScreen().putCharXY(x
, y
, ch
, attr
);
1418 * Render one character without changing the underlying 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
1424 protected final void putCharXY(final int x
, final int y
, final char ch
) {
1425 getScreen().putCharXY(x
, y
, ch
);
1429 * Render a string. Does not wrap if the string exceeds the line.
1431 * @param x column coordinate. 0 is the left-most column.
1432 * @param y row coordinate. 0 is the top-most row.
1433 * @param str string to draw
1434 * @param attr attributes to use (bold, foreColor, backColor)
1436 protected final void putStringXY(final int x
, final int y
, final String str
,
1437 final CellAttributes attr
) {
1439 getScreen().putStringXY(x
, y
, str
, attr
);
1443 * Render a string without changing the underlying attribute. Does not
1444 * wrap if the string exceeds the line.
1446 * @param x column coordinate. 0 is the left-most column.
1447 * @param y row coordinate. 0 is the top-most row.
1448 * @param str string to draw
1450 protected final void putStringXY(final int x
, final int y
, final String str
) {
1451 getScreen().putStringXY(x
, y
, str
);
1455 * Draw a vertical line from (x, y) to (x, y + n).
1457 * @param x column coordinate. 0 is the left-most column.
1458 * @param y row coordinate. 0 is the top-most row.
1459 * @param n number of characters to draw
1460 * @param ch character to draw
1461 * @param attr attributes to use (bold, foreColor, backColor)
1463 protected final void vLineXY(final int x
, final int y
, final int n
,
1464 final char ch
, final CellAttributes attr
) {
1466 getScreen().vLineXY(x
, y
, n
, ch
, attr
);
1470 * Draw a horizontal line from (x, y) to (x + n, y).
1472 * @param x column coordinate. 0 is the left-most column.
1473 * @param y row coordinate. 0 is the top-most row.
1474 * @param n number of characters to draw
1475 * @param ch character to draw
1476 * @param attr attributes to use (bold, foreColor, backColor)
1478 protected final void hLineXY(final int x
, final int y
, final int n
,
1479 final char ch
, final CellAttributes attr
) {
1481 getScreen().hLineXY(x
, y
, n
, ch
, attr
);
1485 * Draw a box with a border and empty background.
1487 * @param left left column of box. 0 is the left-most row.
1488 * @param top top row of the box. 0 is the top-most row.
1489 * @param right right column of box
1490 * @param bottom bottom row of the box
1491 * @param border attributes to use for the border
1492 * @param background attributes to use for the background
1494 protected final void drawBox(final int left
, final int top
,
1495 final int right
, final int bottom
,
1496 final CellAttributes border
, final CellAttributes background
) {
1498 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
);
1502 * Draw a box with a border and empty background.
1504 * @param left left column of box. 0 is the left-most row.
1505 * @param top top row of the box. 0 is the top-most row.
1506 * @param right right column of box
1507 * @param bottom bottom row of the box
1508 * @param border attributes to use for the border
1509 * @param background attributes to use for the background
1510 * @param borderType if 1, draw a single-line border; if 2, draw a
1511 * double-line border; if 3, draw double-line top/bottom edges and
1512 * single-line left/right edges (like Qmodem)
1513 * @param shadow if true, draw a "shadow" on the box
1515 protected final void drawBox(final int left
, final int top
,
1516 final int right
, final int bottom
,
1517 final CellAttributes border
, final CellAttributes background
,
1518 final int borderType
, final boolean shadow
) {
1520 getScreen().drawBox(left
, top
, right
, bottom
, border
, background
,
1521 borderType
, shadow
);
1525 * Draw a box shadow.
1527 * @param left left column of box. 0 is the left-most row.
1528 * @param top top row of the box. 0 is the top-most row.
1529 * @param right right column of box
1530 * @param bottom bottom row of the box
1532 protected final void drawBoxShadow(final int left
, final int top
,
1533 final int right
, final int bottom
) {
1535 getScreen().drawBoxShadow(left
, top
, right
, bottom
);
1538 // ------------------------------------------------------------------------
1539 // Other TWidget constructors ---------------------------------------------
1540 // ------------------------------------------------------------------------
1543 * Convenience function to add a label to this container/window.
1546 * @param x column relative to parent
1547 * @param y row relative to parent
1548 * @return the new label
1550 public final TLabel
addLabel(final String text
, final int x
, final int y
) {
1551 return addLabel(text
, x
, y
, "tlabel");
1555 * Convenience function to add a label to this container/window.
1558 * @param x column relative to parent
1559 * @param y row relative to parent
1560 * @param action to call when shortcut is pressed
1561 * @return the new label
1563 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1564 final TAction action
) {
1566 return addLabel(text
, x
, y
, "tlabel", action
);
1570 * Convenience function to add a label to this container/window.
1573 * @param x column relative to parent
1574 * @param y row relative to parent
1575 * @param colorKey ColorTheme key color to use for foreground text.
1576 * Default is "tlabel"
1577 * @return the new label
1579 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1580 final String colorKey
) {
1582 return new TLabel(this, text
, x
, y
, colorKey
);
1586 * Convenience function to add a label to this container/window.
1589 * @param x column relative to parent
1590 * @param y row relative to parent
1591 * @param colorKey ColorTheme key color to use for foreground text.
1592 * Default is "tlabel"
1593 * @param action to call when shortcut is pressed
1594 * @return the new label
1596 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1597 final String colorKey
, final TAction action
) {
1599 return new TLabel(this, text
, x
, y
, colorKey
, action
);
1603 * Convenience function to add a label to this container/window.
1606 * @param x column relative to parent
1607 * @param y row relative to parent
1608 * @param colorKey ColorTheme key color to use for foreground text.
1609 * Default is "tlabel"
1610 * @param useWindowBackground if true, use the window's background color
1611 * @return the new label
1613 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1614 final String colorKey
, final boolean useWindowBackground
) {
1616 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
);
1620 * Convenience function to add a label to this container/window.
1623 * @param x column relative to parent
1624 * @param y row relative to parent
1625 * @param colorKey ColorTheme key color to use for foreground text.
1626 * Default is "tlabel"
1627 * @param useWindowBackground if true, use the window's background color
1628 * @param action to call when shortcut is pressed
1629 * @return the new label
1631 public final TLabel
addLabel(final String text
, final int x
, final int y
,
1632 final String colorKey
, final boolean useWindowBackground
,
1633 final TAction action
) {
1635 return new TLabel(this, text
, x
, y
, colorKey
, useWindowBackground
,
1640 * Convenience function to add a button to this container/window.
1642 * @param text label on the button
1643 * @param x column relative to parent
1644 * @param y row relative to parent
1645 * @param action action to call when button is pressed
1646 * @return the new button
1648 public final TButton
addButton(final String text
, final int x
, final int y
,
1649 final TAction action
) {
1651 return new TButton(this, text
, x
, y
, action
);
1655 * Convenience function to add a checkbox to this container/window.
1657 * @param x column relative to parent
1658 * @param y row relative to parent
1659 * @param label label to display next to (right of) the checkbox
1660 * @param checked initial check state
1661 * @return the new checkbox
1663 public final TCheckBox
addCheckBox(final int x
, final int y
,
1664 final String label
, final boolean checked
) {
1666 return new TCheckBox(this, x
, y
, label
, checked
);
1670 * Convenience function to add a combobox to this container/window.
1672 * @param x column relative to parent
1673 * @param y row relative to parent
1674 * @param width visible combobox width, including the down-arrow
1675 * @param values the possible values for the box, shown in the drop-down
1676 * @param valuesIndex the initial index in values, or -1 for no default
1678 * @param valuesHeight the height of the values drop-down when it is
1680 * @param updateAction action to call when a new value is selected from
1681 * the list or enter is pressed in the edit field
1682 * @return the new combobox
1684 public final TComboBox
addComboBox(final int x
, final int y
,
1685 final int width
, final List
<String
> values
, final int valuesIndex
,
1686 final int valuesHeight
, final TAction updateAction
) {
1688 return new TComboBox(this, x
, y
, width
, values
, valuesIndex
,
1689 valuesHeight
, updateAction
);
1693 * Convenience function to add a spinner to this container/window.
1695 * @param x column relative to parent
1696 * @param y row relative to parent
1697 * @param upAction action to call when the up arrow is clicked or pressed
1698 * @param downAction action to call when the down arrow is clicked or
1700 * @return the new spinner
1702 public final TSpinner
addSpinner(final int x
, final int y
,
1703 final TAction upAction
, final TAction downAction
) {
1705 return new TSpinner(this, x
, y
, upAction
, downAction
);
1709 * Convenience function to add a calendar to this container/window.
1711 * @param x column relative to parent
1712 * @param y row relative to parent
1713 * @param updateAction action to call when the user changes the value of
1715 * @return the new calendar
1717 public final TCalendar
addCalendar(final int x
, final int y
,
1718 final TAction updateAction
) {
1720 return new TCalendar(this, x
, y
, updateAction
);
1724 * Convenience function to add a progress bar to this container/window.
1726 * @param x column relative to parent
1727 * @param y row relative to parent
1728 * @param width width of progress bar
1729 * @param value initial value of percent complete
1730 * @return the new progress bar
1732 public final TProgressBar
addProgressBar(final int x
, final int y
,
1733 final int width
, final int value
) {
1735 return new TProgressBar(this, x
, y
, width
, value
);
1739 * Convenience function to add a radio button group to this
1742 * @param x column relative to parent
1743 * @param y row relative to parent
1744 * @param label label to display on the group box
1745 * @return the new radio button group
1747 public final TRadioGroup
addRadioGroup(final int x
, final int y
,
1748 final String label
) {
1750 return new TRadioGroup(this, x
, y
, label
);
1754 * Convenience function to add a text field to this container/window.
1756 * @param x column relative to parent
1757 * @param y row relative to parent
1758 * @param width visible text width
1759 * @param fixed if true, the text cannot exceed the display width
1760 * @return the new text field
1762 public final TField
addField(final int x
, final int y
,
1763 final int width
, final boolean fixed
) {
1765 return new TField(this, x
, y
, width
, fixed
);
1769 * Convenience function to add a text field to this container/window.
1771 * @param x column relative to parent
1772 * @param y row relative to parent
1773 * @param width visible text width
1774 * @param fixed if true, the text cannot exceed the display width
1775 * @param text initial text, default is empty string
1776 * @return the new text field
1778 public final TField
addField(final int x
, final int y
,
1779 final int width
, final boolean fixed
, final String text
) {
1781 return new TField(this, x
, y
, width
, fixed
, text
);
1785 * Convenience function to add a text field to this container/window.
1787 * @param x column relative to parent
1788 * @param y row relative to parent
1789 * @param width visible text width
1790 * @param fixed if true, the text cannot exceed the display width
1791 * @param text initial text, default is empty string
1792 * @param enterAction function to call when enter key is pressed
1793 * @param updateAction function to call when the text is updated
1794 * @return the new text field
1796 public final TField
addField(final int x
, final int y
,
1797 final int width
, final boolean fixed
, final String text
,
1798 final TAction enterAction
, final TAction updateAction
) {
1800 return new TField(this, x
, y
, width
, fixed
, text
, enterAction
,
1805 * Convenience function to add a scrollable text box to this
1808 * @param text text on the screen
1809 * @param x column relative to parent
1810 * @param y row relative to parent
1811 * @param width width of text area
1812 * @param height height of text area
1813 * @param colorKey ColorTheme key color to use for foreground text
1814 * @return the new text box
1816 public final TText
addText(final String text
, final int x
,
1817 final int y
, final int width
, final int height
, final String colorKey
) {
1819 return new TText(this, text
, x
, y
, width
, height
, colorKey
);
1823 * Convenience function to add a scrollable text box to this
1826 * @param text text on the screen
1827 * @param x column relative to parent
1828 * @param y row relative to parent
1829 * @param width width of text area
1830 * @param height height of text area
1831 * @return the new text box
1833 public final TText
addText(final String text
, final int x
, final int y
,
1834 final int width
, final int height
) {
1836 return new TText(this, text
, x
, y
, width
, height
, "ttext");
1840 * Convenience function to add an editable text area box to this
1843 * @param text text on the screen
1844 * @param x column relative to parent
1845 * @param y row relative to parent
1846 * @param width width of text area
1847 * @param height height of text area
1848 * @return the new text box
1850 public final TEditorWidget
addEditor(final String text
, final int x
,
1851 final int y
, final int width
, final int height
) {
1853 return new TEditorWidget(this, text
, x
, y
, width
, height
);
1857 * Convenience function to spawn a message box.
1859 * @param title window title, will be centered along the top border
1860 * @param caption message to display. Use embedded newlines to get a
1862 * @return the new message box
1864 public final TMessageBox
messageBox(final String title
,
1865 final String caption
) {
1867 return getApplication().messageBox(title
, caption
, TMessageBox
.Type
.OK
);
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 * @param type one of the TMessageBox.Type constants. Default is
1878 * @return the new message box
1880 public final TMessageBox
messageBox(final String title
,
1881 final String caption
, final TMessageBox
.Type type
) {
1883 return getApplication().messageBox(title
, caption
, type
);
1887 * Convenience function to spawn an input box.
1889 * @param title window title, will be centered along the top border
1890 * @param caption message to display. Use embedded newlines to get a
1892 * @return the new input box
1894 public final TInputBox
inputBox(final String title
, final String caption
) {
1896 return getApplication().inputBox(title
, caption
);
1900 * Convenience function to spawn an input box.
1902 * @param title window title, will be centered along the top border
1903 * @param caption message to display. Use embedded newlines to get a
1905 * @param text initial text to seed the field with
1906 * @return the new input box
1908 public final TInputBox
inputBox(final String title
, final String caption
,
1909 final String text
) {
1911 return getApplication().inputBox(title
, caption
, text
);
1915 * Convenience function to spawn an input box.
1917 * @param title window title, will be centered along the top border
1918 * @param caption message to display. Use embedded newlines to get a
1920 * @param text initial text to seed the field with
1921 * @param type one of the Type constants. Default is Type.OK.
1922 * @return the new input box
1924 public final TInputBox
inputBox(final String title
, final String caption
,
1925 final String text
, final TInputBox
.Type type
) {
1927 return getApplication().inputBox(title
, caption
, text
, type
);
1931 * Convenience function to add a password text field to this
1934 * @param x column relative to parent
1935 * @param y row relative to parent
1936 * @param width visible text width
1937 * @param fixed if true, the text cannot exceed the display width
1938 * @return the new text field
1940 public final TPasswordField
addPasswordField(final int x
, final int y
,
1941 final int width
, final boolean fixed
) {
1943 return new TPasswordField(this, x
, y
, width
, fixed
);
1947 * Convenience function to add a password text field to this
1950 * @param x column relative to parent
1951 * @param y row relative to parent
1952 * @param width visible text width
1953 * @param fixed if true, the text cannot exceed the display width
1954 * @param text initial text, default is empty string
1955 * @return the new text field
1957 public final TPasswordField
addPasswordField(final int x
, final int y
,
1958 final int width
, final boolean fixed
, final String text
) {
1960 return new TPasswordField(this, x
, y
, width
, fixed
, text
);
1964 * Convenience function to add a password text field to this
1967 * @param x column relative to parent
1968 * @param y row relative to parent
1969 * @param width visible text width
1970 * @param fixed if true, the text cannot exceed the display width
1971 * @param text initial text, default is empty string
1972 * @param enterAction function to call when enter key is pressed
1973 * @param updateAction function to call when the text is updated
1974 * @return the new text field
1976 public final TPasswordField
addPasswordField(final int x
, final int y
,
1977 final int width
, final boolean fixed
, final String text
,
1978 final TAction enterAction
, final TAction updateAction
) {
1980 return new TPasswordField(this, x
, y
, width
, fixed
, text
, enterAction
,
1985 * Convenience function to add a scrollable tree view to this
1988 * @param x column relative to parent
1989 * @param y row relative to parent
1990 * @param width width of tree view
1991 * @param height height of tree view
1992 * @return the new tree view
1994 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
1995 final int width
, final int height
) {
1997 return new TTreeViewWidget(this, x
, y
, width
, height
);
2001 * Convenience function to add a scrollable tree view to this
2004 * @param x column relative to parent
2005 * @param y row relative to parent
2006 * @param width width of tree view
2007 * @param height height of tree view
2008 * @param action action to perform when an item is selected
2009 * @return the new tree view
2011 public final TTreeViewWidget
addTreeViewWidget(final int x
, final int y
,
2012 final int width
, final int height
, final TAction action
) {
2014 return new TTreeViewWidget(this, x
, y
, width
, height
, action
);
2018 * Convenience function to spawn a file open box.
2020 * @param path path of selected file
2021 * @return the result of the new file open box
2022 * @throws IOException if a java.io operation throws
2024 public final String
fileOpenBox(final String path
) throws IOException
{
2025 return getApplication().fileOpenBox(path
);
2029 * Convenience function to spawn a file save box.
2031 * @param path path of selected file
2032 * @return the result of the new file open box
2033 * @throws IOException if a java.io operation throws
2035 public final String
fileSaveBox(final String path
) throws IOException
{
2036 return getApplication().fileOpenBox(path
, TFileOpenBox
.Type
.SAVE
);
2040 * Convenience function to spawn a file open box.
2042 * @param path path of selected file
2043 * @param type one of the Type constants
2044 * @return the result of the new file open box
2045 * @throws IOException if a java.io operation throws
2047 public final String
fileOpenBox(final String path
,
2048 final TFileOpenBox
.Type type
) throws IOException
{
2050 return getApplication().fileOpenBox(path
, type
);
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 * @param filter a string that files must match to be displayed
2059 * @return the result of the new file open box
2060 * @throws IOException of a java.io operation throws
2062 public final String
fileOpenBox(final String path
,
2063 final TFileOpenBox
.Type type
, final String filter
) throws IOException
{
2065 ArrayList
<String
> filters
= new ArrayList
<String
>();
2066 filters
.add(filter
);
2068 return getApplication().fileOpenBox(path
, type
, filters
);
2072 * Convenience function to spawn a file open box.
2074 * @param path path of selected file
2075 * @param type one of the Type constants
2076 * @param filters a list of strings that files must match to be displayed
2077 * @return the result of the new file open box
2078 * @throws IOException of a java.io operation throws
2080 public final String
fileOpenBox(final String path
,
2081 final TFileOpenBox
.Type type
,
2082 final List
<String
> filters
) throws IOException
{
2084 return getApplication().fileOpenBox(path
, type
, filters
);
2088 * Convenience function to add a directory list to this container/window.
2090 * @param path directory path, must be a directory
2091 * @param x column relative to parent
2092 * @param y row relative to parent
2093 * @param width width of text area
2094 * @param height height of text area
2095 * @return the new directory list
2097 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2098 final int y
, final int width
, final int height
) {
2100 return new TDirectoryList(this, path
, x
, y
, width
, height
, null);
2104 * Convenience function to add a directory list to this container/window.
2106 * @param path directory path, must be a directory
2107 * @param x column relative to parent
2108 * @param y row relative to parent
2109 * @param width width of text area
2110 * @param height height of text area
2111 * @param action action to perform when an item is selected (enter or
2113 * @return the new directory list
2115 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2116 final int y
, final int width
, final int height
, final TAction action
) {
2118 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
);
2122 * Convenience function to add a directory list to this container/window.
2124 * @param path directory path, must be a directory
2125 * @param x column relative to parent
2126 * @param y row relative to parent
2127 * @param width width of text area
2128 * @param height height of text area
2129 * @param action action to perform when an item is selected (enter or
2131 * @param singleClickAction action to perform when an item is selected
2133 * @return the new directory list
2135 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2136 final int y
, final int width
, final int height
, final TAction action
,
2137 final TAction singleClickAction
) {
2139 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2144 * Convenience function to add a directory list to this container/window.
2146 * @param path directory path, must be a directory
2147 * @param x column relative to parent
2148 * @param y row relative to parent
2149 * @param width width of text area
2150 * @param height height of text area
2151 * @param action action to perform when an item is selected (enter or
2153 * @param singleClickAction action to perform when an item is selected
2155 * @param filters a list of strings that files must match to be displayed
2156 * @return the new directory list
2158 public final TDirectoryList
addDirectoryList(final String path
, final int x
,
2159 final int y
, final int width
, final int height
, final TAction action
,
2160 final TAction singleClickAction
, final List
<String
> filters
) {
2162 return new TDirectoryList(this, path
, x
, y
, width
, height
, action
,
2163 singleClickAction
, filters
);
2167 * Convenience function to add a list to this container/window.
2169 * @param strings list of strings to show
2170 * @param x column relative to parent
2171 * @param y row relative to parent
2172 * @param width width of text area
2173 * @param height height of text area
2174 * @return the new directory list
2176 public final TList
addList(final List
<String
> strings
, final int x
,
2177 final int y
, final int width
, final int height
) {
2179 return new TList(this, strings
, x
, y
, width
, height
, null);
2183 * Convenience function to add a list to this container/window.
2185 * @param strings list of strings to show
2186 * @param x column relative to parent
2187 * @param y row relative to parent
2188 * @param width width of text area
2189 * @param height height of text area
2190 * @param enterAction action to perform when an item is selected
2191 * @return the new directory list
2193 public final TList
addList(final List
<String
> strings
, final int x
,
2194 final int y
, final int width
, final int height
,
2195 final TAction enterAction
) {
2197 return new TList(this, strings
, x
, y
, width
, height
, enterAction
);
2201 * Convenience function to add a list to this container/window.
2203 * @param strings list of strings to show
2204 * @param x column relative to parent
2205 * @param y row relative to parent
2206 * @param width width of text area
2207 * @param height height of text area
2208 * @param enterAction action to perform when an item is selected
2209 * @param moveAction action to perform when the user navigates to a new
2210 * item with arrow/page keys
2211 * @return the new directory list
2213 public final TList
addList(final List
<String
> strings
, final int x
,
2214 final int y
, final int width
, final int height
,
2215 final TAction enterAction
, final TAction moveAction
) {
2217 return new TList(this, strings
, x
, y
, width
, height
, enterAction
,
2222 * Convenience function to add an image to this container/window.
2224 * @param x column relative to parent
2225 * @param y row relative to parent
2226 * @param width number of text cells for width of the image
2227 * @param height number of text cells for height of the image
2228 * @param image the image to display
2229 * @param left left column of the image. 0 is the left-most column.
2230 * @param top top row of the image. 0 is the top-most row.
2232 public final TImage
addImage(final int x
, final int y
,
2233 final int width
, final int height
,
2234 final BufferedImage image
, final int left
, final int top
) {
2236 return new TImage(this, x
, y
, width
, height
, image
, left
, top
);
2240 * Convenience function to add an image to this container/window.
2242 * @param x column relative to parent
2243 * @param y row relative to parent
2244 * @param width number of text cells for width of the image
2245 * @param height number of text cells for height of the image
2246 * @param image the image to display
2247 * @param left left column of the image. 0 is the left-most column.
2248 * @param top top row of the image. 0 is the top-most row.
2249 * @param clickAction function to call when mouse is pressed
2251 public final TImage
addImage(final int x
, final int y
,
2252 final int width
, final int height
,
2253 final BufferedImage image
, final int left
, final int top
,
2254 final TAction clickAction
) {
2256 return new TImage(this, x
, y
, width
, height
, image
, left
, top
,
2261 * Convenience function to add an editable 2D data table to this
2264 * @param x column relative to parent
2265 * @param y row relative to parent
2266 * @param width width of widget
2267 * @param height height of widget
2269 public TTableWidget
addTable(final int x
, final int y
, final int width
,
2272 return new TTableWidget(this, x
, y
, width
, height
);