import jexer.backend.Screen;
import jexer.bits.Cell;
import jexer.bits.CellAttributes;
+import jexer.bits.Clipboard;
import jexer.bits.ColorTheme;
import jexer.event.TCommandEvent;
import jexer.event.TInputEvent;
* @param command command event
*/
public void onCommand(final TCommandEvent command) {
- // Default: do nothing, pass to children instead
- for (TWidget widget: children) {
- widget.onCommand(command);
+ if (activeChild != null) {
+ activeChild.onCommand(command);
}
}
this.x = x;
this.y = y;
- this.width = width;
- this.height = height;
+ // Call the functions so that subclasses can choose how to handle it.
+ setWidth(width);
+ setHeight(height);
if (layout != null) {
layout.onResize(new TResizeEvent(TResizeEvent.Type.WIDGET,
width, height));
return null;
}
+ /**
+ * Get the Clipboard.
+ *
+ * @return the Clipboard, or null if not assigned
+ */
+ public Clipboard getClipboard() {
+ if (window != null) {
+ return window.getApplication().getClipboard();
+ }
+ return null;
+ }
+
/**
* Comparison operator. For various subclasses it sorts on:
* <ul>
* @return difference between this.tabOrder and that.tabOrder, or
* difference between this.z and that.z, or String.compareTo(text)
*/
- public final int compareTo(final TWidget that) {
+ public int compareTo(final TWidget that) {
if ((this instanceof TWindow)
&& (that instanceof TWindow)
) {
return window.getApplication().getTheme();
}
+ /**
+ * See if this widget can be drawn onto a screen.
+ *
+ * @return true if this widget is part of the hierarchy that can draw to
+ * a screen
+ */
+ public final boolean isDrawable() {
+ if ((window == null)
+ || (window.getScreen() == null)
+ || (parent == null)
+ ) {
+ return false;
+ }
+ if (parent == this) {
+ return true;
+ }
+ return (parent.isDrawable());
+ }
+
/**
* Draw my specific widget. When called, the screen rectangle I draw
* into is already setup (offset and clipping).
* Called by parent to render to TWindow. Note package private access.
*/
final void drawChildren() {
- if (window == null) {
+ if (!isDrawable()) {
return;
}
// Draw me
draw();
+ if (!isDrawable()) {
+ // An action taken by a draw method unhooked me from the UI.
+ // Bail out.
+ return;
+ }
+
assert (visible == true);
// Continue down the chain. Draw the active child last so that it
for (TWidget widget: children) {
if (widget.isVisible() && (widget != activeChild)) {
widget.drawChildren();
+ if (!isDrawable()) {
+ // An action taken by a draw method unhooked me from the UI.
+ // Bail out.
+ return;
+ }
}
}
if (activeChild != null) {
if (activeChild != null) {
activeChild.active = false;
}
- child.active = true;
- activeChild = child;
}
+ child.active = true;
+ activeChild = child;
}
}
}
}
+ /**
+ * Make this widget, all of its parents, the active child.
+ */
+ public final void activateAll() {
+ activate();
+ if (parent == this) {
+ return;
+ }
+ if (parent != null) {
+ parent.activateAll();
+ }
+ }
+
/**
* Switch the active widget with the next in the tab order.
*
splitPane.setLeft(this);
splitPane.setRight(newWidget);
}
- splitPane.activate();
if (newWidget != null) {
- newWidget.activate();
+ newWidget.activateAll();
} else {
- activate();
+ activateAll();
}
assert (parent != null);
splitPane.setTop(this);
splitPane.setBottom(newWidget);
}
- splitPane.activate();
if (newWidget != null) {
- newWidget.activate();
+ newWidget.activateAll();
} else {
- activate();
+ activateAll();
}
assert (parent != null);
return new TRadioGroup(this, x, y, label);
}
+ /**
+ * Convenience function to add a radio button group to this
+ * container/window.
+ *
+ * @param x column relative to parent
+ * @param y row relative to parent
+ * @param width width of group
+ * @param label label to display on the group box
+ */
+ public final TRadioGroup addRadioGroup(final int x, final int y,
+ final int width, final String label) {
+
+ return new TRadioGroup(this, x, y, width, label);
+ }
+
/**
* Convenience function to add a text field to this container/window.
*