0.0.1:
-- TMessageBox
-- TInputBox
- AWTBackend
0.0.2:
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
*/
public class TApplication {
+ /**
+ * WidgetEventHandler is the main event consumer loop. There are at most
+ * two such threads in existence: the primary for normal case and a
+ * secondary that is used for TMessageBox, TInputBox, and similar.
+ */
+ private class WidgetEventHandler implements Runnable {
+ /**
+ * The main application.
+ */
+ private TApplication application;
+
+ /**
+ * Whether or not this WidgetEventHandler is the primary or secondary
+ * thread.
+ */
+ private boolean primary = true;
+
+ /**
+ * Public constructor.
+ *
+ * @param application the main application
+ * @param primary if true, this is the primary event handler thread
+ */
+ public WidgetEventHandler(final TApplication application,
+ final boolean primary) {
+
+ this.application = application;
+ this.primary = primary;
+ }
+
+ /**
+ * The consumer loop.
+ */
+ public void run() {
+
+ // Loop forever
+ while (!application.quit) {
+
+ // Wait until application notifies me
+ while (!application.quit) {
+ try {
+ synchronized (application.drainEventQueue) {
+ if (application.drainEventQueue.size() > 0) {
+ break;
+ }
+ }
+ synchronized (application) {
+ application.wait();
+ if ((!primary)
+ && (application.secondaryEventReceiver == null)
+ ) {
+ // Secondary thread, time to exit
+ return;
+ }
+ break;
+ }
+ } catch (InterruptedException e) {
+ // SQUASH
+ }
+ }
+
+ // Pull all events off the queue
+ for (;;) {
+ TInputEvent event = null;
+ synchronized (application.drainEventQueue) {
+ if (application.drainEventQueue.size() == 0) {
+ break;
+ }
+ event = application.drainEventQueue.remove(0);
+ }
+ if (primary) {
+ primaryHandleEvent(event);
+ } else {
+ secondaryHandleEvent(event);
+ }
+ if ((!primary)
+ && (application.secondaryEventReceiver == null)
+ ) {
+ // Secondary thread, time to exit
+ return;
+ }
+ }
+ } // while (true) (main runnable loop)
+ }
+ }
+
+ /**
+ * The primary event handler thread.
+ */
+ private WidgetEventHandler primaryEventHandler;
+
+ /**
+ * The secondary event handler thread.
+ */
+ private WidgetEventHandler secondaryEventHandler;
+
+ /**
+ * The widget receiving events from the secondary event handler thread.
+ */
+ private TWidget secondaryEventReceiver;
+
/**
* Access to the physical screen, keyboard, and mouse.
*/
backend = new ECMA48Backend(input, output);
theme = new ColorTheme();
desktopBottom = getScreen().getHeight() - 1;
- fillEventQueue = new LinkedList<TInputEvent>();
- drainEventQueue = new LinkedList<TInputEvent>();
+ fillEventQueue = new ArrayList<TInputEvent>();
+ drainEventQueue = new ArrayList<TInputEvent>();
windows = new LinkedList<TWindow>();
menus = new LinkedList<TMenu>();
subMenus = new LinkedList<TMenu>();
timers = new LinkedList<TTimer>();
accelerators = new HashMap<TKeypress, TMenuItem>();
+
+ // Setup the main consumer thread
+ primaryEventHandler = new WidgetEventHandler(this, true);
+ (new Thread(primaryEventHandler)).start();
}
/**
drawAll();
}
- /*
-
- // Shutdown the fibers
- eventQueue.length = 0;
- if (secondaryEventFiber !is null) {
- assert(secondaryEventReceiver !is null);
- secondaryEventReceiver = null;
- if (secondaryEventFiber.state == Fiber.State.HOLD) {
- // Wake up the secondary handler so that it can exit.
- secondaryEventFiber.call();
- }
+ // Shutdown the consumer threads
+ synchronized (this) {
+ this.notifyAll();
}
- if (primaryEventFiber.state == Fiber.State.HOLD) {
- // Wake up the primary handler so that it can exit.
- primaryEventFiber.call();
- }
- */
-
backend.shutdown();
}
}
}
- // TODO: change to two separate threads
- primaryHandleEvent(event);
-
- /*
-
// Put into the main queue
- addEvent(event);
-
- // Have one of the two consumer Fibers peel the events off
- // the queue.
- if (secondaryEventFiber !is null) {
- assert(secondaryEventFiber.state == Fiber.State.HOLD);
-
- // Wake up the secondary handler for these events
- secondaryEventFiber.call();
- } else {
- assert(primaryEventFiber.state == Fiber.State.HOLD);
-
- // Wake up the primary handler for these events
- primaryEventFiber.call();
- }
- */
+ synchronized (drainEventQueue) {
+ drainEventQueue.add(event);
+ }
+ // Wake all threads: primary thread will either be consuming events
+ // again or waiting in yield(), and secondary thread will either not
+ // exist or consuming events.
+ synchronized (this) {
+ this.notifyAll();
+ }
}
/**
* @see #primaryHandleEvent(TInputEvent event)
*/
private void secondaryHandleEvent(final TInputEvent event) {
- // TODO
+ secondaryEventReceiver.handleEvent(event);
+ }
+
+ /**
+ * Enable a widget to override the primary event thread.
+ *
+ * @param widget widget that will receive events
+ */
+ public final void enableSecondaryEventReceiver(final TWidget widget) {
+ assert (secondaryEventReceiver == null);
+ assert (secondaryEventHandler == null);
+ assert (widget instanceof TMessageBox);
+ secondaryEventReceiver = widget;
+ secondaryEventHandler = new WidgetEventHandler(this, false);
+ (new Thread(secondaryEventHandler)).start();
+
+ // Refresh
+ repaint = true;
+ }
+
+ /**
+ * Yield to the secondary thread.
+ */
+ public final void yield() {
+ assert (secondaryEventReceiver != null);
+ while (secondaryEventReceiver != null) {
+ synchronized (this) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ // SQUASH
+ }
+ }
+ }
}
/**
for (TTimer timer: timers) {
if (timer.getNextTick().getTime() < now.getTime()) {
timer.tick();
- if (timer.recurring == true) {
+ if (timer.recurring) {
keepTimers.add(timer);
}
} else {
// Refresh screen
repaint = true;
- /*
- TODO
-
-
// Check if we are closing a TMessageBox or similar
- if (secondaryEventReceiver !is null) {
- assert(secondaryEventFiber !is null);
+ if (secondaryEventReceiver != null) {
+ assert (secondaryEventHandler != null);
// Do not send events to the secondaryEventReceiver anymore, the
// window is closed.
secondaryEventReceiver = null;
- // Special case: if this is called while executing on a
- // secondaryEventFiber, call it so that widgetEventHandler() can
- // terminate.
- if (secondaryEventFiber.state == Fiber.State.HOLD) {
- secondaryEventFiber.call();
- }
- secondaryEventFiber = null;
-
- // Unfreeze the logic in handleEvent()
- if (primaryEventFiber.state == Fiber.State.HOLD) {
- primaryEventFiber.call();
+ // Wake all threads: primary thread will be consuming events
+ // again, and secondary thread will exit.
+ synchronized (this) {
+ this.notifyAll();
}
}
- */
}
/**
* @return if true, this event was consumed
*/
protected boolean onCommand(final TCommandEvent command) {
- /*
- TODO
// Default: handle cmExit
if (command.equals(cmExit)) {
if (messageBox("Confirmation", "Exit application?",
- TMessageBox.Type.YESNO).result == TMessageBox.Result.YES) {
+ TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) {
quit = true;
}
repaint = true;
return true;
}
+ /*
+ TODO
if (command.equals(cmShell)) {
openTerminal(0, 0, TWindow.Flag.RESIZABLE);
repaint = true;
return true;
}
+ */
if (command.equals(cmTile)) {
tileWindows();
repaint = true;
return true;
}
- */
+
return false;
}
// Default: handle MID_EXIT
if (menu.getId() == TMenu.MID_EXIT) {
- /*
- TODO
if (messageBox("Confirmation", "Exit application?",
- TMessageBox.Type.YESNO).result == TMessageBox.Result.YES) {
+ TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) {
quit = true;
}
// System.err.printf("onMenu MID_EXIT result: quit = %s\n", quit);
repaint = true;
return true;
- */
- quit = true;
- repaint = true;
- return true;
}
/*
*
* @return the new menu
*/
- final public TMenu addWindowMenu() {
+ public final TMenu addWindowMenu() {
TMenu windowMenu = addMenu("&Window");
windowMenu.addDefaultItem(TMenu.MID_TILE);
windowMenu.addDefaultItem(TMenu.MID_CASCADE);
* @param duration number of milliseconds to wait between ticks
* @param recurring if true, re-schedule this timer after every tick
* @param action function to call when button is pressed
+ * @return the timer
*/
public final TTimer addTimer(final long duration, final boolean recurring,
final TAction action) {
}
}
+ /**
+ * Convenience function to spawn a message box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @return the new message box
+ */
+ public final TMessageBox messageBox(final String title,
+ final String caption) {
+
+ return new TMessageBox(this, title, caption, TMessageBox.Type.OK);
+ }
+
+ /**
+ * Convenience function to spawn a message box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param type one of the TMessageBox.Type constants. Default is
+ * Type.OK.
+ * @return the new message box
+ */
+ public final TMessageBox messageBox(final String title,
+ final String caption, final TMessageBox.Type type) {
+
+ return new TMessageBox(this, title, caption, type);
+ }
+
+ /**
+ * Convenience function to spawn an input box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @return the new input box
+ */
+ public final TInputBox inputBox(final String title, final String caption) {
+
+ return new TInputBox(this, title, caption);
+ }
+
+ /**
+ * Convenience function to spawn an input box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param text initial text to seed the field with
+ * @return the new input box
+ */
+ public final TInputBox inputBox(final String title, final String caption,
+ final String text) {
+
+ return new TInputBox(this, title, caption, text);
+ }
+
}
--- /dev/null
+/**
+ * Jexer - Java Text User Interface
+ *
+ * License: LGPLv3 or later
+ *
+ * This module is licensed under the GNU Lesser General Public License
+ * Version 3. Please see the file "COPYING" in this directory for more
+ * information about the GNU Lesser General Public License Version 3.
+ *
+ * Copyright (C) 2015 Kevin Lamonte
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * http://www.gnu.org/licenses/, or write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * @author Kevin Lamonte [kevin.lamonte@gmail.com]
+ * @version 1
+ */
+package jexer;
+
+/**
+ * TInputBox is a system-modal dialog with an OK button and a text input
+ * field. Call it like:
+ *
+ * <p>
+ * <pre>
+ * {@code
+ * box = application.inputBox(title, caption);
+ * if (box.getText().equals("yes")) {
+ * ... the user entered "yes", do stuff ...
+ * }
+ * }
+ * </pre>
+ *
+ */
+public final class TInputBox extends TMessageBox {
+
+ /**
+ * The input field.
+ */
+ private TField field;
+
+ /**
+ * Retrieve the answer text.
+ *
+ * @return the answer text
+ */
+ public String getText() {
+ return field.getText();
+ }
+
+ /**
+ * Public constructor. The input box will be centered on screen.
+ *
+ * @param application TApplication that manages this window
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ */
+ public TInputBox(final TApplication application, final String title,
+ final String caption) {
+
+ this(application, title, caption, "");
+ }
+
+ /**
+ * Public constructor. The input box will be centered on screen.
+ *
+ * @param application TApplication that manages this window
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param text initial text to seed the field with
+ */
+ public TInputBox(final TApplication application, final String title,
+ final String caption, final String text) {
+
+ super(application, title, caption, Type.OK, false);
+
+ for (TWidget widget: getChildren()) {
+ if (widget instanceof TButton) {
+ widget.setY(widget.getY() + 2);
+ }
+ }
+
+ setHeight(getHeight() + 2);
+ field = addField(1, getHeight() - 6, getWidth() - 4, false, text);
+
+ // Yield to the secondary thread. When I come back from the
+ // constructor response will already be set.
+ getApplication().yield();
+ }
+
+}
--- /dev/null
+/**
+ * Jexer - Java Text User Interface
+ *
+ * License: LGPLv3 or later
+ *
+ * This module is licensed under the GNU Lesser General Public License
+ * Version 3. Please see the file "COPYING" in this directory for more
+ * information about the GNU Lesser General Public License Version 3.
+ *
+ * Copyright (C) 2015 Kevin Lamonte
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * http://www.gnu.org/licenses/, or write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * @author Kevin Lamonte [kevin.lamonte@gmail.com]
+ * @version 1
+ */
+package jexer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TMessageBox is a system-modal dialog with buttons for OK, Cancel, Yes, or
+ * No. Call it like:
+ *
+ * <p>
+ * <pre>
+ * {@code
+ * box = application.messageBox(title, caption,
+ * TMessageBox.Type.OK | TMessageBox.Type.CANCEL);
+ *
+ * if (box.getResult() == TMessageBox.OK) {
+ * ... the user pressed OK, do stuff ...
+ * }
+ * }
+ * </pre>
+ *
+ */
+public class TMessageBox extends TWindow {
+
+ /**
+ * Message boxes have these supported types.
+ */
+ public enum Type {
+ /**
+ * Show an OK button.
+ */
+ OK,
+
+ /**
+ * Show both OK and Cancel buttons.
+ */
+ OKCANCEL,
+
+ /**
+ * Show both Yes and No buttons.
+ */
+ YESNO,
+
+ /**
+ * Show Yes, No, and Cancel buttons.
+ */
+ YESNOCANCEL
+ };
+
+ /**
+ * Message boxes have these possible results.
+ */
+ public enum Result {
+ /**
+ * User clicked "OK".
+ */
+ OK,
+
+ /**
+ * User clicked "Cancel".
+ */
+ CANCEL,
+
+ /**
+ * User clicked "Yes".
+ */
+ YES,
+
+ /**
+ * User clicked "No".
+ */
+ NO
+ };
+
+
+ /**
+ * Which button was clicked: OK, CANCEL, YES, or NO.
+ */
+ private Result result = Result.OK;
+
+ /**
+ * Get the result.
+ *
+ * @return the result: OK, CANCEL, YES, or NO.
+ */
+ public final Result getResult() {
+ return result;
+ }
+
+ /**
+ * Public constructor. The message box will be centered on screen.
+ *
+ * @param application TApplication that manages this window
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ */
+ public TMessageBox(final TApplication application, final String title,
+ final String caption) {
+
+ this(application, title, caption, Type.OK, true);
+ }
+
+ /**
+ * Public constructor. The message box will be centered on screen.
+ *
+ * @param application TApplication that manages this window
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param type one of the Type constants. Default is Type.OK.
+ */
+ public TMessageBox(final TApplication application, final String title,
+ final String caption, final Type type) {
+
+ this(application, title, caption, type, true);
+ }
+
+ /**
+ * Public constructor. The message box will be centered on screen.
+ *
+ * @param application TApplication that manages this window
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param type one of the Type constants. Default is Type.OK.
+ * @param yield if true, yield this Thread. Subclasses need to set this
+ * to false and yield at their end of their constructor intead.
+ */
+ protected TMessageBox(final TApplication application, final String title,
+ final String caption, final Type type, final boolean yield) {
+
+ // Start as 50x50 at (1, 1). These will be changed later.
+ super(application, title, 1, 1, 100, 100, CENTERED | MODAL);
+
+ // Determine width and height
+ String [] lines = caption.split("\n");
+ int width = title.length() + 12;
+ setHeight(6 + lines.length);
+ for (String line: lines) {
+ if (line.length() + 4 > width) {
+ width = line.length() + 4;
+ }
+ }
+ setWidth(width);
+ if (getWidth() > getScreen().getWidth()) {
+ setWidth(getScreen().getWidth());
+ }
+ // Re-center window to get an appropriate (x, y)
+ center();
+
+ // Now add my elements
+ int lineI = 1;
+ for (String line: lines) {
+ addLabel(line, 1, lineI, "twindow.background.modal");
+ lineI++;
+ }
+
+ // The button line
+ lineI++;
+ List<TButton> buttons = new ArrayList<TButton>();
+
+ int buttonX = 0;
+
+ // Setup button actions
+ switch (type) {
+
+ case OK:
+ result = Result.OK;
+ if (getWidth() < 15) {
+ setWidth(15);
+ }
+ buttonX = (getWidth() - 11) / 2;
+ buttons.add(addButton(" &OK ", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.OK;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ break;
+
+ case OKCANCEL:
+ result = Result.CANCEL;
+ if (getWidth() < 26) {
+ setWidth(26);
+ }
+ buttonX = (getWidth() - 22) / 2;
+ buttons.add(addButton(" &OK ", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.OK;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ buttonX += 8 + 4;
+ buttons.add(addButton("&Cancel", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.CANCEL;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ break;
+
+ case YESNO:
+ result = Result.NO;
+ if (getWidth() < 20) {
+ setWidth(20);
+ }
+ buttonX = (getWidth() - 16) / 2;
+ buttons.add(addButton("&Yes", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.YES;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ buttonX += 5 + 4;
+ buttons.add(addButton("&No", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.NO;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ break;
+
+ case YESNOCANCEL:
+ result = Result.CANCEL;
+ if (getWidth() < 31) {
+ setWidth(31);
+ }
+ buttonX = (getWidth() - 27) / 2;
+ buttons.add(addButton("&Yes", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.YES;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ buttonX += 5 + 4;
+ buttons.add(addButton("&No", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.NO;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ buttonX += 4 + 4;
+ buttons.add(addButton("&Cancel", buttonX, lineI,
+ new TAction() {
+ public void DO() {
+ result = Result.CANCEL;
+ getApplication().closeWindow(TMessageBox.this);
+ }
+ }
+ )
+ );
+ break;
+
+ default:
+ throw new IllegalArgumentException("Invalid message box type: " + type);
+ }
+
+ // Set the secondaryThread to run me
+ getApplication().enableSecondaryEventReceiver(this);
+
+ if (yield) {
+ // Yield to the secondary thread. When I come back from the
+ // constructor response will already be set.
+ getApplication().yield();
+ }
+ }
+
+}
* @param colorKey ColorTheme key color to use for foreground text
* @return the new text box
*/
- public TText addText(final String text, final int x,
+ public final TText addText(final String text, final int x,
final int y, final int width, final int height, final String colorKey) {
return new TText(this, text, x, y, width, height, colorKey);
* @param height height of text area
* @return the new text box
*/
- public TText addText(final String text, final int x, final int y,
+ public final TText addText(final String text, final int x, final int y,
final int width, final int height) {
return new TText(this, text, x, y, width, height, "ttext");
}
+ /**
+ * Convenience function to spawn a message box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @return the new message box
+ */
+ public final TMessageBox messageBox(final String title,
+ final String caption) {
+
+ return getApplication().messageBox(title, caption, TMessageBox.Type.OK);
+ }
+
+ /**
+ * Convenience function to spawn a message box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param type one of the TMessageBox.Type constants. Default is
+ * Type.OK.
+ * @return the new message box
+ */
+ public final TMessageBox messageBox(final String title,
+ final String caption, final TMessageBox.Type type) {
+
+ return getApplication().messageBox(title, caption, type);
+ }
+
+ /**
+ * Convenience function to spawn an input box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @return the new input box
+ */
+ public final TInputBox inputBox(final String title, final String caption) {
+
+ return getApplication().inputBox(title, caption);
+ }
+
+ /**
+ * Convenience function to spawn an input box.
+ *
+ * @param title window title, will be centered along the top border
+ * @param caption message to display. Use embedded newlines to get a
+ * multi-line box.
+ * @param text initial text to seed the field with
+ * @return the new input box
+ */
+ public final TInputBox inputBox(final String title, final String caption,
+ final String text) {
+
+ return getApplication().inputBox(title, caption, text);
+ }
}
* This window demonstates the TMessageBox and TInputBox widgets.
*/
class DemoMsgBoxWindow extends TWindow {
- /*
- private void openYNCMessageBox() {
- application.messageBox("Yes/No/Cancel MessageBox",
- q"EOS
-This is an example of a Yes/No/Cancel MessageBox.
-
-Note that the MessageBox text can span multiple
-lines.
-
-The default result (if someone hits the top-left
-close button) is CANCEL.
-EOS",
- TMessageBox.Type.YESNOCANCEL);
- }
-
- private void openYNMessageBox() {
- application.messageBox("Yes/No MessageBox",
- q"EOS
-This is an example of a Yes/No MessageBox.
-
-Note that the MessageBox text can span multiple
-lines.
-
-The default result (if someone hits the top-left
-close button) is NO.
-EOS",
- TMessageBox.Type.YESNO);
- }
-
- private void openOKCMessageBox() {
- application.messageBox("OK/Cancel MessageBox",
- q"EOS
-This is an example of a OK/Cancel MessageBox.
-
-Note that the MessageBox text can span multiple
-lines.
-
-The default result (if someone hits the top-left
-close button) is CANCEL.
-EOS",
- TMessageBox.Type.OKCANCEL);
- }
-
- private void openOKMessageBox() {
- application.messageBox("OK MessageBox",
- q"EOS
-This is an example of a OK MessageBox. This is the
-default MessageBox.
-
-Note that the MessageBox text can span multiple
-lines.
-
-The default result (if someone hits the top-left
-close button) is OK.
-EOS",
- TMessageBox.Type.OK);
- }
-
- */
/**
* Constructor.
// Construct a demo window. X and Y don't matter because it
// will be centered on screen.
super(parent, "Message Boxes", 0, 0, 60, 15, flags);
- /*
- uint row = 1;
+
+ int row = 1;
// Add some widgets
addLabel("Default OK message box", 1, row);
- addButton("Open O&K MB", 35, row, &openOKMessageBox);
+ addButton("Open O&K MB", 35, row,
+ new TAction() {
+ public void DO() {
+ getApplication().messageBox("OK MessageBox",
+"This is an example of a OK MessageBox. This is the\n" +
+"default MessageBox.\n" +
+"\n" +
+"Note that the MessageBox text can span multiple\n" +
+"lines.\n" +
+"\n" +
+"The default result (if someone hits the top-left\n" +
+"close button) is OK.\n",
+ TMessageBox.Type.OK);
+ }
+ }
+ );
row += 2;
addLabel("OK/Cancel message box", 1, row);
- addButton("O&pen OKC MB", 35, row, &openOKCMessageBox);
+ addButton("O&pen OKC MB", 35, row,
+ new TAction() {
+ public void DO() {
+ getApplication().messageBox("OK/Cancel MessageBox",
+"This is an example of a OK/Cancel MessageBox.\n" +
+"\n" +
+"Note that the MessageBox text can span multiple\n" +
+"lines.\n" +
+"\n" +
+"The default result (if someone hits the top-left\n" +
+"close button) is CANCEL.\n",
+ TMessageBox.Type.OKCANCEL);
+ }
+ }
+ );
row += 2;
addLabel("Yes/No message box", 1, row);
- addButton("Open &YN MB", 35, row, &openYNMessageBox);
+ addButton("Open &YN MB", 35, row,
+ new TAction() {
+ public void DO() {
+ getApplication().messageBox("Yes/No MessageBox",
+"This is an example of a Yes/No MessageBox.\n" +
+"\n" +
+"Note that the MessageBox text can span multiple\n" +
+"lines.\n" +
+"\n" +
+"The default result (if someone hits the top-left\n" +
+"close button) is NO.\n",
+ TMessageBox.Type.YESNO);
+ }
+ }
+ );
row += 2;
addLabel("Yes/No/Cancel message box", 1, row);
- addButton("Ope&n YNC MB", 35, row, &openYNCMessageBox);
+ addButton("Ope&n YNC MB", 35, row,
+ new TAction() {
+ public void DO() {
+ getApplication().messageBox("Yes/No/Cancel MessageBox",
+"This is an example of a Yes/No/Cancel MessageBox.\n" +
+"\n" +
+"Note that the MessageBox text can span multiple\n" +
+"lines.\n" +
+"\n" +
+"The default result (if someone hits the top-left\n" +
+"close button) is CANCEL.\n",
+ TMessageBox.Type.YESNOCANCEL);
+ }
+ }
+ );
row += 2;
addLabel("Input box", 1, row);
addButton("Open &input box", 35, row,
- {
- application.inputBox("Input Box",
- q"EOS
-This is an example of an InputBox.
-
-Note that the InputBox text can span multiple
-lines.
-EOS",
- "some input text");
+ new TAction() {
+ public void DO() {
+ TInputBox in = getApplication().inputBox("Input Box",
+"This is an example of an InputBox.\n" +
+"\n" +
+"Note that the InputBox text can span multiple\n" +
+"lines.\n",
+ "some input text");
+ getApplication().messageBox("Your InputBox Answer",
+ "You entered: " + in.getText());
+ }
}
);
- addButton("&Close Window", (width - 14) / 2, height - 4,
- {
- application.closeWindow(this);
+ addButton("&Close Window", (getWidth() - 14) / 2, getHeight() - 4,
+ new TAction() {
+ public void DO() {
+ getApplication().closeWindow(DemoMsgBoxWindow.this);
+ }
}
);
- */
}
}
// do this kind of logic on their own.
private TWindow modalWindow;
private void openModalWindow() {
- modalWindow = application.addWindow("Demo Modal Window", 0, 0,
+ modalWindow = getApplication().addWindow("Demo Modal Window", 0, 0,
58, 15, TWindow.Flag.MODAL);
modalWindow.addLabel("This is an example of a very braindead modal window.", 1, 1);
modalWindow.addLabel("Modal windows are centered by default.", 1, 2);
modalWindow.height - 4, &modalWindowClose);
}
private void modalWindowClose() {
- application.closeWindow(modalWindow);
+ getApplication().closeWindow(modalWindow);
}
*/
addLabel("Terminal", 1, row);
addButton("Termi&nal", 35, row,
{
- application.openTerminal(0, 0);
+ getApplication().openTerminal(0, 0);
}
);
}