2 import jexer
.TApplication
;
4 import jexer
.TTerminalWidget
;
5 import jexer
.TSplitPane
;
7 import jexer
.event
.TMenuEvent
;
8 import jexer
.menu
.TMenu
;
11 * Implements a simple tiling window manager. A terminal widget is added to
12 * the desktop, which can be split horizontally or vertically. A close
13 * action is provided to each window to remove the split when its shell
16 * This example shows what can be done with minimal changes to stock Jexer
19 public class JexerTilingWindowManager2
extends TApplication
{
22 * Menu item: split the terminal vertically.
24 private static final int MENU_SPLIT_VERTICAL
= 2000;
27 * Menu item: split the terminal horizontally.
29 private static final int MENU_SPLIT_HORIZONTAL
= 2001;
31 * Menu item: recreate the root terminal.
33 private static final int MENU_RESPAWN_ROOT
= 2002;
36 * Handle to the root widget.
38 private TWidget root
= null;
43 public static void main(String
[] args
) throws Exception
{
44 // For this application, we must use ptypipe so that the terminal
45 // shells can be aware of their size.
46 System
.setProperty("jexer.TTerminal.ptypipe", "true");
48 // Let's also suppress the status line.
49 System
.setProperty("jexer.hideStatusBar", "true");
51 JexerTilingWindowManager2 jtwm
= new JexerTilingWindowManager2();
52 (new Thread(jtwm
)).start();
56 * Public constructor chooses the ECMA-48 / Xterm backend.
58 public JexerTilingWindowManager2() throws Exception
{
59 super(BackendType
.XTERM
);
61 // The stock tool menu has items for redrawing the screen, opening
62 // images, and (when using the Swing backend) setting the font.
65 // We will have one menu containing a mix of new and stock commands
66 TMenu tileMenu
= addMenu("&Tile");
68 // New commands for this example: split vertical and horizontal.
69 tileMenu
.addItem(MENU_SPLIT_VERTICAL
, "&Vertical Split");
70 tileMenu
.addItem(MENU_SPLIT_HORIZONTAL
, "&Horizontal Split");
71 tileMenu
.addItem(MENU_RESPAWN_ROOT
, "&Respawn Root Terminal");
73 // Stock commands: a new shell with resizable window, and exit
75 tileMenu
.addSeparator();
76 tileMenu
.addItem(TMenu
.MID_SHELL
, "&New Windowed Terminal");
77 tileMenu
.addSeparator();
78 tileMenu
.addDefaultItem(TMenu
.MID_EXIT
);
80 // TTerminalWidget can request the text-block mouse pointer be
81 // suppressed, but the default TDesktop will ignore it. Let's set a
82 // new TDesktop to pass that mouse pointer visibility option to
84 setDesktop(new TDesktop(this) {
86 public boolean hasHiddenMouse() {
87 TWidget active
= getActiveChild();
88 if (active
instanceof TTerminalWidget
) {
89 return ((TTerminalWidget
) active
).hasHiddenMouse();
95 // Spin up the root terminal
100 * Process menu events.
103 protected boolean onMenu(TMenuEvent event
) {
104 TWidget active
= getDesktop().getActiveChild();
105 TSplitPane split
= null;
107 switch (event
.getId()) {
108 case MENU_RESPAWN_ROOT
:
109 assert (root
== null);
110 createRootTerminal();
113 case MENU_SPLIT_VERTICAL
:
115 assert (getDesktop().getActiveChild() == null);
116 createRootTerminal();
119 split
= active
.splitVertical(false, createTerminal());
120 if (active
== root
) {
125 case MENU_SPLIT_HORIZONTAL
:
127 assert (getDesktop().getActiveChild() == null);
128 createRootTerminal();
131 split
= active
.splitHorizontal(false, createTerminal());
132 if (active
== root
) {
138 return super.onMenu(event
);
144 * Create the root terminal.
146 private void createRootTerminal() {
147 assert (root
== null);
148 disableMenuItem(MENU_RESPAWN_ROOT
);
149 root
= createTerminal();
153 * Create a new terminal.
155 * @return the new terminal
157 private TWidget
createTerminal() {
158 return new TTerminalWidget(getDesktop(), 0, 0,
159 getDesktop().getWidth(), getDesktop().getHeight(),
162 if (source
.getParent() instanceof TSplitPane
) {
163 ((TSplitPane
) source
.getParent()).removeSplit(source
,
166 source
.getApplication().enableMenuItem(