aboutsummaryrefslogtreecommitdiff
path: root/src/esieequest/ui/rich/app/AppInterface.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/esieequest/ui/rich/app/AppInterface.java')
-rw-r--r--src/esieequest/ui/rich/app/AppInterface.java244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/esieequest/ui/rich/app/AppInterface.java b/src/esieequest/ui/rich/app/AppInterface.java
new file mode 100644
index 0000000..79a51cf
--- /dev/null
+++ b/src/esieequest/ui/rich/app/AppInterface.java
@@ -0,0 +1,244 @@
1package esieequest.ui.rich.app;
2
3import java.awt.Graphics;
4import java.awt.Image;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.awt.image.BufferedImage;
8import java.net.URL;
9
10import javax.swing.JButton;
11import javax.swing.JFileChooser;
12import javax.swing.JTextPane;
13import javax.swing.filechooser.FileNameExtensionFilter;
14
15import lombok.Getter;
16
17import com.wordpress.tipsforjava.swing.StretchIcon;
18
19import esieequest.engine.audioplayer.SysAudioPlayer;
20import esieequest.engine.commands.Command;
21import esieequest.engine.datastore.DataStore;
22import esieequest.engine.datastore.FileDataStore;
23import esieequest.engine.scheduler.SysScheduler;
24import esieequest.game.Text;
25import esieequest.game.items.Inventory;
26import esieequest.game.items.Item;
27import esieequest.game.map.Direction;
28import esieequest.game.map.Room;
29import esieequest.game.map.Side;
30import esieequest.game.states.Quest;
31import esieequest.ui.rich.RichInterface;
32
33/**
34 * The Swing based graphical user interface.
35 *
36 * @author Pacien TRAN-GIRARD
37 * @author BenoƮt LUBRANO DI SBARAGLIONE
38 */
39abstract class AppInterface extends RichInterface implements ActionListener {
40
41 private static final String ILLUSTRATION_DIR = "resources/images/";
42 private static final String ILLUSTRATION_EXT = ".jpg";
43
44 @Getter
45 private final Layout layout;
46
47 /**
48 * The default constructor.
49 */
50 public AppInterface() {
51 super(new FileDataStore(), new SysScheduler(), new SysAudioPlayer());
52
53 this.layout = new Layout(this);
54
55 this.setControlsState(false);
56 }
57
58 /**
59 * Clears the textual input field.
60 */
61 private void clearInputField() {
62 this.layout.getInputField().setText(null);
63 }
64
65 /**
66 * Sets the controls state.
67 *
68 * @param state
69 * the controls state
70 */
71 private void setControlsState(final boolean state) {
72 this.layout.getInputField().setEnabled(state);
73 this.layout.getSaveButton().setEnabled(state);
74 this.layout.getInventoryButton().setEnabled(state);
75 this.layout.getLeftButton().setEnabled(state);
76 this.layout.getRightButton().setEnabled(state);
77 if (!state) {
78 this.layout.getForwardButton().setEnabled(state);
79 this.layout.getBackButton().setEnabled(state);
80 this.layout.getActionButton().setEnabled(state);
81 }
82 }
83
84 /**
85 * Placeholder image generation from
86 * http://stackoverflow.com/a/17802477/1348634
87 *
88 * @param text
89 * the image text
90 * @return the Image
91 */
92 private Image generatePlaceholderImage(final String text) {
93 final BufferedImage bufferedImage = new BufferedImage(240, 135,
94 BufferedImage.TYPE_BYTE_BINARY);
95 final Graphics graphics = bufferedImage.getGraphics();
96 graphics.drawString(text, 5, 10 + 5);
97 return bufferedImage;
98 }
99
100 /**
101 * Opens the inventory (switches to the inventory tab).
102 */
103 private void openInventory() {
104 this.layout.getConsolePanel().setVisible(false);
105 this.layout.getInventoryPanel().setVisible(true);
106 }
107
108 /**
109 * Closes the inventory (switches to the console tab).
110 */
111 private void closeInventory() {
112 this.layout.getInventoryPanel().setVisible(false);
113 this.layout.getConsolePanel().setVisible(true);
114 }
115
116 /**
117 * Toggles the inventory tab.
118 */
119 private void toggleInventory() {
120 if (this.layout.getInventoryPanel().isVisible()) {
121 this.closeInventory();
122 } else {
123 this.openInventory();
124 }
125 }
126
127 /**
128 * Translates the received ActionEvent into the corresponding game command
129 * and forwards it to the game engine.
130 */
131 @Override
132 public void actionPerformed(final ActionEvent actionEvent) {
133 if (actionEvent.getActionCommand() == Command.INVENTORY.name()) {
134 this.toggleInventory();
135 } else if (actionEvent.getActionCommand() == Command.LOAD.name()) {
136 final JFileChooser fileChooser = new JFileChooser();
137 fileChooser.setFileFilter(new FileNameExtensionFilter(DataStore.SAVE_LABEL,
138 DataStore.SAVE_EXT));
139 final int option = fileChooser.showOpenDialog(this.layout.getMainPanel());
140 if (option == JFileChooser.APPROVE_OPTION) {
141 this.getGameEngine().interpret(
142 actionEvent.getActionCommand() + Text.COMMAND_SEPARATOR
143 + fileChooser.getSelectedFile().getPath());
144 }
145 } else if (actionEvent.getActionCommand() == Command.SAVE.name()) {
146 final JFileChooser fileChooser = new JFileChooser();
147 fileChooser.setFileFilter(new FileNameExtensionFilter(DataStore.SAVE_LABEL,
148 DataStore.SAVE_EXT));
149 final int option = fileChooser.showSaveDialog(this.layout.getMainPanel());
150 if (option == JFileChooser.APPROVE_OPTION) {
151 final String path = fileChooser.getSelectedFile().getPath();
152 final String filePath = path.endsWith(DataStore.SAVE_EXT) ? path : path + "."
153 + DataStore.SAVE_EXT;
154 this.getGameEngine().interpret(
155 actionEvent.getActionCommand() + Text.COMMAND_SEPARATOR + filePath);
156 }
157 } else {
158 this.getGameEngine().interpret(actionEvent.getActionCommand());
159 this.clearInputField();
160 }
161 }
162
163 @Override
164 public void setLabel(final String questTitle) {
165 this.layout.getQuestTextPane().setText(questTitle);
166 }
167
168 @Override
169 public void setFrame(final String imageName) {
170 final URL imageURL = this.getClass().getClassLoader().getResource(
171 AppInterface.ILLUSTRATION_DIR + imageName + AppInterface.ILLUSTRATION_EXT);
172 final StretchIcon imageIcon;
173 if (imageURL == null) {
174 imageIcon = new StretchIcon(this.generatePlaceholderImage(imageName), true);
175 } else {
176 imageIcon = new StretchIcon(imageURL, true);
177 }
178 this.layout.getImageLabel().setIcon(imageIcon);
179 }
180
181 @Override
182 public void enableInput() {
183 this.setControlsState(true);
184 }
185
186 @Override
187 public void disableInput() {
188 this.setControlsState(false);
189 this.setLabel(Text.DEFAULT_QUEST_TITLE.toString());
190 }
191
192 @Override
193 public void echo(final String message) {
194 this.closeInventory();
195 this.layout.getInfoTextPane().setText(message);
196 }
197
198 @Override
199 public void updateQuest(final Quest quest) {
200 this.setLabel(quest.getTitle());
201 this.getAudioPlayer().play(quest.name());
202 }
203
204 @Override
205 public void updateLocation(final Room room, final Direction direction, final Side side,
206 final boolean canGoBack) {
207 String locationImageName = room.name() + Text.FILENAME_SEPARATOR.toString()
208 + direction.name();
209 if (side.getInventory().getSize() > 0) {
210 locationImageName += Text.FILENAME_SEPARATOR.toString()
211 + side.getInventory().getItem().name();
212 }
213 this.setFrame(locationImageName);
214 this.layout.getBackButton().setEnabled(canGoBack);
215 this.layout.getForwardButton().setEnabled(side.hasDoor());
216 this.layout.getActionButton().setEnabled(