1e482d45db9d267544f1a67fd1152496551617dd
2 * Jexer - Java Text User Interface
4 * License: LGPLv3 or later
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
10 * Copyright (C) 2015 Kevin Lamonte
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
38 * This window demonstates the TText, THScroller, and TVScroller widgets.
40 class DemoTextWindow
extends TWindow
{
43 * Hang onto my TText so I can resize it with the window.
45 private TText textField
;
50 * @param parent the main application
52 public DemoTextWindow(final TApplication parent
) {
53 super(parent
, "Text Areas", 0, 0, 44, 20, RESIZABLE
);
56 "This is an example of a reflowable text field. Some example text follows.\n" +
58 "This library implements a text-based windowing system loosely\n" +
59 "reminiscient of Borland's [Turbo\n" +
60 "Vision](http://en.wikipedia.org/wiki/Turbo_Vision) library. For those\n" +
61 "wishing to use the actual C++ Turbo Vision library, see [Sergio\n" +
62 "Sigala's updated version](http://tvision.sourceforge.net/) that runs\n" +
63 "on many more platforms.\n" +
65 "Currently the only console platform supported is Posix (tested on\n" +
66 "Linux). Input/output is handled through terminal escape sequences\n" +
67 "generated by the library itself: ncurses is not required or linked to. \n" +
68 "xterm mouse tracking using UTF8 coordinates is supported.\n" +
70 "This library is licensed LGPL (\"GNU Lesser General Public License\")\n" +
71 "version 3 or greater. See the file COPYING for the full license text,\n" +
72 "which includes both the GPL v3 and the LGPL supplemental terms.\n" +
78 * Handle window/screen resize events.
80 * @param event resize event
83 public void onResize(final TResizeEvent event
) {
84 if (event
.getType() == TResizeEvent
.Type
.WIDGET
) {
85 // Resize the text field
86 textField
.setWidth(event
.getWidth() - 4);
87 textField
.setHeight(event
.getHeight() - 4);
92 // Pass to children instead
93 for (TWidget widget
: getChildren()) {
94 widget
.onResize(event
);
100 * This window demonstates the TRadioGroup, TRadioButton, and TCheckbox
103 class DemoCheckboxWindow
extends TWindow
{
108 * @param parent the main application
110 DemoCheckboxWindow(final TApplication parent
) {
111 this(parent
, CENTERED
| RESIZABLE
);
117 * @param parent the main application
118 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
120 DemoCheckboxWindow(final TApplication parent
, final int flags
) {
121 // Construct a demo window. X and Y don't matter because it will be
122 // centered on screen.
123 super(parent
, "Radiobuttons and Checkboxes", 0, 0, 60, 15, flags
);
128 addLabel("Check box example 1", 1, row
);
129 addCheckbox(35, row
++, "Checkbox 1", false);
130 addLabel("Check box example 2", 1, row
);
131 addCheckbox(35, row
++, "Checkbox 2", true);
134 TRadioGroup group
= addRadioGroup(1, row
, "Group 1");
135 group
.addRadioButton("Radio option 1");
136 group
.addRadioButton("Radio option 2");
137 group
.addRadioButton("Radio option 3");
139 addButton("&Close Window", (getWidth() - 14) / 2, getHeight() - 4,
142 DemoCheckboxWindow
.this.getApplication()
143 .closeWindow(DemoCheckboxWindow
.this);
153 * This window demonstates the TMessageBox and TInputBox widgets.
155 class DemoMsgBoxWindow
extends TWindow
{
157 private void openYNCMessageBox() {
158 application.messageBox("Yes/No/Cancel MessageBox",
160 This is an example of a Yes/No/Cancel MessageBox.
162 Note that the MessageBox text can span multiple
165 The default result (if someone hits the top-left
166 close button) is CANCEL.
168 TMessageBox.Type.YESNOCANCEL);
171 private void openYNMessageBox() {
172 application.messageBox("Yes/No MessageBox",
174 This is an example of a Yes/No MessageBox.
176 Note that the MessageBox text can span multiple
179 The default result (if someone hits the top-left
182 TMessageBox.Type.YESNO);
185 private void openOKCMessageBox() {
186 application.messageBox("OK/Cancel MessageBox",
188 This is an example of a OK/Cancel MessageBox.
190 Note that the MessageBox text can span multiple
193 The default result (if someone hits the top-left
194 close button) is CANCEL.
196 TMessageBox.Type.OKCANCEL);
199 private void openOKMessageBox() {
200 application.messageBox("OK MessageBox",
202 This is an example of a OK MessageBox. This is the
205 Note that the MessageBox text can span multiple
208 The default result (if someone hits the top-left
211 TMessageBox.Type.OK);
219 * @param parent the main application
221 DemoMsgBoxWindow(final TApplication parent
) {
222 this(parent
, TWindow
.CENTERED
| TWindow
.RESIZABLE
);
228 * @param parent the main application
229 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
231 DemoMsgBoxWindow(final TApplication parent
, final int flags
) {
232 // Construct a demo window. X and Y don't matter because it
233 // will be centered on screen.
234 super(parent
, "Message Boxes", 0, 0, 60, 15, flags
);
239 addLabel("Default OK message box", 1, row);
240 addButton("Open O&K MB", 35, row, &openOKMessageBox);
243 addLabel("OK/Cancel message box", 1, row);
244 addButton("O&pen OKC MB", 35, row, &openOKCMessageBox);
247 addLabel("Yes/No message box", 1, row);
248 addButton("Open &YN MB", 35, row, &openYNMessageBox);
251 addLabel("Yes/No/Cancel message box", 1, row);
252 addButton("Ope&n YNC MB", 35, row, &openYNCMessageBox);
255 addLabel("Input box", 1, row);
256 addButton("Open &input box", 35, row,
258 application.inputBox("Input Box",
260 This is an example of an InputBox.
262 Note that the InputBox text can span multiple
269 addButton("&Close Window", (width - 14) / 2, height - 4,
271 application.closeWindow(this);
279 * This is the main "demo" application window. It makes use of the TTimer,
280 * TProgressBox, TLabel, TButton, and TField widgets.
282 class DemoMainWindow
extends TWindow
{
284 // Timer that increments a number.
285 private TTimer timer
;
287 // Timer label is updated with timer ticks.
291 // The modal window is a more low-level example of controlling a window
292 // "from the outside". Most windows will probably subclass TWindow and
293 // do this kind of logic on their own.
294 private TWindow modalWindow;
295 private void openModalWindow() {
296 modalWindow = application.addWindow("Demo Modal Window", 0, 0,
297 58, 15, TWindow.Flag.MODAL);
298 modalWindow.addLabel("This is an example of a very braindead modal window.", 1, 1);
299 modalWindow.addLabel("Modal windows are centered by default.", 1, 2);
300 modalWindow.addButton("&Close", (modalWindow.width - 8)/2,
301 modalWindow.height - 4, &modalWindowClose);
303 private void modalWindowClose() {
304 application.closeWindow(modalWindow);
309 * We need to override onClose so that the timer will no longer be called
310 * after we close the window. TTimers currently are completely unaware
311 * of the rest of the UI classes.
314 public void onClose() {
315 getApplication().removeTimer(timer
);
319 * Construct demo window. It will be centered on screen.
321 * @param parent the main application
323 public DemoMainWindow(final TApplication parent
) {
324 this(parent
, CENTERED
| RESIZABLE
);
327 // These are used by the timer loop. They have to be at class scope so
328 // that they can be accessed by the anonymous TAction class.
330 TProgressBar progressBar
;
335 * @param parent the main application
336 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
338 private DemoMainWindow(final TApplication parent
, final int flags
) {
339 // Construct a demo window. X and Y don't matter because it will be
340 // centered on screen.
341 super(parent
, "Demo Window", 0, 0, 60, 23, flags
);
347 addLabel("Message Boxes", 1, row
);
348 addButton("&MessageBoxes", 35, row
,
351 new DemoMsgBoxWindow(getApplication());
358 addLabel("Open me as modal", 1, row
);
359 addButton("W&indow", 35, row
,
362 new DemoMainWindow(getApplication(), MODAL
);
369 addLabel("Variable-width text field:", 1, row
);
370 addField(35, row
++, 15, false, "Field text");
372 addLabel("Fixed-width text field:", 1, row
);
373 addField(35, row
, 15, true);
377 addLabel("Radio buttons and checkboxes", 1, row
);
378 addButton("&Checkboxes", 35, row
,
381 new DemoCheckboxWindow(getApplication());
390 addLabel("Editor window", 1, row);
391 addButton("Edito&r", 35, row,
393 new TEditor(application, 0, 0, 60, 15);
401 addLabel("Text areas", 1, row
);
402 addButton("&Text", 35, row
,
405 new DemoTextWindow(getApplication());
414 addLabel("Tree views", 1, row);
415 addButton("Tree&View", 35, row,
417 new DemoTreeViewWindow(application);
424 addLabel("Terminal", 1, row);
425 addButton("Termi&nal", 35, row,
427 application.openTerminal(0, 0);
434 progressBar
= addProgressBar(1, row
, 22, 0);
436 timerLabel
= addLabel("Timer", 1, row
);
437 timer
= getApplication().addTimer(100, true,
441 timerLabel
.setText(String
.format("Timer: %d", timerI
));
442 timerLabel
.setWidth(timerLabel
.getText().length());
446 progressBar
.setValue(timerI
);
447 DemoMainWindow
.this.setRepaint();
455 * The demo application itself.
457 class DemoApplication
extends TApplication
{
460 * Public constructor.
462 * @throws Exception if TApplication can't instantiate the Backend.
464 public DemoApplication() throws Exception
{
466 new DemoMainWindow(this);
472 TMenu demoMenu
= addMenu("&Demo");
473 TMenuItem item
= demoMenu
.addItem(2000, "&Checkable");
474 item
.setCheckable(true);
475 item
= demoMenu
.addItem(2001, "Disabled");
476 item
.setEnabled(false);
477 item
= demoMenu
.addItem(2002, "&Normal");
478 TSubMenu subMenu
= demoMenu
.addSubMenu("Sub-&Menu");
479 item
= demoMenu
.addItem(2010, "N&ormal A&&D");
481 item
= subMenu
.addItem(2000, "&Checkable (sub)");
482 item
.setCheckable(true);
483 item
= subMenu
.addItem(2001, "Disabled (sub)");
484 item
.setEnabled(false);
485 item
= subMenu
.addItem(2002, "&Normal (sub)");
487 subMenu
= subMenu
.addSubMenu("Sub-&Menu");
488 item
= subMenu
.addItem(2000, "&Checkable (sub)");
489 item
.setCheckable(true);
490 item
= subMenu
.addItem(2001, "Disabled (sub)");
491 item
.setEnabled(false);
492 item
= subMenu
.addItem(2002, "&Normal (sub)");
500 * This class provides a simple demonstration of Jexer's capabilities.
506 * @param args Command line arguments
508 public static void main(final String
[] args
) {
510 DemoApplication app
= new DemoApplication();
512 } catch (Exception e
) {