2 * This file is part of lanterna (http://code.google.com/p/lanterna/).
4 * lanterna is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 2010-2015 Martin
19 package com
.googlecode
.lanterna
.gui2
;
21 import com
.googlecode
.lanterna
.TerminalPosition
;
22 import com
.googlecode
.lanterna
.input
.KeyStroke
;
23 import com
.googlecode
.lanterna
.TerminalSize
;
24 import com
.googlecode
.lanterna
.input
.KeyType
;
29 * Abstract Window has most of the code requiring for a window to function, all concrete window implementations extends
30 * from this in one way or another. You can define your own window by extending from this, as an alternative to building
31 * up the GUI externally by constructing a {@code BasicWindow} and adding components to it.
34 public abstract class AbstractWindow
extends AbstractBasePane
implements Window
{
36 private WindowBasedTextGUI textGUI
;
37 private boolean visible
;
38 private TerminalSize lastKnownSize
;
39 private TerminalSize lastKnownDecoratedSize
;
40 private TerminalPosition lastKnownPosition
;
41 private TerminalPosition contentOffset
;
42 private Set
<Hint
> hints
;
43 private boolean closeWindowWithEscape
;
46 * Default constructor, this creates a window with no title
48 public AbstractWindow() {
53 * Creates a window with a specific title that will (probably) be drawn in the window decorations
54 * @param title Title of this window
56 public AbstractWindow(String title
) {
61 this.lastKnownPosition
= null;
62 this.lastKnownSize
= null;
63 this.lastKnownDecoratedSize
= null;
64 this.closeWindowWithEscape
= false;
66 this.hints
= new HashSet
<Hint
>();
70 * Setting this property to {@code true} will cause pressing the ESC key to close the window. This used to be the
71 * default behaviour of lanterna 3 during the development cycle but is not longer the case. You are encouraged to
72 * put proper buttons or other kind of components to clearly mark to the user how to close the window instead of
73 * magically taking ESC, but sometimes it can be useful (when doing testing, for example) to enable this mode.
74 * @param closeWindowWithEscape If {@code true}, this window will self-close if you press ESC key
76 public void setCloseWindowWithEscape(boolean closeWindowWithEscape
) {
77 this.closeWindowWithEscape
= closeWindowWithEscape
;
81 public void setTextGUI(WindowBasedTextGUI textGUI
) {
82 //This is kind of stupid check, but might cause it to blow up on people using the library incorrectly instead of
83 //just causing weird behaviour
84 if(this.textGUI
!= null && textGUI
!= null) {
85 throw new UnsupportedOperationException("Are you calling setTextGUI yourself? Please read the documentation"
86 + " in that case (this could also be a bug in Lanterna, please report it if you are sure you are "
87 + "not calling Window.setTextGUI(..) from your code)");
89 this.textGUI
= textGUI
;
93 public WindowBasedTextGUI
getTextGUI() {
98 * Alters the title of the window to the supplied string
99 * @param title New title of the window
101 public void setTitle(String title
) {
107 public String
getTitle() {
112 public boolean isVisible() {
117 public void setVisible(boolean visible
) {
118 this.visible
= visible
;
121 public void draw(TextGUIGraphics graphics
) {
122 if(!graphics
.getSize().equals(lastKnownSize
)) {
123 getComponent().invalidate();
125 setSize(graphics
.getSize(), false);
126 super.draw(graphics
);
130 public boolean handleInput(KeyStroke key
) {
131 boolean handled
= super.handleInput(key
);
132 if(!handled
&& closeWindowWithEscape
&& key
.getKeyType() == KeyType
.Escape
) {
140 public TerminalPosition
toGlobal(TerminalPosition localPosition
) {
141 if(localPosition
== null) {
144 return lastKnownPosition
.withRelative(contentOffset
.withRelative(localPosition
));
148 public TerminalPosition
fromGlobal(TerminalPosition globalPosition
) {
149 if(globalPosition
== null) {
152 return globalPosition
.withRelative(
153 -lastKnownPosition
.getColumn() - contentOffset
.getColumn(),
154 -lastKnownPosition
.getRow() - contentOffset
.getRow());
158 public TerminalSize
getPreferredSize() {
159 return contentHolder
.getPreferredSize();
163 public void setHints(Collection
<Hint
> hints
) {
164 this.hints
= new HashSet
<Hint
>(hints
);
169 public Set
<Hint
> getHints() {
170 return Collections
.unmodifiableSet(hints
);
174 public final TerminalPosition
getPosition() {
175 return lastKnownPosition
;
179 public final void setPosition(TerminalPosition topLeft
) {
180 this.lastKnownPosition
= topLeft
;
184 public final TerminalSize
getSize() {
185 return lastKnownSize
;
189 public void setSize(TerminalSize size
) {
193 private void setSize(TerminalSize size
, boolean invalidate
) {
194 this.lastKnownSize
= size
;
201 public final TerminalSize
getDecoratedSize() {
202 return lastKnownDecoratedSize
;
206 public final void setDecoratedSize(TerminalSize decoratedSize
) {
207 this.lastKnownDecoratedSize
= decoratedSize
;
211 public void setContentOffset(TerminalPosition offset
) {
212 this.contentOffset
= offset
;
216 public void close() {
217 if(textGUI
!= null) {
218 textGUI
.removeWindow(this);
224 public void waitUntilClosed() {
225 WindowBasedTextGUI textGUI
= getTextGUI();
226 if(textGUI
!= null) {
227 textGUI
.waitForWindowToClose(this);