View Javadoc
1   package com.nilhcem.fakesmtp.gui;
2   
3   import com.nilhcem.fakesmtp.core.ArgsHandler;
4   import com.nilhcem.fakesmtp.core.I18n;
5   import com.nilhcem.fakesmtp.gui.info.ClearAllButton;
6   import com.nilhcem.fakesmtp.gui.info.NbReceivedLabel;
7   import com.nilhcem.fakesmtp.gui.info.PortTextField;
8   import com.nilhcem.fakesmtp.gui.info.SaveMsgField;
9   import com.nilhcem.fakesmtp.gui.info.StartServerButton;
10  import com.nilhcem.fakesmtp.gui.tab.LastMailPane;
11  import com.nilhcem.fakesmtp.gui.tab.LogsPane;
12  import com.nilhcem.fakesmtp.gui.tab.MailsListPane;
13  import com.nilhcem.fakesmtp.server.MailSaver;
14  import com.nilhcem.fakesmtp.server.SMTPServerHandler;
15  import net.miginfocom.swing.MigLayout;
16  
17  import javax.swing.JLabel;
18  import javax.swing.JPanel;
19  import javax.swing.JTabbedPane;
20  import java.util.Observable;
21  
22  /**
23   * Provides the main panel of the application, which will contain all the components.
24   *
25   * @author Nilhcem
26   * @since 1.0
27   */
28  public final class MainPanel {
29  	// I18n
30  	private final I18n i18n = I18n.INSTANCE;
31  
32  	// Panel and layout
33  	private final MigLayout layout = new MigLayout(
34  		"", // Layout constraints
35  		"[] 10 [] [] [grow,fill]", // Column constraints
36  		"[] [] 5 [] 5 [grow,fill] []"); // Row constraints
37  	private final JPanel mainPanel = new JPanel(layout);
38  
39  	// Directory chooser
40  	private final DirChooser dirChooser = new DirChooser(mainPanel);
41  
42  	// Port
43  	private final JLabel portLabel = new JLabel(i18n.get("mainpanel.listening.port"));
44  	private final PortTextField portText = new PortTextField();
45  	private final StartServerButton startServerBtn = new StartServerButton();
46  
47  	// Messages received
48  	private final JLabel receivedLabel = new JLabel(i18n.get("mainpanel.messages.received"));
49  	private final NbReceivedLabel nbReceivedLabel = new NbReceivedLabel();
50  
51  	// Save incoming messages to
52  	private final JLabel saveMessages = new JLabel(i18n.get("mainpanel.save.messages"));
53  	private final SaveMsgField saveMsgTextField = new SaveMsgField();
54  
55  	// Tab pane
56  	private final JTabbedPane tabbedPane = new JTabbedPane();
57  	private final LogsPane logsPane = new LogsPane();
58  	private final MailsListPane mailsListPane = new MailsListPane();
59  	private final LastMailPane lastMailPane = new LastMailPane();
60  
61  	// Clear all
62  	private final ClearAllButton clearAll = new ClearAllButton();
63  
64  	/**
65  	 * Creates the main panel.
66  	 * <p>
67  	 * To create the main panel, the method will first have to handle components interactions by
68  	 * adding observers to observable elements, then the method will build the GUI by placing all the
69  	 * components in the main panel.
70  	 * </p>
71  	 *
72  	 * @param menu the menu bar which will notify the directory file chooser.
73  	 */
74  	public MainPanel(Observable menu) {
75  		assignLabelsToFields();
76  		addObservers(menu);
77  		buildGUI();
78  		checkArgs();
79  	}
80  
81  	/**
82  	 * Returns the JPanel object.
83  	 *
84  	 * @return the JPanel object.
85  	 */
86  	public JPanel get() {
87  		return mainPanel;
88  	}
89  
90  	/**
91  	 * Handles components interactions by adding observers to observable elements.
92  	 * <p>
93  	 * The interactions are the following:
94  	 * <ul>
95  	 *   <li>Open the directory chooser when clicking on the menu/the save message field;</li>
96  	 *   <li>Enable/Disable the port field when the server starts;</li>
97  	 *   <li>Set the new directory, once a folder is selected;<li>
98  	 *   <li>Notify components when a message is received;</li>
99  	 *   <li>Notify components when the user wants to clear them all.</li>
100 	 * </ul>
101 	 * </p>
102 	 *
103 	 * @param menu the menu bar which will notify the directory file chooser.
104 	 */
105 	private void addObservers(Observable menu) {
106 		// When we want to select a directory
107 		menu.addObserver(dirChooser);
108 		saveMsgTextField.addObserver(dirChooser);
109 
110 		// When we click on "start server" button
111 		startServerBtn.addObserver(portText);
112 
113 		// When we press "Enter" on the PortTextField
114 		portText.addObserver(startServerBtn);
115 
116 		// Once we chose a directory
117 		dirChooser.addObserver(saveMsgTextField);
118 
119 		// When a message is received
120 		MailSaver mailSaver = SMTPServerHandler.INSTANCE.getMailSaver();
121 		mailSaver.addObserver(nbReceivedLabel);
122 		mailSaver.addObserver(mailsListPane);
123 		mailSaver.addObserver(lastMailPane);
124 		mailSaver.addObserver(clearAll);
125 
126 		// When we click on "clear all"
127 		clearAll.addObserver(nbReceivedLabel);
128 		clearAll.addObserver(mailsListPane);
129 		clearAll.addObserver(logsPane);
130 		clearAll.addObserver(lastMailPane);
131 	}
132 
133 	/**
134 	 * Places all components in the panel.
135 	 */
136 	private void buildGUI() {
137 		// Port / Start server
138 		mainPanel.add(portLabel);
139 		mainPanel.add(portText.get(), "w 60!");
140 		mainPanel.add(startServerBtn.get(), "span, w 165!");
141 
142 		// Save messages to...
143 		mainPanel.add(saveMessages);
144 		mainPanel.add(saveMsgTextField.get(), "span, w 230!");
145 
146 		// Nb received
147 		mainPanel.add(receivedLabel);
148 		mainPanel.add(nbReceivedLabel.get(), "span");
149 
150 		// Tab pane
151 		tabbedPane.add(mailsListPane.get(), i18n.get("mainpanel.tab.mailslist"));
152 		tabbedPane.add(logsPane.get(), i18n.get("mainpanel.tab.smtplog"));
153 		tabbedPane.add(lastMailPane.get(), i18n.get("mainpanel.tab.lastmessage"));
154 		mainPanel.add(tabbedPane, "span, grow");
155 
156 		// Clear all
157 		mainPanel.add(clearAll.get(), "span, center");
158 	}
159 
160 	/**
161 	 * Checks command line arguments and toggles components if necessary.
162 	 * <p>
163 	 * <ul><li>if the user has chosen a different port, then specifies it in the port text field.</li>
164 	 * <li>if the user has chosen to auto-start the SMTP server, then it toggles automatically the "start server" button.</li></ul>
165 	 * </p>
166 	 */
167 	private void checkArgs() {
168 		ArgsHandler args = ArgsHandler.INSTANCE;
169 
170 		if (args.getPort() != null) {
171 			portText.setText(args.getPort());
172 		}
173 
174 		if (args.shouldStartServerAtLaunch()) {
175 			startServerBtn.toggleButton();
176 		}
177 
178 		if (args.memoryModeEnabled()) {
179 			saveMsgTextField.get().setEnabled(false);
180 		}
181 	}
182 
183 	/**
184 	 * Assigns labels to components, for accessibility purpose.
185 	 */
186 	private void assignLabelsToFields() {
187 		portLabel.setLabelFor(portText.get());
188 		saveMessages.setLabelFor(saveMsgTextField.get());
189 		receivedLabel.setLabelFor(nbReceivedLabel.get());
190 	}
191 
192 	/**
193 	 * Returns reference to portText field. Used for saving last values to file
194 	 *
195 	 * @return reference to portText field. Used for saving last values to file
196 	 */
197 	public PortTextField getPortText() {
198 		return portText;
199 	}
200 
201 	/**
202 	 * Returns reference to saveMsgTextField. Used for saving last values to file
203      *
204      * @return reference to saveMsgTextField. Used for saving last values to file
205 	 */
206 	public SaveMsgField getSaveMsgTextField() {
207 		return saveMsgTextField;
208 	}
209 }