1 import java
.util
.ArrayList
;
3 import jexer
.TApplication
;
6 import jexer
.TTerminalWidget
;
7 import jexer
.TSplitPane
;
9 import jexer
.event
.TKeypressEvent
;
10 import jexer
.event
.TMenuEvent
;
11 import jexer
.menu
.TMenu
;
14 * Implements a simple tiling window manager. A terminal widget is added to
15 * the desktop, which can be split horizontally or vertically. A close
16 * action is provided to each window to remove the split when its shell
19 * This example shows what can be done with minimal changes to stock Jexer
22 public class JexerTilingWindowManager2
extends TApplication
{
25 * Menu item: split the terminal vertically.
27 private static final int MENU_SPLIT_VERTICAL
= 2000;
30 * Menu item: split the terminal horizontally.
32 private static final int MENU_SPLIT_HORIZONTAL
= 2001;
34 * Menu item: recreate the root terminal.
36 private static final int MENU_RESPAWN_ROOT
= 2002;
39 * Handle to the root widget.
41 private TWidget root
= null;
46 public static void main(String
[] args
) throws Exception
{
47 // For this application, we must use ptypipe so that the terminal
48 // shells can be aware of their size.
49 System
.setProperty("jexer.TTerminal.ptypipe", "true");
51 // Let's also suppress the status line.
52 System
.setProperty("jexer.hideStatusBar", "true");
54 JexerTilingWindowManager2 jtwm
= new JexerTilingWindowManager2();
55 (new Thread(jtwm
)).start();
59 * Public constructor chooses the ECMA-48 / Xterm backend.
61 public JexerTilingWindowManager2() throws Exception
{
62 super(BackendType
.XTERM
);
64 // The stock tool menu has items for redrawing the screen, opening
65 // images, and (when using the Swing backend) setting the font.
68 // We will have one menu containing a mix of new and stock commands
69 TMenu tileMenu
= addMenu("&Tile");
71 // New commands for this example: split vertical and horizontal.
72 tileMenu
.addItem(MENU_SPLIT_VERTICAL
, "&Vertical Split");
73 tileMenu
.addItem(MENU_SPLIT_HORIZONTAL
, "&Horizontal Split");
74 tileMenu
.addItem(MENU_RESPAWN_ROOT
, "&Respawn Root Terminal");
76 // Stock commands: a new shell with resizable window, and exit
78 tileMenu
.addSeparator();
79 tileMenu
.addItem(TMenu
.MID_SHELL
, "&New Windowed Terminal");
80 tileMenu
.addSeparator();
81 tileMenu
.addDefaultItem(TMenu
.MID_EXIT
);
83 // TTerminalWidget can request the text-block mouse pointer be
84 // suppressed, but the default TDesktop will ignore it. Let's set a
85 // new TDesktop to pass that mouse pointer visibility option to
87 setDesktop(new TDesktop(this) {
89 public boolean hasHiddenMouse() {
90 TWidget active
= getActiveChild();
91 if (active
instanceof TTerminalWidget
) {
92 return ((TTerminalWidget
) active
).hasHiddenMouse();
98 // Spin up the root terminal
103 * Process menu events.
106 protected boolean onMenu(TMenuEvent event
) {
107 TWidget active
= getDesktop().getActiveChild();
108 TSplitPane split
= null;
110 switch (event
.getId()) {
111 case MENU_RESPAWN_ROOT
:
112 assert (root
== null);
113 createRootTerminal();
116 case MENU_SPLIT_VERTICAL
:
118 assert (getDesktop().getActiveChild() == null);
119 createRootTerminal();
122 split
= active
.splitVertical(false, createTerminal());
123 if (active
== root
) {
128 case MENU_SPLIT_HORIZONTAL
:
130 assert (getDesktop().getActiveChild() == null);
131 createRootTerminal();
134 split
= active
.splitHorizontal(false, createTerminal());
135 if (active
== root
) {
141 return super.onMenu(event
);
147 * Create the root terminal.
149 private void createRootTerminal() {
150 assert (root
== null);
151 disableMenuItem(MENU_RESPAWN_ROOT
);
152 root
= createTerminal();
156 * Create a new terminal.
158 * @return the new terminal
160 private TWidget
createTerminal() {
161 return new TTerminalWidget(getDesktop(), 0, 0,
162 getDesktop().getWidth(), getDesktop().getHeight(),
165 if (source
.getParent() instanceof TSplitPane
) {
166 ((TSplitPane
) source
.getParent()).removeSplit(source
,
169 source
.getApplication().enableMenuItem(