2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2019 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
.List
;
33 import jexer
.bits
.CellAttributes
;
34 import jexer
.bits
.GraphicsChars
;
35 import jexer
.event
.TKeypressEvent
;
36 import jexer
.event
.TMouseEvent
;
37 import static jexer
.TKeypress
.*;
40 * TComboBox implements a combobox containing a drop-down list and edit
41 * field. Alt-Down can be used to show the drop-down.
43 public class TComboBox
extends TWidget
{
45 // ------------------------------------------------------------------------
46 // Variables --------------------------------------------------------------
47 // ------------------------------------------------------------------------
50 * The list of items in the drop-down.
55 * The edit field containing the value to return.
60 * The action to perform when the user selects an item (clicks or enter).
62 private TAction updateAction
= null;
65 * If true, the field cannot be updated to a value not on the list.
67 private boolean limitToListValue
= true;
69 // ------------------------------------------------------------------------
70 // Constructors -----------------------------------------------------------
71 // ------------------------------------------------------------------------
76 * @param parent parent widget
77 * @param x column relative to parent
78 * @param y row relative to parent
79 * @param width visible combobox width, including the down-arrow
80 * @param values the possible values for the box, shown in the drop-down
81 * @param valuesIndex the initial index in values, or -1 for no default
83 * @param valuesHeight the height of the values drop-down when it is
85 * @param updateAction action to call when a new value is selected from
86 * the list or enter is pressed in the edit field
88 public TComboBox(final TWidget parent
, final int x
, final int y
,
89 final int width
, final List
<String
> values
, final int valuesIndex
,
90 final int valuesHeight
, final TAction updateAction
) {
92 // Set parent and window
93 super(parent
, x
, y
, width
, 1);
95 assert (values
!= null);
97 this.updateAction
= updateAction
;
99 field
= addField(0, 0, width
- 3, false, "", updateAction
, null);
100 if (valuesIndex
>= 0) {
101 field
.setText(values
.get(valuesIndex
));
104 list
= addList(values
, 0, 1, width
, valuesHeight
,
107 field
.setText(list
.getSelected());
108 list
.setEnabled(false);
109 list
.setVisible(false);
110 TComboBox
.this.setHeight(1);
111 if (TComboBox
.this.limitToListValue
== false) {
112 TComboBox
.this.activate(field
);
114 if (updateAction
!= null) {
120 if (valuesIndex
>= 0) {
121 list
.setSelectedIndex(valuesIndex
);
124 list
.setEnabled(false);
125 list
.setVisible(false);
127 if (limitToListValue
) {
128 field
.setEnabled(false);
134 // ------------------------------------------------------------------------
135 // Event handlers ---------------------------------------------------------
136 // ------------------------------------------------------------------------
139 * Returns true if the mouse is currently on the down arrow.
141 * @param mouse mouse event
142 * @return true if the mouse is currently on the down arrow
144 private boolean mouseOnArrow(final TMouseEvent mouse
) {
145 if ((mouse
.getY() == 0)
146 && (mouse
.getX() >= getWidth() - 3)
147 && (mouse
.getX() <= getWidth() - 1)
155 * Handle mouse down clicks.
157 * @param mouse mouse button down event
160 public void onMouseDown(final TMouseEvent mouse
) {
161 if ((mouseOnArrow(mouse
)) && (mouse
.isMouse1())) {
162 // Make the list visible or not.
163 if (list
.isActive()) {
164 list
.setEnabled(false);
165 list
.setVisible(false);
167 if (limitToListValue
== false) {
171 list
.setEnabled(true);
172 list
.setVisible(true);
173 setHeight(list
.getHeight() + 1);
178 // Pass to parent for the things we don't care about.
179 super.onMouseDown(mouse
);
185 * @param keypress keystroke event
188 public void onKeypress(final TKeypressEvent keypress
) {
189 if (keypress
.equals(kbEsc
)) {
190 if (list
.isActive()) {
191 list
.setEnabled(false);
192 list
.setVisible(false);
194 if (limitToListValue
== false) {
201 if (keypress
.equals(kbAltDown
)) {
202 list
.setEnabled(true);
203 list
.setVisible(true);
204 setHeight(list
.getHeight() + 1);
209 if (keypress
.equals(kbTab
)
210 || (keypress
.equals(kbShiftTab
))
211 || (keypress
.equals(kbBackTab
))
213 if (list
.isActive()) {
214 list
.setEnabled(false);
215 list
.setVisible(false);
217 if (limitToListValue
== false) {
224 // Pass to parent for the things we don't care about.
225 super.onKeypress(keypress
);
228 // ------------------------------------------------------------------------
229 // TWidget ----------------------------------------------------------------
230 // ------------------------------------------------------------------------
233 * Draw the combobox down arrow.
237 CellAttributes comboBoxColor
;
239 if (!isAbsoluteActive()) {
240 // We lost focus, turn off the list.
241 if (list
.isActive()) {
242 list
.setEnabled(false);
243 list
.setVisible(false);
245 if (limitToListValue
== false) {
251 if (isAbsoluteActive()) {
252 comboBoxColor
= getTheme().getColor("tcombobox.active");
254 comboBoxColor
= getTheme().getColor("tcombobox.inactive");
257 putCharXY(getWidth() - 3, 0, GraphicsChars
.DOWNARROWLEFT
,
259 putCharXY(getWidth() - 2, 0, GraphicsChars
.DOWNARROW
,
261 putCharXY(getWidth() - 1, 0, GraphicsChars
.DOWNARROWRIGHT
,
265 // ------------------------------------------------------------------------
266 // TComboBox --------------------------------------------------------------
267 // ------------------------------------------------------------------------
270 * Get combobox text value.
272 * @return text in the edit field
274 public String
getText() {
275 return field
.getText();
279 * Set combobox text value.
281 * @param text the new text in the edit field
283 public void setText(final String text
) {
288 * Set combobox text value.
290 * @param text the new text in the edit field
291 * @param caseSensitive if true, perform a case-sensitive search for the
294 public void setText(final String text
, final boolean caseSensitive
) {
296 for (int i
= 0; i
< list
.getMaxSelectedIndex(); i
++) {
297 if (caseSensitive
== true) {
298 if (list
.getListItem(i
).equals(text
)) {
299 list
.setSelectedIndex(i
);
303 if (list
.getListItem(i
).toLowerCase().equals(text
.toLowerCase())) {
304 list
.setSelectedIndex(i
);
309 list
.setSelectedIndex(-1);
313 * Set combobox text to one of the list values.
315 * @param index the index in the list
317 public void setIndex(final int index
) {
318 list
.setSelectedIndex(index
);
319 field
.setText(list
.getSelected());
323 * Get a copy of the list of strings to display.
325 * @return the list of strings
327 public final List
<String
> getList() {
328 return list
.getList();
332 * Set the new list of strings to display.
334 * @param list new list of strings
336 public final void setList(final List
<String
> list
) {
337 this.list
.setList(list
);