This repository has been archived by the owner on Mar 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
CommandBox.java
159 lines (136 loc) · 4.72 KB
/
CommandBox.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package seedu.address.ui;
import java.util.List;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Region;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
/**
* The UI component that is responsible for receiving user command inputs.
*/
public class CommandBox extends UiPart<Region> {
public static final String ERROR_STYLE_CLASS = "error";
private static final String FXML = "CommandBox.fxml";
private final CommandExecutor commandExecutor;
private final List<String> history;
private ListElementPointer historySnapshot;
@FXML
private TextField commandTextField;
public CommandBox(CommandExecutor commandExecutor, List<String> history) {
super(FXML);
this.commandExecutor = commandExecutor;
this.history = history;
// calls #setStyleToDefault() whenever there is a change to the text of the command box.
commandTextField.textProperty().addListener((unused1, unused2, unused3) -> setStyleToDefault());
historySnapshot = new ListElementPointer(history);
}
/**
* Handles the key press event, {@code keyEvent}.
*/
@FXML
private void handleKeyPress(KeyEvent keyEvent) {
switch (keyEvent.getCode()) {
case UP:
// As up and down buttons will alter the position of the caret,
// consuming it causes the caret's position to remain unchanged
keyEvent.consume();
navigateToPreviousInput();
break;
case DOWN:
keyEvent.consume();
navigateToNextInput();
break;
default:
// let JavaFx handle the keypress
}
}
/**
* Updates the text field with the previous input in {@code historySnapshot},
* if there exists a previous input in {@code historySnapshot}
*/
private void navigateToPreviousInput() {
assert historySnapshot != null;
if (!historySnapshot.hasPrevious()) {
return;
}
replaceText(historySnapshot.previous());
}
/**
* Updates the text field with the next input in {@code historySnapshot},
* if there exists a next input in {@code historySnapshot}
*/
private void navigateToNextInput() {
assert historySnapshot != null;
if (!historySnapshot.hasNext()) {
return;
}
replaceText(historySnapshot.next());
}
/**
* Sets {@code CommandBox}'s text field with {@code text} and
* positions the caret to the end of the {@code text}.
*/
private void replaceText(String text) {
commandTextField.setText(text);
commandTextField.positionCaret(commandTextField.getText().length());
}
/**
* Handles the Enter button pressed event.
*/
@FXML
private void handleCommandEntered() {
String commandText = commandTextField.getText();
if (commandText.equals("")) {
return;
}
try {
commandExecutor.execute(commandText);
initHistory();
historySnapshot.next();
commandTextField.setText("");
} catch (CommandException | ParseException e) {
initHistory();
setStyleToIndicateCommandFailure();
}
}
/**
* Initializes the history snapshot.
*/
private void initHistory() {
historySnapshot = new ListElementPointer(history);
// add an empty string to represent the most-recent end of historySnapshot, to be shown to
// the user if she tries to navigate past the most-recent end of the historySnapshot.
historySnapshot.add("");
}
/**
* Sets the command box style to use the default style.
*/
private void setStyleToDefault() {
commandTextField.getStyleClass().remove(ERROR_STYLE_CLASS);
}
/**
* Sets the command box style to indicate a failed command.
*/
private void setStyleToIndicateCommandFailure() {
ObservableList<String> styleClass = commandTextField.getStyleClass();
if (styleClass.contains(ERROR_STYLE_CLASS)) {
return;
}
styleClass.add(ERROR_STYLE_CLASS);
}
/**
* Represents a function that can execute commands.
*/
@FunctionalInterface
public interface CommandExecutor {
/**
* Executes the command and returns the result.
*
* @see seedu.address.logic.Logic#execute(String)
*/
CommandResult execute(String commandText) throws CommandException, ParseException;
}
}