2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import java
.util
.LinkedList
;
32 import java
.util
.List
;
34 import jexer
.bits
.CellAttributes
;
35 import jexer
.event
.TKeypressEvent
;
36 import jexer
.event
.TMouseEvent
;
37 import static jexer
.TKeypress
.*;
40 * TText implements a simple scrollable text area. It reflows automatically on
43 public class TText
extends TScrollableWidget
{
46 * Available text justifications.
48 public enum Justification
{
50 * Left-justified text.
60 * Right-justified text.
65 * Fully-justified text.
71 * How to justify the text.
73 private Justification justification
= Justification
.LEFT
;
81 * Text converted to lines.
83 private List
<String
> lines
;
88 private String colorKey
;
91 * Maximum width of a single line.
93 private int maxLineWidth
;
96 * Number of lines between each paragraph.
98 private int lineSpacing
= 1;
103 * @param text new text to display
105 public void setText(final String text
) {
115 public String
getText() {
120 * Convenience method used by TWindowLoggerOutput.
122 * @param line new line to add
124 public void addLine(final String line
) {
125 if (text
.length() == 0) {
135 * Recompute the bounds for the scrollbars.
137 private void computeBounds() {
139 for (String line
: lines
) {
140 if (line
.length() > maxLineWidth
) {
141 maxLineWidth
= line
.length();
145 vScroller
.setTopValue(0);
146 vScroller
.setBottomValue((lines
.size() - getHeight()) + 1);
147 if (vScroller
.getBottomValue() < 0) {
148 vScroller
.setBottomValue(0);
150 if (vScroller
.getValue() > vScroller
.getBottomValue()) {
151 vScroller
.setValue(vScroller
.getBottomValue());
154 hScroller
.setLeftValue(0);
155 hScroller
.setRightValue((maxLineWidth
- getWidth()) + 1);
156 if (hScroller
.getRightValue() < 0) {
157 hScroller
.setRightValue(0);
159 if (hScroller
.getValue() > hScroller
.getRightValue()) {
160 hScroller
.setValue(hScroller
.getRightValue());
167 * @param justification LEFT, CENTER, RIGHT, or FULL
169 public void setJustification(final Justification justification
) {
170 this.justification
= justification
;
175 * Left-justify the text.
177 public void leftJustify() {
178 justification
= Justification
.LEFT
;
183 * Center-justify the text.
185 public void centerJustify() {
186 justification
= Justification
.CENTER
;
191 * Right-justify the text.
193 public void rightJustify() {
194 justification
= Justification
.RIGHT
;
199 * Fully-justify the text.
201 public void fullJustify() {
202 justification
= Justification
.FULL
;
207 * Resize text and scrollbars for a new width/height.
210 public void reflowData() {
214 // Break up text into paragraphs
215 String
[] paragraphs
= text
.split("\n\n");
216 for (String p
: paragraphs
) {
217 switch (justification
) {
219 lines
.addAll(jexer
.bits
.StringUtils
.left(p
,
223 lines
.addAll(jexer
.bits
.StringUtils
.center(p
,
227 lines
.addAll(jexer
.bits
.StringUtils
.right(p
,
231 lines
.addAll(jexer
.bits
.StringUtils
.full(p
,
236 for (int i
= 0; i
< lineSpacing
; i
++) {
244 * Public constructor.
246 * @param parent parent widget
247 * @param text text on the screen
248 * @param x column relative to parent
249 * @param y row relative to parent
250 * @param width width of text area
251 * @param height height of text area
253 public TText(final TWidget parent
, final String text
, final int x
,
254 final int y
, final int width
, final int height
) {
256 this(parent
, text
, x
, y
, width
, height
, "ttext");
260 * Public constructor.
262 * @param parent parent widget
263 * @param text text on the screen
264 * @param x column relative to parent
265 * @param y row relative to parent
266 * @param width width of text area
267 * @param height height of text area
268 * @param colorKey ColorTheme key color to use for foreground
269 * text. Default is "ttext".
271 public TText(final TWidget parent
, final String text
, final int x
,
272 final int y
, final int width
, final int height
,
273 final String colorKey
) {
275 // Set parent and window
276 super(parent
, x
, y
, width
, height
);
279 this.colorKey
= colorKey
;
281 lines
= new LinkedList
<String
>();
283 vScroller
= new TVScroller(this, getWidth() - 1, 0, getHeight() - 1);
284 hScroller
= new THScroller(this, 0, getHeight() - 1, getWidth() - 1);
294 CellAttributes color
= getTheme().getColor(colorKey
);
296 int begin
= vScroller
.getValue();
298 for (int i
= begin
; i
< lines
.size(); i
++) {
299 String line
= lines
.get(i
);
300 if (hScroller
.getValue() < line
.length()) {
301 line
= line
.substring(hScroller
.getValue());
305 String formatString
= "%-" + Integer
.toString(getWidth() - 1) + "s";
306 getScreen().putStringXY(0, topY
, String
.format(formatString
, line
),
310 if (topY
>= (getHeight() - 1)) {
315 // Pad the rest with blank lines
316 for (int i
= topY
; i
< (getHeight() - 1); i
++) {
317 getScreen().hLineXY(0, i
, getWidth() - 1, ' ', color
);
323 * Handle mouse press events.
325 * @param mouse mouse button press event
328 public void onMouseDown(final TMouseEvent mouse
) {
329 if (mouse
.isMouseWheelUp()) {
330 vScroller
.decrement();
333 if (mouse
.isMouseWheelDown()) {
334 vScroller
.increment();
339 super.onMouseDown(mouse
);
345 * @param keypress keystroke event
348 public void onKeypress(final TKeypressEvent keypress
) {
349 if (keypress
.equals(kbLeft
)) {
350 hScroller
.decrement();
351 } else if (keypress
.equals(kbRight
)) {
352 hScroller
.increment();
353 } else if (keypress
.equals(kbUp
)) {
354 vScroller
.decrement();
355 } else if (keypress
.equals(kbDown
)) {
356 vScroller
.increment();
357 } else if (keypress
.equals(kbPgUp
)) {
358 vScroller
.bigDecrement();
359 } else if (keypress
.equals(kbPgDn
)) {
360 vScroller
.bigIncrement();
361 } else if (keypress
.equals(kbHome
)) {
363 } else if (keypress
.equals(kbEnd
)) {
364 vScroller
.toBottom();
366 // Pass other keys (tab etc.) on
367 super.onKeypress(keypress
);