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]
33 import java
.util
.ArrayList
;
34 import java
.util
.List
;
36 import jexer
.bits
.CellAttributes
;
37 import jexer
.event
.TKeypressEvent
;
38 import jexer
.event
.TMouseEvent
;
39 import static jexer
.TKeypress
.*;
42 * TList shows a list of strings, and lets the user select one.
44 public class TList
extends TWidget
{
47 * The list of strings to display.
49 private List
<String
> strings
;
54 private int selectedString
= -1;
57 * Get the selection index.
59 * @return -1 if nothing is selected, otherwise the index into the list
61 public final int getSelectedIndex() {
62 return selectedString
;
66 * Set the selected string index.
68 * @param index -1 to unselect, otherwise the index into the list
70 public final void setSelectedIndex(final int index
) {
71 selectedString
= index
;
75 * Get the selected string.
77 * @return the selected string, or null of nothing is selected yet
79 public final String
getSelected() {
80 if ((selectedString
>= 0) && (selectedString
<= strings
.size() - 1)) {
81 return strings
.get(selectedString
);
87 * Set the new list of strings to display.
89 * @param list new list of strings
91 public final void setList(final List
<String
> list
) {
100 private TVScroller vScroller
;
103 * Get the vertical scrollbar. This is used by subclasses.
105 * @return the vertical scrollbar
107 public final TVScroller
getVScroller() {
112 * Horizontal scrollbar.
114 private THScroller hScroller
;
117 * Get the horizontal scrollbar. This is used by subclasses.
119 * @return the horizontal scrollbar
121 public final THScroller
getHScroller() {
126 * Maximum width of a single line.
128 private int maxLineWidth
;
131 * The action to perform when the user selects an item (clicks or enter).
133 private TAction enterAction
= null;
136 * The action to perform when the user navigates with keyboard.
138 private TAction moveAction
= null;
141 * Perform user selection action.
143 public void dispatchEnter() {
144 assert (selectedString
>= 0);
145 assert (selectedString
< strings
.size());
146 if (enterAction
!= null) {
152 * Perform list movement action.
154 public void dispatchMove() {
155 assert (selectedString
>= 0);
156 assert (selectedString
< strings
.size());
157 if (moveAction
!= null) {
163 * Resize for a new width/height.
165 public void reflow() {
171 for (int i
= 0; i
< strings
.size(); i
++) {
172 String line
= strings
.get(i
);
173 if (line
.length() > maxLineWidth
) {
174 maxLineWidth
= line
.length();
179 if (vScroller
== null) {
180 vScroller
= new TVScroller(this, getWidth() - 1, 0,
183 vScroller
.setX(getWidth() - 1);
184 vScroller
.setHeight(getHeight() - 1);
186 vScroller
.setBottomValue(strings
.size() - getHeight() + 1);
187 vScroller
.setTopValue(0);
188 vScroller
.setValue(0);
189 if (vScroller
.getBottomValue() < 0) {
190 vScroller
.setBottomValue(0);
192 vScroller
.setBigChange(getHeight() - 1);
195 if (hScroller
== null) {
196 hScroller
= new THScroller(this, 0, getHeight() - 1,
199 hScroller
.setY(getHeight() - 1);
200 hScroller
.setWidth(getWidth() - 1);
202 hScroller
.setRightValue(maxLineWidth
- getWidth() + 1);
203 hScroller
.setLeftValue(0);
204 hScroller
.setValue(0);
205 if (hScroller
.getRightValue() < 0) {
206 hScroller
.setRightValue(0);
208 hScroller
.setBigChange(getWidth() - 1);
212 * Public constructor.
214 * @param parent parent widget
215 * @param strings list of strings to show
216 * @param x column relative to parent
217 * @param y row relative to parent
218 * @param width width of text area
219 * @param height height of text area
221 public TList(final TWidget parent
, final List
<String
> strings
, final int x
,
222 final int y
, final int width
, final int height
) {
224 this(parent
, strings
, x
, y
, width
, height
, null);
228 * Public constructor.
230 * @param parent parent widget
231 * @param strings list of strings to show. This is allowed to be null
232 * and set later with setList() or by subclasses.
233 * @param x column relative to parent
234 * @param y row relative to parent
235 * @param width width of text area
236 * @param height height of text area
237 * @param enterAction action to perform when an item is selected
239 public TList(final TWidget parent
, final List
<String
> strings
, final int x
,
240 final int y
, final int width
, final int height
,
241 final TAction enterAction
) {
243 super(parent
, x
, y
, width
, height
);
244 this.enterAction
= enterAction
;
245 this.strings
= new ArrayList
<String
>();
246 if (strings
!= null) {
247 this.strings
.addAll(strings
);
253 * Public constructor.
255 * @param parent parent widget
256 * @param strings list of strings to show. This is allowed to be null
257 * and set later with setList() or by subclasses.
258 * @param x column relative to parent
259 * @param y row relative to parent
260 * @param width width of text area
261 * @param height height of text area
262 * @param enterAction action to perform when an item is selected
263 * @param moveAction action to perform when the user navigates to a new
264 * item with arrow/page keys
266 public TList(final TWidget parent
, final List
<String
> strings
, final int x
,
267 final int y
, final int width
, final int height
,
268 final TAction enterAction
, final TAction moveAction
) {
270 super(parent
, x
, y
, width
, height
);
271 this.enterAction
= enterAction
;
272 this.moveAction
= moveAction
;
273 this.strings
= new ArrayList
<String
>();
274 if (strings
!= null) {
275 this.strings
.addAll(strings
);
281 * Draw the files list.
285 CellAttributes color
= null;
286 int begin
= vScroller
.getValue();
288 for (int i
= begin
; i
< strings
.size(); i
++) {
289 String line
= strings
.get(i
);
290 if (hScroller
.getValue() < line
.length()) {
291 line
= line
.substring(hScroller
.getValue());
295 if (i
== selectedString
) {
296 color
= getTheme().getColor("tlist.selected");
297 } else if (isAbsoluteActive()) {
298 color
= getTheme().getColor("tlist");
300 color
= getTheme().getColor("tlist.inactive");
302 String formatString
= "%-" + Integer
.toString(getWidth() - 1) + "s";
303 getScreen().putStringXY(0, topY
, String
.format(formatString
, line
),
306 if (topY
>= getHeight() - 1) {
311 if (isAbsoluteActive()) {
312 color
= getTheme().getColor("tlist");
314 color
= getTheme().getColor("tlist.inactive");
317 // Pad the rest with blank lines
318 for (int i
= topY
; i
< getHeight() - 1; i
++) {
319 getScreen().hLineXY(0, i
, getWidth() - 1, ' ', color
);
324 * Handle mouse press events.
326 * @param mouse mouse button press event
329 public void onMouseDown(final TMouseEvent mouse
) {
330 if (mouse
.isMouseWheelUp()) {
331 vScroller
.decrement();
334 if (mouse
.isMouseWheelDown()) {
335 vScroller
.increment();
339 if ((mouse
.getX() < getWidth() - 1)
340 && (mouse
.getY() < getHeight() - 1)) {
341 if (vScroller
.getValue() + mouse
.getY() < strings
.size()) {
342 selectedString
= vScroller
.getValue() + mouse
.getY();
349 super.onMouseDown(mouse
);
355 * @param keypress keystroke event
358 public void onKeypress(final TKeypressEvent keypress
) {
359 if (keypress
.equals(kbLeft
)) {
360 hScroller
.decrement();
361 } else if (keypress
.equals(kbRight
)) {
362 hScroller
.increment();
363 } else if (keypress
.equals(kbUp
)) {
364 if (strings
.size() > 0) {
365 if (selectedString
>= 0) {
366 if (selectedString
> 0) {
367 if (selectedString
- vScroller
.getValue() == 0) {
368 vScroller
.decrement();
373 selectedString
= strings
.size() - 1;
376 if (selectedString
>= 0) {
379 } else if (keypress
.equals(kbDown
)) {
380 if (strings
.size() > 0) {
381 if (selectedString
>= 0) {
382 if (selectedString
< strings
.size() - 1) {
384 if (selectedString
- vScroller
.getValue() == getHeight() - 1) {
385 vScroller
.increment();
392 if (selectedString
>= 0) {
395 } else if (keypress
.equals(kbPgUp
)) {
396 vScroller
.bigDecrement();
397 if (selectedString
>= 0) {
398 selectedString
-= getHeight() - 1;
399 if (selectedString
< 0) {
403 if (selectedString
>= 0) {
406 } else if (keypress
.equals(kbPgDn
)) {
407 vScroller
.bigIncrement();
408 if (selectedString
>= 0) {
409 selectedString
+= getHeight() - 1;
410 if (selectedString
> strings
.size() - 1) {
411 selectedString
= strings
.size() - 1;
414 if (selectedString
>= 0) {
417 } else if (keypress
.equals(kbHome
)) {
419 if (strings
.size() > 0) {
422 if (selectedString
>= 0) {
425 } else if (keypress
.equals(kbEnd
)) {
426 vScroller
.toBottom();
427 if (strings
.size() > 0) {
428 selectedString
= strings
.size() - 1;
430 if (selectedString
>= 0) {
433 } else if (keypress
.equals(kbTab
)) {
434 getParent().switchWidget(true);
435 } else if (keypress
.equals(kbShiftTab
) || keypress
.equals(kbBackTab
)) {
436 getParent().switchWidget(false);
437 } else if (keypress
.equals(kbEnter
)) {
438 if (selectedString
>= 0) {
442 // Pass other keys (tab etc.) on
443 super.onKeypress(keypress
);